Zenzic v0.6.1rc2 — Obsidian Bastion
This is a historical record of a development milestone. The first stable release is v0.7.0 — Quartz Maturity.
v0.6.1rc2 — Obsidian Bastion is the release that turned Zenzic from a capable single-engine linter into a genuine multi-engine documentation Safe Harbor.
The architectural shift
The defining change of the Bastion cycle was the rejection of a hidden assumption: that every project using Zenzic would have a single, knowable documentation engine.
That assumption broke the moment we tried Zensical — a MkDocs-compatible engine with its own configuration surface. The fix was not to add another adapter. It was to rethink the adapter contract entirely.
Headless Architecture (Pillar 1, enforced)
Every adapter was refactored to receive a pre-built context object — BuildContext —
rather than reading configuration files at runtime. This eliminated the last class of
I/O in the hot path and made the system deterministically testable.
New in v0.6.1rc2
| Feature | Notes |
|---|---|
Zensical adapter (engine = "zensical") | Full zensical.toml parsing |
| Zensical Transparent Proxy | engine = "zensical-bridge" for MkDocs nav compatibility |
| Docusaurus enterprise adapter | Versioned docs, @site/ alias, slug alignment |
Z401 MISSING_DIRECTORY_INDEX | SEO guardrail: every directory must have a landing page |
Z402 ORPHAN_PAGE | Detects pages declared but unreachable from the nav tree |
| Zenzic Lab (9 Acts) | Interactive zero-config onboarding showcase |
uvx zenzic check all ./path | Primary curiosity path with zero install friction |
Shield hardening: four bypass vectors closed
The security audit that ran concurrently with the Bastion architecture work found and closed four bypass vectors in the Shield credential scanner — the module responsible for detecting leaked credentials before any documentation build begins.
| Vector | Codename | Attack method | Fix |
|---|---|---|---|
| Unicode format characters | ZRT-006 | Zero-width joiners (U+200D, U+200C, U+200B) inserted mid-token to break regex matching | Normaliser strips all Unicode category Cf characters before scanning |
| HTML entity obfuscation | ZRT-006 | AK encoded credential prefixes bypass plain-text matching | html.unescape() decodes NNN; and HH; entities in the normalisation pass |
| Comment interleaving | ZRT-007 | HTML <!-- --> and MDX {/* */} comments inserted mid-token | Normaliser strips both comment forms before any pattern is applied |
| Cross-line split detection | ZRT-007b | Secrets split across two consecutive lines evade single-line scanners | scan_lines_with_lookback() carries a 1-line lookback buffer; deduplication via seen-set |
Two additional hardening measures were applied in this cycle:
Blood Sentinel (Exit 3). A dedicated fatal exit code was formalised for architectural
violations — docs_dir paths that escape the repository root now trigger Exit 3 before
any scan begins. This is not a lint finding. It is a hard stop.
ReDoS protection. Lines exceeding 1 MiB are silently truncated before regex matching, preventing catastrophic backtracking against adversarially crafted inputs.
Operation Obsidian Stress
During the v0.6.1rc2 cycle, an AI-driven adversarial audit found four bypass vectors in the Shield credential scanner. All four were closed before the release candidate was finalised. The complete post-mortem is published here:
→ We Put Our Documentation Linter Under an AI-Driven Siege
The full architectural story of the Bastion cycle:
→ What Happens When You Rip the Foundation Out of a Security Tool