Skip to content

PythonWoods/zenzic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

152 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Zenzic Zenzic

PyPI Version Python Versions License

Zenzic Shield Zenzic Score Built with Docusaurus 4-Gates: Sentinel Seal REUSE 3.x compliant

Zenzic Shield internally audits this repository for credential leaks on every commit.

Deterministic audit of documentation structures with bidirectional traceability.
Every finding maps to a source file and a line number. Every URL has a physical origin. Zero global state.


โšก Try it now โ€” Zero Installation

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

uvx zenzic check all ./your-folder

Zenzic will identify your engine via its configuration files or default to Standalone Mode for plain Markdown folders โ€” providing immediate protection for links, credentials, and file integrity.

Note: In Standalone Mode there is no declared navigation contract, so orphan-page detection (Z402) is disabled. What you get: full link validation (Z101/Z104), credential scanning (Z201), path-traversal blocking (Z202), and directory-index integrity checks (Z401).


๐Ÿš€ Quick Start

pip install zenzic
zenzic lab        # Interactive showroom โ€” 9 acts, every engine, zero setup
zenzic check all  # Audit the current directory

๐Ÿ“– Full docs โ†’ ยท ๐Ÿ… Badges ยท ๐Ÿ”„ CI/CD guide


๐Ÿš€ CI/CD Ready: Use the Official Zenzic Action to run Zenzic in GitHub Actions โ€” findings surface directly in Code Scanning, PR annotations, and the Security tab.

- uses: PythonWoods/zenzic-action@v1
  with:
    format: sarif
    upload-sarif: "true"

GitHub Code Scanning showing Zenzic findings


๐ŸŽฏ 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.
  • Not a blackbox. Every finding carries a code, a source file, and a line number. Absolute traceability โ€” no finding without a physical origin.

๐Ÿ“‹ Capability Matrix

Capability Command Detects Exit
Link integrity check links Broken links, dead anchors 1
Circular anchors check all Self-referential anchor links (Z107) 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
Untagged code blocks check all Fenced blocks with no language specifier (Z505) 1
Placeholder content check placeholders Stub pages and forbidden text patterns 1
Unused assets check assets Images and files not referenced anywhere 1
Config asset integrity check all Favicon and OG image paths declared in engine config confirmed on disk (Z404) 1
Brand integrity check all Obsolete release codenames (Z905) โ€” configurable via [project_metadata] 1
Credential scanning check references 9 credential families โ€” text, URLs, code blocks 2
Path traversal check links System-path escape attempts 3
Enterprise reporting check all --format sarif SARIF 2.1.0 output for GitHub Code Scanning โ€” inline PR annotations 1/2/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.7.1 "Quartz Maturity" (Stable) โ€” Z104 proactive suggestions, Standalone Mode truth audit, and Engineering Ledger hardening. See 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 PAT, Stripe, Slack, OpenAI, Google, PEM headers, hex payloads. Base64 speculative decoding catches obfuscated credentials in frontmatter and code blocks. โ†’ 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 DocusaurusAdapter Versioned docs, @site/ alias, Ghost Route detection, Virtual Routes (Tags, Pagination, Authors)
MkDocs MkDocsAdapter i18n suffix + folder modes, fallback_to_default
Zensical ZensicalAdapter Transparent Proxy bridges mkdocs.yml if zensical.toml absent
Any folder StandaloneAdapter File integrity checks only โ€” orphan detection disabled without a nav contract

Third-party adapters install via the zenzic.adapters entry-point group. See the Developer Guide for the adapter API.

Docusaurus Virtual Routes

Docusaurus generates URL pages that have no physical Markdown source: tag listing pages (/blog/tags/python/), paginated blog indexes (/blog/page/2/), and author pages (/blog/authors/alice/). Before EPOCH 7b, Zenzic had no knowledge of these routes, so any link pointing at them was incorrectly flagged as a broken link.

DocusaurusAdapter now builds a Virtual Route map derived from frontmatter metadata โ€” no build step needed, no Node.js execution. Each virtual route carries a source_files set that traces it back to the physical files that generate it, satisfying the Reverse-Mapping Invariant: every URL in the VSM has an unambiguous physical origin. A VirtualRoute with source_files=frozenset() raises ValueError at construction โ€” no untraced URL can reach the VSM.


โš™๏ธ Configuration

Zero-config by default. Full priority chain: CLI flags > zenzic.toml > [tool.zenzic] in pyproject.toml > built-ins. CLI flags always take precedence over configuration files.

# 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 | standalone
default_locale = "en"
locales        = ["it"]
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:

