Bengal 0.1.9

Architecture decomposition, Python 3.14 modernization, build performance, protocol migrations, and comprehensive docs audit

Key additions: Major architecture decomposition (mixins → free functions + composed services, 12 → 4 Site mixins), Python 3.14 modernization (PEP 695 type params, slots, exception chaining), build performance optimizations (~50-60% faster), protocol-based decoupling across 40+ files, thread safety hardening, incremental build improvements, structured error handling, and a comprehensive documentation staleness audit.


Highlights

Architecture Decomposition

The largest structural change in Bengal's history — systematic decomposition of monolithic mixins into free functions and composed services:

  • Protocol-based decoupling:PageLike and SiteLike split into role-based protocols (SiteConfig, SiteContent, Summarizable), migrated across 40+ consumer files
  • Mixin elimination:Site inheritance chain reduced from 12 to 4 mixins — PageComputedMixin, PageBundleMixin, PageNavigationMixin, SitePropertiesMixin, and SiteVersioningMixinall extracted to free functions or composed services
  • ConfigService: New frozen dataclass composing all configuration access, wired intoSitewith bridge properties (31 tests)
  • EffectTracer: ReplacesDependencyTrackerwith persistence, file fingerprinting, and thread-safe operation
  • Module splits:snapshots/builder.py(1,762 lines) split into 5 focused modules
  • Type cleanup: 55 staletype: ignore comments removed, Anyescape hatches replaced with correct types across rendering and Page files

Python 3.14 Modernization

Codebase-wide adoption of modern Python syntax:

  • PEP 695 type parameters:class Foo[T]: replaces class Foo(Generic[T]):throughout
  • slots=True on all frozen dataclasses for memory efficiency
  • Exception chaining in all raise-in-except blocks
  • ClassVarannotations on mutable class defaults
  • Comprehension conversion from manual list building (PERF401)
  • Narrowed exception handlers across rendering modules

Build Performance Optimizations

Three-phase performance RFC delivering cumulative ~50-60% speedup for large sites:

  • Fast mode (build.fast_mode=True): Skip HTML pretty-printing/minification for ~10-15% speedup
  • Render-time asset tracking: ContextVar-based AssetTracker eliminates post-render HTML parsing (~20-25% speedup)
  • Autodoc AST caching: Cache parsed Python module data across builds (~30-40% speedup for autodoc-heavy sites)
  • Parser pooling: Re-enabled with patitas 0.1.1's_reinit()support (~78% faster parser instantiation)
  • Snapshot pre-computation: NavTrees and renderer caches pre-computed at snapshot time for lock-free lookups

Incremental Build Observability

New CLI flags for understanding rebuild decisions:

# Explain why pages are being rebuilt
bengal build --explain

# Preview what would be rebuilt without doing it
bengal build --dry-run

# Machine-readable rebuild manifest
bengal build --explain-json > manifest.json

Thread Safety Hardening

Comprehensive free-threading support for Python 3.14t:

  • ContextVar asset manifest: Fixes TOCTOU race condition (~8M ops/sec, zero lock contention)
  • Lock ordering convention: Documented lock hierarchy prevents deadlocks
  • Immutable snapshots: Pre-computed at snapshot time for lock-free rendering
  • BuildCache/DependencyTracker separation: Clean pipeline boundaries
  • Threading integration tests: EffectTracer and BuildTaxonomyIndex verified under concurrent load

Cache Coordination

UnifiedCacheCoordinatormanages cache invalidation across all subsystems:

  • PathRegistry: Centralized path-to-cache-key mapping
  • RebuildManifest: Tracks what needs rebuilding and why
  • Content-hash embedding: O(1) change detection via embedded hashes in output
  • Template change detection: Cache now detects template file changes and triggers rebuilds
  • EffectTracer pipeline: Wired into incremental builds with persistence and file fingerprinting

Structured Error Handling

Five new exception classes with actionable suggestions:

Exception Use Case
BengalParsingError Markdown/frontmatter parsing failures
BengalAutodocError Autodoc extraction issues
BengalValidatorError Health check validation failures
BengalBuildError Build pipeline errors
BengalTemplateFunctionError Template filter/function errors

All exceptions include error codes (O/V/B series) and contextual suggestions.

Documentation Audit

Comprehensive staleness audit across all documentation sections:

  • Fixed stale claims in about, building, content, extending, get-started, reference, and theming
  • Aligned page URL properties to match codebase (page.href, page._path)
  • Replaced Jinja2-style block endings with{% end %}in Kida examples
  • Added external cross-links for Kida, Patitas, and Rosettes

Additional Changes

Developer Experience

  • bengal upgrade: Self-update command with PyPI version checking and installer detection
  • Serve-first startup: Dev server serves cached content immediately (~200ms first paint)
  • Dead link indicators: Visual styling for broken internal links

Theme Enhancements

  • Header customization:nav_position (left/center), sticky, and autohideoptions via data attributes

Changelog & Releases Filter

  • Smart semver-aware version sorting
  • Domain-aware filtering with simplified API

CI & Packaging

  • Trusted publishing:python-publish.ymlGitHub Actions workflow for OIDC-based PyPI publishing
  • Pages fix:--clean-output flag fixes 404s on /api/ and /cli/

Directives

  • Patitas-native glossary directive

Breaking Changes

None. This is a fully backward-compatible release.


Bug Fixes

  • Duplicate tag pages: Fixed incremental builds generating duplicate taxonomy pages
  • Anchor fragment preservation:.md links now preserve #sectionanchors during normalization
  • Serve-first activation: Fixed serve-first not triggering whenbaseurl is /
  • Python 3.14 import scoping: Fixed cache loading issue with import scoping in 3.14
  • Undefined references: Fixed undefined name references in site and sitemap modules
  • Incremental tag terms: Fixed tag term page generation in incremental builds
  • CI test failures: Fixed missing module, wrong kwarg, and unimplemented test gaps

Dependency Updates

Package Version Change
patitas ≥0.1.1 Adds_reinit()for parser pooling
kida-templates ≥0.1.2 RenderContext, profiling support

Upgrading

uv pip install --upgrade bengal
# or
pip install --upgrade bengal
# or use the new self-update command
bengal upgrade