Metadata-Version: 2.4
Name: zenzic
Version: 0.6.1
Summary: Engineering-grade, engine-agnostic linter and security shield for Markdown documentation
Project-URL: Homepage, https://zenzic.dev
Project-URL: Documentation, https://zenzic.dev/docs/
Project-URL: Repository, https://github.com/PythonWoods/zenzic
Project-URL: Changelog, https://github.com/PythonWoods/zenzic/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/PythonWoods/zenzic/issues
Author-email: PythonWoods <dev@pythonwoods.dev>
License-Expression: Apache-2.0
License-File: LICENSE
License-File: LICENSES/Apache-2.0.txt
Keywords: ci,documentation,json,links,linter,mkdocs,security,strict,toml,yaml,zensical
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Documentation
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.11
Requires-Dist: httpx<1.0,>=0.27
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: rich>=15.0.0
Requires-Dist: typer>=0.9.0
Provides-Extra: mkdocs
Requires-Dist: mkdocs>=1.6.1; extra == 'mkdocs'
Description-Content-Type: text/markdown

<!--
SPDX-FileCopyrightText: 2026 PythonWoods <dev@pythonwoods.dev>
SPDX-License-Identifier: Apache-2.0
-->

# 🛡️ Zenzic

<p align="center">
  <img src="assets/brand/svg/zenzic-wordmark.svg#gh-light-mode-only" alt="Zenzic" width="360">
  <img src="assets/brand/svg/zenzic-wordmark-dark.svg#gh-dark-mode-only" alt="Zenzic" width="360">
</p>

<p align="center">
  <a href="https://pypi.org/project/zenzic/">
    <img src="https://img.shields.io/pypi/v/zenzic?label=PyPI&color=38bdf8&style=flat-square&cacheBuster=sentinel-a4" alt="PyPI Version">
  </a>
  <a href="https://pypi.org/project/zenzic/">
    <img src="https://img.shields.io/pypi/pyversions/zenzic?color=10b981&style=flat-square" alt="Python Versions">
  </a>
  <a href="LICENSE">
    <img src="https://img.shields.io/badge/license-Apache--2.0-0d9488?style=flat-square" alt="License">
  </a>
</p>

<p align="center">
  <a href="https://github.com/PythonWoods/zenzic">
    <img src="https://img.shields.io/badge/🛡️_zenzic_shield-passing-4f46e5?style=flat-square" alt="Zenzic Shield">
  </a>
  <a href="https://github.com/PythonWoods/zenzic">
    <img src="https://img.shields.io/badge/🛡️_zenzic-100%2F100-4f46e5?style=flat-square" alt="Zenzic Score">
  </a>
  <a href="https://docusaurus.io/">
    <img src="https://img.shields.io/badge/docs_by-Docusaurus-3ECC5F?style=flat-square" alt="Built with Docusaurus">
  </a>
</p>

<p align="center">
  <em>Zenzic Shield internally audits this repository for credential leaks on every commit.</em>
</p>

<p align="center">
  <strong>The Safe Harbor for your Markdown documentation.</strong><br>
  <em>Engine-agnostic static analysis — standalone, security-hardened, zero configuration needed.</em>
</p>

---

## ⚡ Try it now — Zero Installation

Got a folder of Markdown files? Run an instant security and link audit using [`uv`][uv]:

```bash
uvx zenzic check all ./your-folder
```

Zenzic will identify your engine via its configuration files or default to **Vanilla mode** for
standalone folders — providing immediate protection for links, credentials, and structural integrity.

---

## 🚀 Quick Start

```bash
pip install zenzic
zenzic lab        # Interactive showroom — 9 acts, every engine, zero setup
zenzic check all  # Audit the current directory
```

📖 [Full docs →][docs-home] · 🏅 [Badges][docs-badges] · 🔄 [CI/CD guide][docs-cicd]

---

## 🎯 Why Zenzic?