[[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.

DFA Guarantee (v0.7.1+): Custom rule patterns must be RE2-compatible โ€” backreferences, lookaheads, and lookbehinds are rejected at load time. See Architecture โ€บ DFA Guarantee.


๐Ÿ”„ CI/CD Integration

Official GitHub Action (Recommended)

permissions:
  contents: read
  security-events: write   # required for Code Scanning upload

steps:
  - uses: actions/checkout@v6

  - name: ๐Ÿ›ก๏ธ Zenzic Documentation Quality Gate
    uses: PythonWoods/zenzic-action@v1
    with:
      format: sarif
      upload-sarif: "true"   # findings appear in the Security tab and as PR annotations

Zero-install with uvx

- 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. Full workflow: .github/workflows/ci.yml


๐Ÿ“ฆ Installation

# 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

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

Python compatibility: Zenzic requires Python 3.10+. In CI, every release is officially validated against Python 3.10 (Floor โ€” legacy compatibility) and Python 3.14 (Peak โ€” performance and future-readiness). If you run any version in between, it works.


๐Ÿ–ฅ๏ธ CLI Reference

# Checks
zenzic check links [--strict] [--no-external]
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] [--no-external]

# 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

Zenzic Sentinel Report โ€” All checks passed, score 100/100

Visit the documentation portal for interactive screenshots and rich examples.


๐Ÿ“– Documentation Map โ€” Quartz Promise

Zenzic's docs ship as two separate Docusaurus instances under the same domain. Each has its own sidebar, search, and audience โ€” never mixed.

zenzic.dev/
โ”œโ”€โ”€ docs/           โ†’ User Area    โ€” install, configure, CI/CD, finding codes
โ”œโ”€โ”€ developers/     โ†’ Dev Area     โ€” plugins, adapters, ADRs, tech debt ledger
โ”œโ”€โ”€ blog/           โ†’ Release notes & engineering post-mortems
โ””โ”€โ”€ community/      โ†’ Brand kit, FAQs, governance

The Quartz Promise. Two instances, one Sentinel. The split is enforced by ADR 011: Cross-Instance Allowlist โ€” every cross-boundary link is a documented contract, never a silent suppression. Hidden debt corrupts trust; declared debt is engineering. See the Technical Debt Ledger for what we deferred and why.

Entry points:

You are a... Start here
๐Ÿ‘ค User integrating Zenzic uvx zenzic lab ยท User Guide
๐Ÿ”ง Contributor / plugin author Developer Portal ยท ADR Vault
๐Ÿ›ก๏ธ Security reviewer Engineering Ledger ยท SECURITY.md

๐Ÿงฑ Engineering Ledger

Zenzic is governed by three non-negotiable operational contracts โ€” each enforce-able by machine, not by convention.

Three design axioms from the NASA Power of 10 โ€” applied without exception:

  • Rule 1 / Rule 4 โ€” Pure, deterministic control flow. The analysis engine has zero global state. Given identical inputs, Zenzic produces identical output. Every finding maps to a single source file and a single line number. No stochastic components; no inference dependencies declared in pyproject.toml.
  • Rule 2 โ€” No dynamic execution. subprocess.Popen, os.system, and all shell invocations are permanently banned from src/. Docusaurus TypeScript configs are parsed as plain text. Node.js is never invoked. The Zero Subprocess invariant is enforced by ruff and audited at every push.

These are not conventions โ€” they are machine-enforced contracts.

Zero Assumptions โ€” Every adapter runs under mypy --strict. No Any, no silent coercions. The type system is a compile-time contract โ€” not a suggestion.

# mypy: strict = true
# Zero untyped defs, zero ignored errors.

Subprocess-Free โ€” subprocess.Popen is permanently banned from src/. Docusaurus .ts configs are parsed as plain text. Node.js is never invoked.

# ruff: ban = ["subprocess"]
# Deterministic static analysis only.

Deterministic Compliance โ€” Every source file carries an SPDX header. REUSE 3.x is enforced in CI. No ambiguous licensing โ€” machine-verifiable on every PR.

# REUSE-IgnoreStart / REUSE-IgnoreEnd
# SPDX-License-Identifier: Apache-2.0

See the Architecture Guide 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

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 for the Zenzic Way checklist and PR conventions.


๐Ÿค Contributing

  1. Open an issue to discuss the change.
  2. Read the Contributing Guide โ€” 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 ยท Security Policy

๐Ÿ“Ž Citing

A CITATION.cff is present at the root. Click "Cite this repository" on GitHub for APA or BibTeX output.

๐Ÿ“„ License

Apache-2.0 โ€” see LICENSE.


๐Ÿ“š The Zenzic Chronicles

Zenzic was born from a technical journey through the fragility of modern documentation ecosystems. Discover the philosophy, the security siege, and the engineering behind the Sentinel in the Engineering Chronicles on the official blog.

The v0.7.1 release story โ€” AI-driven red-team siege, 4 bypass vectors closed, and the road to engine-agnostic parity โ€” is documented in Beyond the Siege: Zenzic v0.7.1.


PythonWoods

Engineered with precision by PythonWoods in Italy ๐Ÿ‡ฎ๐Ÿ‡น
"Building the Safe Harbor for technical knowledge."

Documentation ยท GitHub ยท Blog