Quartz Maturity
During the final consolidation sprint for v0.7.0, we ran four AI agents against Zenzic's own documentation site. They were instructed to find everything wrong with it.
They found a file that Zenzic had marked REACHABLE. The file existed on disk, had valid frontmatter, and was not referenced by any broken link. By every metric in the pre-v0.7.0 implementation, it was clean.
The file had not appeared in the sidebar for three weeks. No navbar entry linked to it. No footer item referenced it. A user navigating the documentation site had no way to reach it by clicking. It was, from the reader's perspective, gone.
Zenzic was asking the wrong question.
The Wrong Question
Traditional documentation linters ask: does the file exist on disk?
That is the correct question for a filesystem validator. It is the wrong question for a documentation integrity tool. Documentation is not a filesystem. It is an experience delivered through navigation surfaces — sidebar menus, navbar links, footer references. A file that exists on disk but appears on none of those surfaces is, for all practical purposes, invisible to every reader who visits your site.
Zenzic v0.7.0 asks a different question:
Can a user reach this file by clicking through the navigation of your documentation site?
If the answer is no, the file is an orphan — regardless of whether it exists on disk.
This is the UX-Discoverability Law.
Rule R21: The UX-Discoverability Law
The formal rule, added to Zenzic's rule registry in D090:
R21 — UX-Discoverability: A file is REACHABLE if and only if at least one user-clickable navigation surface declares it. A file absent from all navigation surfaces is ORPHAN_BUT_EXISTING, regardless of its presence on disk.
For Docusaurus projects, "navigation surfaces" means exactly three sources:
| Surface | Config location | Detection method |
|---|---|---|
| Sidebar | sidebars.ts / sidebars.js | type: 'doc' entries and bare string IDs |
| Navbar | themeConfig.navbar.items | to: URL paths, docId: references |
| Footer | themeConfig.footer.links | to: URL paths |
Zenzic parses all three statically — no Node.js, no build step, no external process.
The implementation is pure Python, respects Pillar 2 (zero subprocesses), and handles
both .ts and .js sidebar files. JS-style comments are stripped before parsing.
baseUrl and routeBasePath prefixes are normalised before path resolution.
A single frozenset[str] is returned to the Core, which applies the orphan rule
uniformly across all engines. The Core knows nothing about sidebars, navbars, or
footers. It receives a set of navigable paths and compares them against disk contents.
That is the entire contract.
The Three-Surface Parser in Practice
Given a project with an explicit sidebars.ts that deliberately omits changelog.mdx:
// sidebars.ts — changelog is not listed
const sidebars = {
docs: ['intro', 'guide/index', 'guide/deploy'],
};
export default sidebars;
And a docusaurus.config.ts that links it from the navbar:
themeConfig: {
navbar: {
items: [
{ to: '/docs/changelog', label: 'Changelog', position: 'right' },
],
},
},
Pre-v0.7.0: changelog.mdx → ORPHAN_BUT_EXISTING (not in sidebar).
Post-v0.7.0: changelog.mdx → REACHABLE (navbar declares it).
The same logic applies to footer-only files. A legal notice linked only in the footer has been invisible to Zenzic's orphan detector until now. In v0.7.0, it is REACHABLE because a user can reach it by clicking.
Architectural Philosophy: A Different Axis
Documentation quality tools exist on a spectrum. Most operate on one axis — link existence — and stop there. Zenzic operates on a different axis entirely: trust.
markdown-link-check and htmlproofer are correct tools for what they declare. They
are link checkers — fast, composable, well-understood. Zenzic is not a link checker
that also happens to check orphans and scan for secrets. It is a Static Analysis
Framework built on a fundamentally different trust model. Comparing them on a
feature checklist alone is like comparing a compiler and a formatter because both
read source files.
The meaningful comparison is architectural:
| Design Dimension | Generic Link Checkers | Zenzic Sentinel Guard |
|---|---|---|
| Trust Model | Trusts the source content | Zero-Trust — every file is untrusted input |
| Site Awareness | Filesystem-only | Virtual Site Map — engine-aware projection |
| Security Layer | None | Shield (9 secret families) + Blood Sentinel (path traversal) |
| CI/CD Footprint | Requires build step or Node.js | Pure Python, subprocess-free, uvx-ready |
| Diagnostic System | Free-form messages | Zxxx Registry — traceable, filterable codes |
| Orphan Detection | Not in scope | R21 Law — nav-surface awareness |
| Output Format | Text / exit code | Text, JSON, SARIF 2.1.0 |
The choice of which tool to run depends on which question you need to answer. If the question is "do these links resolve?", a link checker is the right tool. If the question is "is this documentation safe, complete, and navigable?", the trust model matters — and Zero-Trust is the only honest answer when documentation is produced by teams, contributors, or automated agents you do not fully control.
The Safe Harbor: What v0.7.0 Completes
The term "Safe Harbor" has been in Zenzic's vocabulary since the first engineering post. This is what it means in v0.7.0:
| Pillar | Guarantee |
|---|---|
| Engine parity | Z404 config asset checking in Docusaurus, MkDocs, and Zensical |
| Core purity | validator.py contains zero engine-name references (Purity Protocol) |
| Zero-trust input | Documentation treated as untrusted input; Shield operates on every scan |
| Sovereign root | zenzic.toml follows the target, not the caller — monorepo-safe |
| SARIF integration | All findings in GitHub Code Scanning format (--format sarif) |
| Diagnostic traceability | Every finding carries a Zxxx code with severity, message, and fix |
| Verified test surface | 1,485+ passing tests, mutant-tested boundaries, cross-platform CI |
| UX-Discoverability | Navbar + footer harvesting — orphan detection sees what readers see |
This is not a list of aspirational features. Each row has a test class, a CHANGELOG entry, and a decision record documenting the architectural choice that makes it true.
SARIF: Documentation Quality in Your Security Dashboard
Starting with v0.7.0, every zenzic check command supports --format sarif:
zenzic check all ./docs --format sarif > results.sarif
The output is valid SARIF 2.1.0, consumable directly by GitHub Code Scanning. Add this to your CI workflow:
- name: Run Zenzic
run: uvx zenzic check all ./docs --format sarif > zenzic.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: zenzic.sarif
Your documentation findings — broken links, orphan pages, credential fragments, missing assets — appear in the Security tab of your repository, tracked alongside code vulnerabilities. Findings are filterable by Zxxx code, assignable, and closeable through the same workflow as any other security advisory.
The documentation pipeline is now a first-class citizen of your security posture.
The Purity Protocol: Zero Engine Leaks in Core
One invariant that emerged from the consolidation and defines the v0.7.0 architecture:
validator.py — the heart of Zenzic — contains no reference to any engine by name.
No "docusaurus", no "sidebar", no "navbar". The Core receives a frozenset[str] of
navigable paths from adapter.get_nav_paths(). What lives inside that method is the
adapter's problem, not the Core's.
# validator.py — the entire engine interface
nav_paths = adapter.get_nav_paths() # frozenset[str] | frozenset()
For Docusaurus, get_nav_paths() is a Multi-Source Harvester: it merges sidebar IDs,
navbar to: paths, and footer to: paths into a single frozenset before returning it.
The Core never sees the difference. For MkDocs, the same method returns nav: entries.
For Zensical, it returns nav: entries. For Standalone, it returns frozenset().
One interface. Four adapters. Zero engine leaks in Core.
Adding a new adapter that modifies validator.py is a protocol violation. The
adapter contract is the boundary — everything engine-specific must live behind it.
The Zenzic Lab: 20 Acts
The Lab is the fastest way to understand what Zenzic does. Run it now:
uvx zenzic lab
Twenty interactive Acts, each demonstrating a distinct capability against bundled fixture projects:
| Acts | Coverage |
|---|---|
| Acts 0–2 | MkDocs foundations — linter demo, gold standard, broken docs |
| Act 3 | Shield — credential exposure (security breach, exit 2) |
| Acts 4–5 | Scoped targets — single file, custom directory |
| Act 6 | Zensical — transparent proxy (SENTINEL bridge) |
| Act 7 | Docusaurus v3 enterprise — versioning, @site/ aliases, i18n |
| Act 8 | Standalone Mode — full scan, zero nav contract |
| Acts 9–10 | Config asset guards — Z404 (MkDocs + Zensical) |
| Acts 11–12 | OS security — Unix path traversal, Windows path integrity |
| Acts 13–14 | Rules deep-dive — link graph stress, Shield obfuscation |
| Acts 15–16 | Quality rules — SEO coverage (Z401/Z402), quality gate (Z501/Z503) |
| Acts 17–18 | Quality scoring — penalty scorer, score regression scenarios |
| Act 19 | The Base64 Shadow — encoded credential detection |
No configuration required. No project to set up. The Lab runs against bundled fixture projects — no temporary files, no teardown required. The entire experience runs in under 90 seconds on a cold start.
The Documentation of the Documentation Tool
One constraint that emerged during the Diátaxis restructure of zenzic.dev: a
documentation tool that ships with poorly organised documentation is not a credible
authority on documentation quality.
The site now follows the Diátaxis framework across four modes:
- Tutorials — step-by-step learning paths for new users
- How-To Guides — task-oriented instructions for specific problems
- Reference — the complete Zxxx diagnostic registry, CLI interface, and engine specs
- Explanation — the architectural decisions, security model, and design philosophy
Every URL changed in the restructure. The Sovereign Root Protocol found all three
README.md links pointing at the old paths before any user reported them. The tool
caught its own documentation drift.
Get Started in 30 Seconds
uvx zenzic lab
No installation required. uvx resolves and runs Zenzic from PyPI in a temporary
environment. The Lab will walk you through every capability interactively.
For a permanent installation:
uv add --dev zenzic
# or
pip install zenzic
Then run a check against your documentation:
zenzic check all ./docs
| GitHub | github.com/PythonWoods/zenzic |
| Documentation | zenzic.dev |
| PyPI | pypi.org/project/zenzic |
| Changelog | v0.7.0 Release Notes |
This is Part 5 of a five-part engineering series documenting the path from v0.5 to v0.7.0 Stable.
Part 1 — The Sentinel · Part 2 — Sentinel Bastion · Part 3 — The AI Siege · Part 4 — Beyond the Siege · Part 5 — Quartz Maturity
Part 5 of the Zenzic Chronicles. For the complete architectural journey, visit the Safe Harbor Blog.
The 1,525-line Obsidian Masterclass covers every component in depth — verified by 1,485+ tests across Python 3.10 and 3.14.