ADR 005: Agnostic Universalism — Z404 for All Engines
Status: Active Decider: Architecture Lead Date: 2026-04-20 (v0.7.0 sprint)
Context
Z404 (CONFIG_ASSET_MISSING) was originally implemented exclusively for the
Docusaurus adapter. It detected when a file declared in docusaurus.config.ts
(favicon, Open Graph image, custom CSS) did not exist on disk.
This created a structural contradiction: Zenzic's public claim is that it is a
Safe Harbor for all documentation engines. Offering a config-asset integrity
check only to Docusaurus users violated this claim. An MkDocs project declaring
a theme.favicon that pointed to a non-existent file would receive no
diagnostic — a silent gap in the safety perimeter.
Decision
Z404 was extended from a Docusaurus-only check to a universal check covering
all supported engines. Each adapter declares which config assets it owns, and the
core engine invokes check_config_assets() uniformly across all adapters.
| Engine | Assets checked |
|---|---|
| Docusaurus | customCss, favicon, Open Graph image, social card paths in themeConfig |
| MkDocs | theme.favicon, theme.logo (resolved relative to docs_dir/) |
| Zensical | [project].favicon, [project].logo |
| Standalone | — (no engine config file; check is a no-op) |
Rationale
1. Safe Harbor Means All Ports
A harbor that is safe only for Docusaurus ships is not a Safe Harbor — it is a branded harbor with a size restriction. The moment a check is engine-specific without a technical reason, it signals to contributors that engine parity is optional. That signal compounds over releases.
2. The Adapter Protocol Already Provides the Hook
BaseAdapter already defined check_config_assets() as an optional method. The
universalism decision was not an architectural change — it was the activation of
an already-present architectural contract. Every adapter already had the
infrastructure; only the MkDocs and Zensical implementations were missing.
3. Preventing the "Trusted Config" Assumption
The implicit assumption that engine configuration files contain valid asset paths
is the same category of trust error that Zenzic was designed to eliminate. A
theme.favicon: assets/icon.png that doesn't exist is a broken link — it just
happens to live in a YAML file rather than a Markdown document.
Implementation
Each adapter's check_config_assets() method:
- Reads the engine config file (one-time I/O, not in a hot loop).
- Resolves each declared asset path against
docs_root. - Emits a
Findingwith codeZ404for each path that does not exist on disk.
The core check_all() pipeline calls adapter.check_config_assets() after the
per-file scan phase, ensuring Z404 findings appear in the same SARIF report and
exit-code accounting as all other findings.
Consequences
-
MkDocs and Zensical users gain asset integrity validation without any config change.
-
Adding a new engine adapter requires implementing
check_config_assets()— theprotocol now enforces this explicitly (a
NotImplementedErroris raised for adapters that skip it). -
Z404 is now classified as a universal quality check, not an engine-specific
feature, in
reference/finding-codes.mdx.