Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@

END OF TERMS AND CONDITIONS

Copyright 2025 Cell Location Analyzer Contributors
Copyright 2026 PythonWoods <dev@pythonwoods.dev>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
5 changes: 2 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ other build tool during `check`, `score`, or `diff`. The attack surface is limit

| Version | Support status |
| :------ | :------------- |
| `0.4.x` (current) | ✅ Security fixes backported |
| `0.3.x` | ⚠️ Critical fixes only |
| `< 0.3` | ❌ End of life — upgrade recommended |
| `0.4.x` (current) | ✅ All security fixes |
| `< 0.4` | ❌ Not publicly released — no support |

## Disclosure policy

Expand Down
2 changes: 1 addition & 1 deletion docs/about/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ icon: lucide/info

# About Zenzic

Zenzic is an engineering-grade documentation linter and quality gate for MkDocs and Zensical projects.
Zenzic is an engineering-grade documentation linter and quality gate for any Markdown-based project.

Built by [PythonWoods](https://github.com/PythonWoods), it is designed to run in CI/CD pipelines and catch documentation issues before they reach users.

Expand Down
7 changes: 4 additions & 3 deletions docs/about/philosophy.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ The implementation of this commitment is **absolute engine-agnosticism**:
- Third-party adapters install as Python packages and are discovered at runtime via entry-points.
Adding support for a new engine (Hugo, Docusaurus, Sphinx) requires no Zenzic release.

The practical consequence: a project migrating from MkDocs to Zensical can run `zenzic check all`
continuously against both configurations simultaneously. A project that has not yet decided on a
build engine can still validate its documentation quality today.
The practical consequence: a project migrating from MkDocs to Zensical — or to Hugo, Docusaurus,
or any future generator — can run `zenzic check all` continuously against both configurations
simultaneously. A project that has not yet decided on a build engine can still validate its
documentation quality today, using Vanilla mode with zero configuration.

---

Expand Down
19 changes: 17 additions & 2 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,20 @@ Every Zenzic run follows the same four-stage pipeline, regardless of the documen
flowchart LR
classDef source fill:#0f172a,stroke:#38bdf8,stroke-width:2px,color:#e2e8f0
classDef adapter fill:#0f172a,stroke:#7c3aed,stroke-width:2px,color:#e2e8f0
classDef vsm fill:#0f172a,stroke:#f59e0b,stroke-width:2px,color:#e2e8f0
classDef engine fill:#0f172a,stroke:#10b981,stroke-width:2px,color:#e2e8f0
classDef output fill:#0f172a,stroke:#f59e0b,stroke-width:2px,color:#e2e8f0
classDef output fill:#0f172a,stroke:#dc2626,stroke-width:2px,color:#e2e8f0

S["📄 Source\n.md files\nzenzic.toml"]:::source
A["🔌 Adapter\nMkDocsAdapter\nZensicalAdapter\nVanillaAdapter"]:::adapter
V["🗺️ Virtual Site Map\nURL → Route\n(status · anchors)"]:::vsm
R["⚙️ Rule Engine\nBuilt-in checks\nCustom Rules DSL\nPlugin rules"]:::engine
F["📋 Findings\nIntegrityReport\nRuleFindings\nExit code"]:::output

S -->|"get_adapter()"| A
A -->|"nav_paths\nlocale_dirs\nasset_fallback"| R
A -->|"nav_paths\nlocale_dirs\nasset_fallback"| V
S -->|"raw Markdown text"| V
V -->|"routing state\nGhost Routes\nanchor index"| R
S -->|"raw Markdown text"| R
R --> F
```
Expand Down Expand Up @@ -85,6 +89,17 @@ flowchart TD
CAC --> VIO
```

### Terminology: Route vs Path

**Path** — the filesystem location of a source file, relative to `docs/`
(e.g. `guide/index.md`).

**Route** — the canonical URL the build engine will serve for that file
(e.g. `/guide/`). The same source Path can resolve to different Routes under
different engines. The VSM maps every known Path to exactly one Route and
assigns it a status. All link validation and orphan detection operate on
Routes, never on raw Paths — this is what makes Zenzic engine-agnostic.

### Route status values

| Status | Set by | Meaning |
Expand Down
18 changes: 18 additions & 0 deletions docs/guide/engines.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,24 @@ It reads `mkdocs.yml` using a permissive YAML loader that silently ignores unkno
(such as MkDocs `!ENV` interpolation), so environment-variable-heavy configs work without
any preprocessing.

### Static analysis limits

`MkDocsAdapter` parses `mkdocs.yml` as **static data**. It does not execute the MkDocs
build pipeline. This means:

- **`!ENV` tags** — silently treated as `null`. If your nav relies on environment variable
interpolation at build time, the nav entries that depend on those values will be absent
from Zenzic's view.
- **Plugin-generated nav** — plugins that mutate the nav at runtime (e.g. `mkdocs-awesome-pages`,
`mkdocs-literate-nav`) produce a navigation tree that Zenzic never sees. Pages included
only by these plugins will be reported as orphans.
- **Macros** — `mkdocs-macros-plugin` (Jinja2 templates in Markdown) is not evaluated.
Links inside macro expressions are not validated.

For projects that rely heavily on dynamic nav generation, add the plugin-generated paths to
`excluded_dirs` in `zenzic.toml` to suppress false orphan reports until a native adapter
is available.

### Minimal configuration

```toml
Expand Down
Loading