| Without Zenzic | With Zenzic |
| :--- | :--- |
| ❌ Broken anchors silently 200 OK in Docusaurus v3 | ✅ Mathematical anchor validation via VSM |
| ❌ Leaked API keys in code blocks committed to git | ✅ **The Shield** — 9-family credential scanner, exit 2 |
| ❌ Path traversal `../../../../etc/passwd` in links | ✅ **Blood Sentinel** — non-suppressible exit 3 |
| ❌ Orphan pages unreachable from any nav link | ✅ Semantic orphan detection — not just file-exists |
| ❌ Silent 404s accumulating in Google Search Console | ✅ Directory Index Integrity checks |
| ❌ MkDocs → Zensical migration with unknown breakage | ✅ **Transparent Proxy** — lint both with one command |

---

## 🧩 What Zenzic is NOT

- **Not a site generator.** It audits source; it never builds HTML.
- **Not a build wrapper.** Zero-Trust Execution: no subprocesses, no `mkdocs` or `docusaurus` binaries invoked.
- **Not a spell checker.** Structure and security — not prose.
- **Not an HTTP crawler.** All validation is local and file-based.

---

## 📋 Capability Matrix

| Capability | Command | Detects | Exit |
| :--- | :--- | :--- | :---: |
| Link integrity | `check links` | Broken links, dead anchors | 1 |
| Orphan detection | `check orphans` | Files absent from `nav` — invisible after build | 1 |
| Code snippets | `check snippets` | Syntax errors in Python / YAML / JSON / TOML blocks | 1 |
| Placeholder content | `check placeholders` | Stub pages and forbidden text patterns | 1 |
| Unused assets | `check assets` | Images and files not referenced anywhere | 1 |
| **Credential scanning** | `check references` | **9 credential families** — text, URLs, code blocks | **2** |
| **Path traversal** | `check links` | System-path escape attempts | **3** |
| Quality score | `score` | Deterministic 0–100 composite metric | — |
| Regression detection | `diff` | Score drop vs saved baseline — CI-friendly | 1 |

**Autofix:** `zenzic clean assets [-y] [--dry-run]` deletes unused images.

> 🚀 **v0.6.1 "Obsidian Glass" (Stable)** — Full Docusaurus v3 versioning, `@site/` alias
> resolution, and Zensical Transparent Proxy. See [CHANGELOG.md](CHANGELOG.md).

---

## 🛡️ Security: The Shield & Blood Sentinel

Two security layers are permanently active — neither is suppressible by `--exit-zero`:

**The Shield** scans every line — including fenced code blocks — for credentials. Unicode
normalization defeats obfuscation (HTML entities, comment interleaving, cross-line lookback).
Detected families: AWS, GitHub/GitLab, Stripe, Slack, OpenAI, Google, PEM headers, hex payloads.
**→ Exit 2. Rotate and audit immediately.**

**Blood Sentinel** normalizes every resolved link with `os.path.normpath` and rejects any path
escaping the `docs/` root. Catches `../../../../etc/passwd`-style traversal before any OS syscall.
**→ Exit 3.**

| Exit | Meaning |
| :---: | :--- |
| `0` | All checks passed |
| `1` | Quality issues found |
| **`2`** | **SECURITY — leaked credential detected** |
| **`3`** | **SECURITY — system-path traversal detected** |

> Add `zenzic check references` to your pre-commit hooks to catch leaks before git history.

---

## 🔌 Multi-Engine Support

Zenzic reads config files as plain text — never imports or executes your build framework:

| Engine | Adapter | Highlights |
| :--- | :--- | :--- |
| [Docusaurus v3][docusaurus] | `DocusaurusAdapter` | Versioned docs, `@site/` alias, Ghost Route detection |
| [MkDocs][mkdocs] | `MkDocsAdapter` | i18n suffix + folder modes, `fallback_to_default` |
| [Zensical][zensical] | `ZensicalAdapter` | Transparent Proxy bridges `mkdocs.yml` if `zensical.toml` absent |
| Any folder | `VanillaAdapter` | Zero-config, Directory Index Integrity — no engine required |

Third-party adapters install via the `zenzic.adapters` entry-point group.
See the [Developer Guide][docs-arch] for the adapter API.

---

## ⚙️ Configuration

Zero-config by default. Priority: `zenzic.toml` > `[tool.zenzic]` in `pyproject.toml` > built-ins.

