From b65d3599a347431e822e9777286dedd7ad7b94d7 Mon Sep 17 00:00:00 2001 From: Piotr Ramotowski <8025853+PeterRamotowski@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:33:23 +0200 Subject: [PATCH 1/9] docs: generate complete navigation tree --- tools/docs_nav.py | 116 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 tools/docs_nav.py diff --git a/tools/docs_nav.py b/tools/docs_nav.py new file mode 100644 index 0000000..fe0cd04 --- /dev/null +++ b/tools/docs_nav.py @@ -0,0 +1,116 @@ +"""Generate MkDocs navigation from the repository's canonical metadata. + +This hook keeps generated documentation pages inside the Material navigation tree so +active tabs and side navigation remain available on deep pages without maintaining a +large static nav block by hand. +""" +from __future__ import annotations + +from pathlib import Path + +import yaml + +ROOT = Path(__file__).resolve().parents[1] + + +def load_yaml(path: Path): + return yaml.safe_load(path.read_text(encoding="utf-8")) + + +def component_pages(directory: str, metadata_name: str) -> list[dict[str, str]]: + pages: list[dict[str, str]] = [] + for metadata in sorted((ROOT / directory).glob(f"*/{metadata_name}")): + data = load_yaml(metadata) or {} + item_id = data.get("id", metadata.parent.name) + name = data.get("name") or item_id.replace("-", " ").title() + pages.append({str(name): f"{directory}/{item_id}/index.md"}) + return sorted(pages, key=lambda item: next(iter(item)).casefold()) + + +def principle_catalogue() -> list[dict[str, list[dict[str, str]]]]: + registry = load_yaml(ROOT / "principles" / "registry.yaml") or {} + categories_data = load_yaml(ROOT / "principles" / "categories.yaml") or {} + principles = registry.get("principles") or [] + + categories = [ + (category["id"], category["name"]) + for category in categories_data.get("categories") or [] + ] + + groups: list[dict[str, list[dict[str, str]]]] = [] + for category_id, category_name in categories: + entries = [item for item in principles if item.get("category") == category_id] + if not entries: + continue + pages = [ + {str(item["name"]): f"principles/compendium/{item['id']}.md"} + for item in sorted(entries, key=lambda value: str(value["name"]).casefold()) + ] + groups.append({str(category_name): pages}) + return groups + + +def evaluation_pages() -> list[dict[str, str]]: + pages: list[dict[str, str]] = [] + for path in sorted((ROOT / "evaluations" / "scenarios").glob("*.yaml")): + data = load_yaml(path) or {} + scenario_id = data.get("id", path.stem) + title = data.get("name") or data.get("title") or scenario_id.replace("-", " ").title() + pages.append({str(title): f"evaluations/{scenario_id}/index.md"}) + return sorted(pages, key=lambda item: next(iter(item)).casefold()) + + +def build_nav(): + return [ + {"Home": "index.md"}, + { + "Principles": [ + "principles/index.md", + {"Catalogue": principle_catalogue()}, + {"Classification": "principles/CLASSIFICATION.md"}, + {"Authoring guide": "principles/AUTHORING-GUIDE.md"}, + ] + }, + { + "Decision system": [ + "decision-system/index.md", + {"Core Skills": ["core/index.md", *component_pages("core", "skill.yaml")]}, + {"Project profiles": ["profiles/index.md", *component_pages("profiles", "profile.yaml")]}, + {"Modifiers": ["modifiers/index.md", *component_pages("modifiers", "modifier.yaml")]}, + {"Conflict resolution": "CONFLICT-RESOLUTION.md"}, + {"Orchestrator": "orchestrator/SKILL.md"}, + ] + }, + { + "Technologies": [ + "technologies/index.md", + {"Languages": ["languages/index.md", *component_pages("languages", "adapter.yaml")]}, + {"Frameworks": ["frameworks/index.md", *component_pages("frameworks", "adapter.yaml")]}, + ] + }, + { + "Examples": [ + "examples/index.md", + {"Evaluation scenarios": ["evaluations/index.md", *evaluation_pages()]}, + ] + }, + { + "Reference": [ + "reference/index.md", + {"Repository overview": "README.md"}, + {"Specification": "SPECIFICATION.md"}, + {"Architecture": "ARCHITECTURE.md"}, + {"Knowledge model": "KNOWLEDGE-MODEL.md"}, + {"Terminology": "TERMINOLOGY.md"}, + {"Self-containment": "SELF-CONTAINMENT.md"}, + {"Contributing": "CONTRIBUTING.md"}, + {"Roadmap": "ROADMAP.md"}, + {"Changelog": "CHANGELOG.md"}, + ] + }, + ] + + +def on_config(config, **kwargs): + config["nav"] = build_nav() + return config From 99873d3a7aea9d7e58a6dec75e1a42b3b439cd2c Mon Sep 17 00:00:00 2001 From: Piotr Ramotowski <8025853+PeterRamotowski@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:33:37 +0200 Subject: [PATCH 2/9] docs: drive navigation from metadata hook --- mkdocs.yml | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index a128f6a..455bccd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -8,33 +8,8 @@ docs_dir: .site-docs site_dir: .site-build use_directory_urls: true -nav: - - Home: index.md - - Principles: - - Browse principles: principles/index.md - - Classification: principles/CLASSIFICATION.md - - Authoring guide: principles/AUTHORING-GUIDE.md - - Decision system: - - Core Skills: core/index.md - - Project profiles: profiles/index.md - - Modifiers: modifiers/index.md - - Conflict resolution: CONFLICT-RESOLUTION.md - - Orchestrator: orchestrator/SKILL.md - - Technologies: - - Languages: languages/index.md - - Frameworks: frameworks/index.md - - Examples: - - Evaluation scenarios: evaluations/index.md - - Reference: - - Repository overview: README.md - - Specification: SPECIFICATION.md - - Architecture: ARCHITECTURE.md - - Knowledge model: KNOWLEDGE-MODEL.md - - Terminology: TERMINOLOGY.md - - Self-containment: SELF-CONTAINMENT.md - - Contributing: CONTRIBUTING.md - - Roadmap: ROADMAP.md - - Changelog: CHANGELOG.md +hooks: + - tools/docs_nav.py theme: name: material From bd59497714c62183c1bc3e75380f00e7770a0f57 Mon Sep 17 00:00:00 2001 From: Piotr Ramotowski <8025853+PeterRamotowski@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:33:54 +0200 Subject: [PATCH 3/9] docs: add Reference landing page --- docs-site/reference/index.md | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 docs-site/reference/index.md diff --git a/docs-site/reference/index.md b/docs-site/reference/index.md new file mode 100644 index 0000000..1c9f7f5 --- /dev/null +++ b/docs-site/reference/index.md @@ -0,0 +1,52 @@ +# Reference + +System-level contracts, architecture, terminology, and project documentation for Code Principles. + +
+ +
+ +### System contracts + +Start with the normative specification and the architecture that defines how the knowledge base and resolver fit together. + +[Specification →](../SPECIFICATION.md) +[Architecture →](../ARCHITECTURE.md) + +
+ +
+ +### Knowledge model + +Understand classifications, terminology, precedence, and the self-containment rules behind the project. + +[Knowledge model →](../KNOWLEDGE-MODEL.md) +[Terminology →](../TERMINOLOGY.md) +[Self-containment →](../SELF-CONTAINMENT.md) + +
+ +
+ +### Repository + +Read the project overview or contribute changes to the knowledge base and tooling. + +[Repository overview →](../README.md) +[Contributing →](../CONTRIBUTING.md) + +
+ +
+ +### Project history + +See planned work and changes across releases. + +[Roadmap →](../ROADMAP.md) +[Changelog →](../CHANGELOG.md) + +
+ +
From 841466e1687c5b9fd3f5035a58a135cbee55f3bb Mon Sep 17 00:00:00 2001 From: Piotr Ramotowski <8025853+PeterRamotowski@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:34:06 +0200 Subject: [PATCH 4/9] docs: add Decision system landing page --- docs-site/decision-system/index.md | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs-site/decision-system/index.md diff --git a/docs-site/decision-system/index.md b/docs-site/decision-system/index.md new file mode 100644 index 0000000..aba3f77 --- /dev/null +++ b/docs-site/decision-system/index.md @@ -0,0 +1,48 @@ +# Decision system + +See how Code Principles turns canonical engineering knowledge into context-sensitive decisions. + +
+ +
+ +### Core Skills + +Language-independent decision procedures with modes, conflicts, constraints, and review guidance. + +[Browse Core Skills →](../core/index.md) + +
+ +
+ +### Project profiles + +Select the dominant artifact and failure model before technology-specific refinements are applied. + +[Browse project profiles →](../profiles/index.md) + +
+ +
+ +### Modifiers + +Apply verified cross-cutting constraints such as public API, security sensitivity, latency, or compatibility requirements. + +[Browse modifiers →](../modifiers/index.md) + +
+ +
+ +### Resolution rules + +Understand precedence, conflict resolution, and the orchestrator that combines the policy layers. + +[Conflict resolution →](../CONFLICT-RESOLUTION.md) +[Orchestrator →](../orchestrator/SKILL.md) + +
+ +
From 22419ae836596518135b4cccfbdc9f42be4a5640 Mon Sep 17 00:00:00 2001 From: Piotr Ramotowski <8025853+PeterRamotowski@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:34:16 +0200 Subject: [PATCH 5/9] docs: add Technologies landing page --- docs-site/technologies/index.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 docs-site/technologies/index.md diff --git a/docs-site/technologies/index.md b/docs-site/technologies/index.md new file mode 100644 index 0000000..4ab071a --- /dev/null +++ b/docs-site/technologies/index.md @@ -0,0 +1,27 @@ +# Technologies + +Language and framework adapters refine generic engineering policy with concrete runtime, lifecycle, packaging, state, and convention semantics. + +
+ +
+ +### Languages + +JavaScript, TypeScript, Python, PHP, Go, and C++ adapters refine the generic policy without redefining canonical principles. + +[Browse language adapters →](../languages/index.md) + +
+ +
+ +### Frameworks + +React, Next.js, Angular, Vue, Nuxt, Symfony, and Drupal adapters add framework-specific boundaries, lifecycle, state, and extension guidance. + +[Browse framework adapters →](../frameworks/index.md) + +
+ +
From 31de83b570a55b8008cd43a5071ca0a2da094ab7 Mon Sep 17 00:00:00 2001 From: Piotr Ramotowski <8025853+PeterRamotowski@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:34:26 +0200 Subject: [PATCH 6/9] docs: add Examples landing page --- docs-site/examples/index.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 docs-site/examples/index.md diff --git a/docs-site/examples/index.md b/docs-site/examples/index.md new file mode 100644 index 0000000..0db5298 --- /dev/null +++ b/docs-site/examples/index.md @@ -0,0 +1,17 @@ +# Examples + +Worked, executable examples show how repository evidence, project profiles, modifiers, adapters, Skill modes, and conflict decisions combine into resolved engineering policy. + +
+ +
+ +### Evaluation scenarios + +Browse generated human-readable views of the repository's executable policy scenarios. Each page shows the input evidence, expected resolution, tested principles, and forbidden outcomes. + +[Browse evaluation scenarios →](../evaluations/index.md) + +
+ +
From 191def20e1d679218f1592d8ac6d7c69f24bd7bf Mon Sep 17 00:00:00 2001 From: Piotr Ramotowski <8025853+PeterRamotowski@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:34:49 +0200 Subject: [PATCH 7/9] chore: temporarily verify documentation navigation --- .github/workflows/verify-navigation-tree.yml | 68 ++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/verify-navigation-tree.yml diff --git a/.github/workflows/verify-navigation-tree.yml b/.github/workflows/verify-navigation-tree.yml new file mode 100644 index 0000000..13ab36e --- /dev/null +++ b/.github/workflows/verify-navigation-tree.yml @@ -0,0 +1,68 @@ +name: Verify documentation navigation tree + +on: + push: + branches: + - fix/pages-navigation-tree + +permissions: + contents: write + +jobs: + verify: + if: github.actor != 'github-actions[bot]' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + ref: fix/pages-navigation-tree + - uses: actions/setup-python@v6 + with: + python-version: "3.13" + cache: pip + cache-dependency-path: | + requirements-dev.txt + requirements-docs.txt + - name: Install dependencies + run: python -m pip install -r requirements-dev.txt -r requirements-docs.txt + - name: Refresh manifest + run: python tools/update_manifest.py + - name: Validate repository + run: make validate && make validate-normative + - name: Generate and build documentation + run: | + python tools/generate_site_docs.py + mkdocs build + - name: Verify reference and deep navigation + run: | + test -f .site-build/reference/index.html + test -f .site-build/principles/compendium/avoid-accidental-complexity/index.html + test -f .site-build/profiles/reusable-library/index.html + python - <<'PY' + from pathlib import Path + import re + + principle = Path('.site-build/principles/compendium/avoid-accidental-complexity/index.html').read_text(encoding='utf-8') + profile = Path('.site-build/profiles/reusable-library/index.html').read_text(encoding='utf-8') + reference = Path('.site-build/reference/index.html').read_text(encoding='utf-8') + + assert 'Avoid Accidental Complexity' in principle + assert 'md-sidebar--primary' in principle + assert re.search(r'md-tabs__item[^\"]*md-tabs__item--active[^>]*>.*?Principles', principle, re.S), 'Principles tab is not active on detail page' + assert re.search(r'md-nav__item[^\"]*md-nav__item--active[^>]*>.*?Avoid Accidental Complexity', principle, re.S), 'Principle is not represented in active side navigation' + + assert 'Reusable Library' in profile + assert re.search(r'md-tabs__item[^\"]*md-tabs__item--active[^>]*>.*?Decision system', profile, re.S), 'Decision system tab is not active on profile detail page' + + assert ' Date: Wed, 2 Sep 2026 07:35:15 +0000 Subject: [PATCH 8/9] chore: refresh distribution manifest --- MANIFEST.sha256 | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.sha256 b/MANIFEST.sha256 index 4a490ea..4af5bdb 100644 --- a/MANIFEST.sha256 +++ b/MANIFEST.sha256 @@ -398,6 +398,7 @@ c3068c7a08e7f2ae0cc0328323937a78a677acf7c25ca714c01b54d670882f81 schemas/projec b9687f0785ccd4f186cd27ab4e58eaddf37abc43da3d3eb6f905a3d1d860db33 schemas/resolved-policy.schema.json 05936f498fac344084227cfd19ab717c308fb1dd47cfd42cd6fa5c4baa16b478 schemas/skill.schema.json d55c4d1eb6edc1ecccbee5e6db1e0bea371919ad956cbc861caa30f32228e9a3 tools/distribution.py +cbfa65a3813a7a5bc1cb7ac1276faaab31d3ab7c2463c51bbeff22145091c1d2 tools/docs_nav.py f12e52837e8b71dbc4436a2cf0a3a234f2c15823909b6c787d383451e454dcad tools/evaluate.py f90fefe7940fb9438cfec6e163724407da5166e9826f54e57c8d67aaba01e7ba tools/generate_compendium.py 0c062fd50ccf31fdcbbd37538570cca4b85bd4026f6be6909454c7dc9f1c8753 tools/generate_site_docs.py From 48e84c1688767f8dd8e6cab7d6549b7981265b13 Mon Sep 17 00:00:00 2001 From: Piotr Ramotowski <8025853+PeterRamotowski@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:35:29 +0200 Subject: [PATCH 9/9] chore: remove temporary navigation verification workflow --- .github/workflows/verify-navigation-tree.yml | 68 -------------------- 1 file changed, 68 deletions(-) delete mode 100644 .github/workflows/verify-navigation-tree.yml diff --git a/.github/workflows/verify-navigation-tree.yml b/.github/workflows/verify-navigation-tree.yml deleted file mode 100644 index 13ab36e..0000000 --- a/.github/workflows/verify-navigation-tree.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Verify documentation navigation tree - -on: - push: - branches: - - fix/pages-navigation-tree - -permissions: - contents: write - -jobs: - verify: - if: github.actor != 'github-actions[bot]' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - ref: fix/pages-navigation-tree - - uses: actions/setup-python@v6 - with: - python-version: "3.13" - cache: pip - cache-dependency-path: | - requirements-dev.txt - requirements-docs.txt - - name: Install dependencies - run: python -m pip install -r requirements-dev.txt -r requirements-docs.txt - - name: Refresh manifest - run: python tools/update_manifest.py - - name: Validate repository - run: make validate && make validate-normative - - name: Generate and build documentation - run: | - python tools/generate_site_docs.py - mkdocs build - - name: Verify reference and deep navigation - run: | - test -f .site-build/reference/index.html - test -f .site-build/principles/compendium/avoid-accidental-complexity/index.html - test -f .site-build/profiles/reusable-library/index.html - python - <<'PY' - from pathlib import Path - import re - - principle = Path('.site-build/principles/compendium/avoid-accidental-complexity/index.html').read_text(encoding='utf-8') - profile = Path('.site-build/profiles/reusable-library/index.html').read_text(encoding='utf-8') - reference = Path('.site-build/reference/index.html').read_text(encoding='utf-8') - - assert 'Avoid Accidental Complexity' in principle - assert 'md-sidebar--primary' in principle - assert re.search(r'md-tabs__item[^\"]*md-tabs__item--active[^>]*>.*?Principles', principle, re.S), 'Principles tab is not active on detail page' - assert re.search(r'md-nav__item[^\"]*md-nav__item--active[^>]*>.*?Avoid Accidental Complexity', principle, re.S), 'Principle is not represented in active side navigation' - - assert 'Reusable Library' in profile - assert re.search(r'md-tabs__item[^\"]*md-tabs__item--active[^>]*>.*?Decision system', profile, re.S), 'Decision system tab is not active on profile detail page' - - assert '