```toml
# zenzic.toml  (all fields optional)
docs_dir                 = "docs"
fail_under               = 80       # exit 1 if score < threshold; 0 = observe only
excluded_dirs            = ["includes", "assets", "overrides"]
excluded_build_artifacts = ["pdf/*.pdf", "dist/*.zip"]
placeholder_patterns     = ["coming soon", "todo", "stub"]

[build_context]
engine         = "mkdocs"   # mkdocs | docusaurus | zensical | vanilla
default_locale = "en"
locales        = ["it"]
```

```bash
zenzic init             # Generate zenzic.toml with auto-detected values
zenzic init --pyproject # Embed [tool.zenzic] in pyproject.toml
```

**Custom lint rules** — declare project-specific patterns in `zenzic.toml`, no Python required:

```toml
[[custom_rules]]
id       = "ZZ-NODRAFT"
pattern  = "(?i)\\bDRAFT\\b"
message  = "Remove DRAFT marker before publishing."
severity = "warning"
```

Rules fire identically across all adapters. No changes required after engine migration.

---

## 🔄 CI/CD Integration

```yaml
- name: 🛡️ Zenzic Sentinel
  run: uvx zenzic check all --strict
  # Exit 1 = quality · Exit 2 = leaked credential · Exit 3 = path traversal
  # Exits 2 and 3 are never suppressible.

- name: Regression gate
  run: |
    uvx zenzic score --save    # on main branch
    uvx zenzic diff            # on PR — exit 1 if score drops
```

For badge automation and regression gates, see the [CI/CD guide][docs-cicd].
Full workflow: [`.github/workflows/ci.yml`][ci-workflow]

---

## 📦 Installation

```bash
# Zero-install, one-shot audit (recommended for CI and exploration)
uvx zenzic check all ./docs

# Global CLI tool
uv tool install zenzic

# Pinned dev dependency
uv add --dev zenzic

# pip
pip install zenzic
pip install "zenzic[mkdocs]"   # + MkDocs build-time plugin
```

> The `[mkdocs]` extra adds the build-time plugin (`zenzic.integrations.mkdocs`).
> All engine adapters (Docusaurus, Zensical, Vanilla) are included in the base install.

**Portability:** Zenzic rejects absolute internal links (starting with `/`). Relative links
work at any hosting path. External `https://` URLs are never affected.

---

## 🖥️ CLI Reference

```bash
# Checks
zenzic check links [--strict]
zenzic check orphans
zenzic check snippets
zenzic check placeholders
zenzic check assets
zenzic check references [--strict] [--links]
zenzic check all [--strict] [--exit-zero] [--format json] [--engine ENGINE]
zenzic check all [--exclude-dir DIR] [--include-dir DIR]

# Score & diff
zenzic score [--save] [--fail-under N]
zenzic diff  [--threshold N]

# Autofix
zenzic clean assets [-y] [--dry-run]

# Init
zenzic init [--pyproject]

# Interactive showroom
zenzic lab [--act N] [--list]
```

---

## 📟 Visual Tour

```text
╭───────────────────────  🛡  ZENZIC SENTINEL  v0.6.1  ────────────────────────╮
│                                                                              │
│  docusaurus • 38 files (18 docs, 20 assets) • 0.9s                           │
│                                                                              │
│  ────────────────────── docs/guides/setup.mdx ───────────────────────────  │
│                                                                              │
│    ✗ 12:   [Z001]  'quickstart.mdx' not found in docs                        │
│        │                                                                     │
│    12  │ Read the [quickstart guide](quickstart.mdx) first.                  │
│        │                                                                     │
│  ──────────────────────────────────────────────────────────────────────────  │
│                                                                              │
│  ✗ 1 error  • 1 file with findings • FAILED                                  │
│                                                                              │
╰──────────────────────────────────────────────────────────────────────────────╯
```

Visit the [documentation portal][docs-home] for interactive screenshots and rich examples.

---

## 🗺️ Roadmap v0.7.0

- [ ] **Auto-fix Engine** — Automatic repair of broken links and orphaned anchors.
- [ ] **IDE Extensions** — Real-time linting for VS Code and Cursor via LSP.
- [ ] **AI Context Provider** — VSM export in LLM-friendly format for AI agents.
- [ ] **Astro & VitePress Adapters** — Expanding the Safe Harbor to JS frameworks.

---

## 🏗️ Design Philosophy

Zenzic is built on three operational contracts:

**Lint the Source, Not the Build.** The VSM (Virtual Site Map) maps every `.md` file to its
canonical URL without running the build — errors are caught before they reach production.

**Zero-Trust Execution.** No subprocesses, no arbitrary code execution, no build engine imports.
Docusaurus `.ts`/`.js` configs are parsed via static text analysis — Node.js is never invoked.

**Mandatory Exclusion at Every Entry Point.** All file discovery goes through
`LayeredExclusionManager` — a 4-level hierarchy (System → VCS → Config → CLI). No global scan
without an explicit exclusion context.

See the [Architecture Guide][docs-arch] for the Two-Pass Reference Pipeline and VSM deep-dive.

---

## 🙋 FAQ

**Why not `grep`?** Grep is blind to structure. Zenzic understands Docusaurus versioning,
MkDocs i18n fallbacks, and Ghost Routes — pages that don't exist as files but are valid URLs.

**Does it run my build engine?** No. 100% subprocess-free. Static analysis on plain text only.

**Can it handle thousands of files?** Yes. Adaptive parallelism for discovery; O(1) VSM lookup
per link; content-addressable cache (`SHA256(content + config + vsm_snapshot)`) skips unchanged files.

**Shield vs Blood Sentinel?** Shield = secrets *inside* content (exit 2). Blood Sentinel =
links pointing to OS system *paths* (exit 3). Both are non-suppressible.

**No `zenzic.toml` needed?** Correct. Zenzic identifies the engine from config files present and applies safe defaults. Run
`zenzic init` at any time to generate a pre-populated config file.

**What is `zenzic lab`?** A 9-act interactive showroom covering every engine and error class.
Run it once before integrating Zenzic into any project.

---

## 🛠️ Development

```bash
uv sync --all-groups
nox -s tests       # pytest + coverage
nox -s lint        # ruff
nox -s typecheck   # mypy --strict
nox -s preflight   # lint + format + typecheck + pytest + reuse
just verify        # preflight + zenzic check all --strict (self-dogfood)
```

See the [Contributing Guide][contributing] for the Zenzic Way checklist and PR conventions.

---

## 🤝 Contributing

1. Open an [issue][issues] to discuss the change.
2. Read the [Contributing Guide][contributing] — Zenzic Way checklist, pure functions, no
   subprocesses, source-first.
3. Every PR must pass `nox -s preflight` and include REUSE/SPDX headers on new files.

See also: [Code of Conduct][coc] · [Security Policy][security]

## 📎 Citing

A [`CITATION.cff`][citation-cff] is present at the root. Click **"Cite this repository"** on
GitHub for APA or BibTeX output.

## 📄 License

Apache-2.0 — see [LICENSE][license].

---

<p align="center">
  &copy; 2026 <strong>PythonWoods</strong>. Engineered with precision.<br>
  Based in Italy 🇮🇹 &nbsp;·&nbsp; Committed to the craft of Python development.<br>
  <a href="mailto:dev@pythonwoods.dev">dev@pythonwoods.dev</a>
</p>

<!-- ─── Reference link definitions ──────────────────────────────────────────── -->

[mkdocs]:            https://www.mkdocs.org/
[docusaurus]:        https://docusaurus.io/
[zensical]:          https://zensical.org/
[uv]:                https://docs.astral.sh/uv/
[docs-home]:         https://zenzic.dev/docs/
[docs-badges]:       https://zenzic.dev/docs/usage/badges/
[docs-cicd]:         https://zenzic.dev/docs/guides/ci-cd/
[docs-arch]:         https://zenzic.dev/docs/internals/architecture-overview/
[ci-workflow]:       .github/workflows/ci.yml
[contributing]:      CONTRIBUTING.md
[license]:           LICENSE
[citation-cff]:      CITATION.cff
[coc]:               CODE_OF_CONDUCT.md
[security]:          SECURITY.md
[issues]:            https://github.com/PythonWoods/zenzic/issues
