Update 20.37_thought_router_tr_specification.md #3451
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Thought Simulator Doc Dependency Check | |
| on: | |
| pull_request: | |
| paths: | |
| - "thought_simulator/**/*.md" | |
| - "thought_simulator/scripts/check_doc_dependencies.py" | |
| - "thought_simulator/scripts/doc_address.py" | |
| - "thought_simulator/scripts/validate_doc_frontmatter_and_ids.py" | |
| - "thought_simulator/scripts/validate_relation_semantics.py" | |
| - "thought_simulator/scripts/validate_doc_naming_prefixes.py" | |
| - "thought_simulator/scripts/validate_glossary_alignment.py" | |
| - "thought_simulator/30_verification/glossary_term_registry.json" | |
| - "thought_simulator/scripts/validate_requirements_glossary_alignment.py" | |
| - "thought_simulator/scripts/validate_requirements_glossary_scope.py" | |
| - "thought_simulator/20_requirements/glossary_term_registry.json" | |
| - "thought_simulator/50_thought_simulator_design/50.01_50_series_glossary.md" | |
| - "thought_simulator/50_thought_simulator_design/glossary_term_registry.json" | |
| - "thought_simulator/scripts/validate_50_glossary_alignment.py" | |
| - "thought_simulator/scripts/validate_readme_links.py" | |
| - "thought_simulator/scripts/validate_readme_coverage.py" | |
| - "thought_simulator/scripts/validate_30_inventory_index.py" | |
| - "thought_simulator/scripts/validate_30_10_50_pairing.py" | |
| - "thought_simulator/scripts/validate_50_traceability_index.py" | |
| - "thought_simulator/30_verification/30.01_verification_inventory_index.md" | |
| - "thought_simulator/10_thought_simulator_req/50_design/**" | |
| - "thought_simulator/scripts/validate_doc_reference_targets.py" | |
| - "thought_simulator/scripts/validate_20_traceability_matrix.py" | |
| - "thought_simulator/scripts/validate_name_tables.py" | |
| - "thought_simulator/scripts/validate_shorthand_usage.py" | |
| - "thought_simulator/scripts/shorthand_patterns.py" | |
| - "thought_simulator/00_program_governance/00_identity/shorthand_registry.json" | |
| - "thought_simulator/scripts/rename_identity.py" | |
| - "thought_simulator/scripts/bootstrap_name_tables.py" | |
| - "thought_simulator/00_program_governance/00_identity/**" | |
| - ".github/workflows/thought-simulator-doc-dependency-check.yml" | |
| push: | |
| branches: ["main"] | |
| paths: | |
| - "thought_simulator/**/*.md" | |
| - "thought_simulator/scripts/check_doc_dependencies.py" | |
| - "thought_simulator/scripts/doc_address.py" | |
| - "thought_simulator/scripts/validate_doc_frontmatter_and_ids.py" | |
| - "thought_simulator/scripts/validate_relation_semantics.py" | |
| - "thought_simulator/scripts/validate_doc_naming_prefixes.py" | |
| - "thought_simulator/scripts/validate_glossary_alignment.py" | |
| - "thought_simulator/30_verification/glossary_term_registry.json" | |
| - "thought_simulator/scripts/validate_requirements_glossary_alignment.py" | |
| - "thought_simulator/scripts/validate_requirements_glossary_scope.py" | |
| - "thought_simulator/20_requirements/glossary_term_registry.json" | |
| - "thought_simulator/50_thought_simulator_design/50.01_50_series_glossary.md" | |
| - "thought_simulator/50_thought_simulator_design/glossary_term_registry.json" | |
| - "thought_simulator/scripts/validate_50_glossary_alignment.py" | |
| - "thought_simulator/scripts/validate_readme_links.py" | |
| - "thought_simulator/scripts/validate_readme_coverage.py" | |
| - "thought_simulator/scripts/validate_30_inventory_index.py" | |
| - "thought_simulator/scripts/validate_30_10_50_pairing.py" | |
| - "thought_simulator/scripts/validate_50_traceability_index.py" | |
| - "thought_simulator/30_verification/30.01_verification_inventory_index.md" | |
| - "thought_simulator/10_thought_simulator_req/50_design/**" | |
| - "thought_simulator/scripts/validate_doc_reference_targets.py" | |
| - "thought_simulator/scripts/validate_20_traceability_matrix.py" | |
| - "thought_simulator/scripts/validate_name_tables.py" | |
| - "thought_simulator/scripts/validate_shorthand_usage.py" | |
| - "thought_simulator/scripts/shorthand_patterns.py" | |
| - "thought_simulator/00_program_governance/00_identity/shorthand_registry.json" | |
| - "thought_simulator/scripts/rename_identity.py" | |
| - "thought_simulator/scripts/bootstrap_name_tables.py" | |
| - "thought_simulator/00_program_governance/00_identity/**" | |
| - ".github/workflows/thought-simulator-doc-dependency-check.yml" | |
| jobs: | |
| dependency-check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Run dependency lint | |
| run: python thought_simulator/scripts/check_doc_dependencies.py | |
| - name: Run governance marker validation (blocking) | |
| shell: bash | |
| run: | | |
| python - <<'PY' | |
| from pathlib import Path | |
| import sys | |
| required_markers = { | |
| "thought_simulator/USER_GUIDE.md": [ | |
| "No Automatic Propagation From 20 (Mandatory)", | |
| "selected direction (`forward` or `backward`)", | |
| ], | |
| "thought_simulator/10_thought_simulator_req/docs/promotion_protocol.md": [ | |
| "No-auto-propagation rule:", | |
| "selected direction (`forward` or `backward`)", | |
| ], | |
| "thought_simulator/30_verification/README.md": [ | |
| "No-auto-propagation from 20-layer edits:", | |
| "selected direction (`forward` or `backward`)", | |
| ], | |
| "thought_simulator/40_thought_simulator_playground/40.05_master_program_guide.md": [ | |
| "No-auto-propagation from 20-layer edits:", | |
| "selected flow direction: `forward` or `backward`", | |
| ], | |
| "thought_simulator/50_thought_simulator_design/50.05_software_spec_construction_guide.md": [ | |
| "No-auto-propagation from 20-layer edits:", | |
| "chosen direction (`forward` or `backward`)", | |
| ], | |
| } | |
| failures = [] | |
| for rel_path, markers in required_markers.items(): | |
| path = Path(rel_path) | |
| if not path.exists(): | |
| failures.append(f"missing required file: {rel_path}") | |
| continue | |
| content = path.read_text(encoding="utf-8") | |
| for marker in markers: | |
| if marker not in content: | |
| failures.append(f"missing marker in {rel_path}: {marker}") | |
| if failures: | |
| print("ERROR: governance marker validation failed.") | |
| for failure in failures: | |
| print(f"- {failure}") | |
| sys.exit(1) | |
| print("Governance marker validation passed.") | |
| PY | |
| - name: Run rename-triggered maintenance guard (blocking) | |
| shell: bash | |
| run: | | |
| python - <<'PY' | |
| import os | |
| import subprocess | |
| import sys | |
| AUTO_GLOSSARY = "thought_simulator/30_verification/30.30_verification_glossary.md" | |
| AUTO_REGISTRY = "thought_simulator/30_verification/glossary_term_registry.json" | |
| AUTO_50_INDEX = "thought_simulator/50_thought_simulator_design/50.00_design_traceability_index.md" | |
| AUTO_30_INDEX = "thought_simulator/30_verification/30.01_verification_inventory_index.md" | |
| IDENTITY_TABLES = ( | |
| "thought_simulator/00_program_governance/00_identity/40_name_table.json", | |
| "thought_simulator/00_program_governance/00_identity/10.50_name_table.json", | |
| "thought_simulator/00_program_governance/00_identity/30_name_table.json", | |
| "thought_simulator/00_program_governance/00_identity/50_name_table.json", | |
| ) | |
| SCOPE_PREFIXES = ( | |
| "thought_simulator/30_verification/", | |
| "thought_simulator/40_thought_simulator_playground/", | |
| "thought_simulator/50_thought_simulator_design/", | |
| "thought_simulator/10_thought_simulator_req/50_design/", | |
| ) | |
| AUTO_40_INVENTORY = "thought_simulator/40_thought_simulator_playground/40.510_refactor.md" | |
| AUTO_40_README = "thought_simulator/40_thought_simulator_playground/README.md" | |
| # Note: 40, 20, and 50 have standalone component numbering. | |
| # 30 numbering is coupled only to 10.50 (see validate_30_10_50_pairing.py). | |
| # This guard enforces inventory + identity-table maintenance when governed | |
| # paths or module directories are renamed. | |
| def run_git(args): | |
| return subprocess.check_output(["git", *args], text=True).splitlines() | |
| def in_scope(path: str) -> bool: | |
| return path.startswith(SCOPE_PREFIXES) | |
| def is_module_dir(path: str) -> bool: | |
| parts = path.rstrip("/").split("/") | |
| if len(parts) < 2: | |
| return False | |
| leaf = parts[-1] | |
| parent = parts[-2] | |
| if parent == "40_thought_simulator_playground" and leaf.startswith("40."): | |
| return True | |
| if parent == "30_verification" and leaf.startswith("30."): | |
| return True | |
| return False | |
| event_name = os.getenv("GITHUB_EVENT_NAME", "") | |
| if event_name == "pull_request": | |
| base_ref = os.getenv("GITHUB_BASE_REF", "") | |
| if not base_ref: | |
| print("ERROR: pull_request event missing GITHUB_BASE_REF") | |
| sys.exit(1) | |
| subprocess.check_call(["git", "fetch", "--no-tags", "origin", base_ref]) | |
| diff_range = f"origin/{base_ref}...HEAD" | |
| else: | |
| try: | |
| run_git(["rev-parse", "HEAD~1"]) | |
| except subprocess.CalledProcessError: | |
| print("No previous commit available; skipping rename-triggered maintenance guard.") | |
| sys.exit(0) | |
| diff_range = "HEAD~1..HEAD" | |
| status_lines = run_git(["diff", "--name-status", diff_range]) | |
| changed_paths = set() | |
| renamed_items = [] | |
| for line in status_lines: | |
| parts = line.split("\t") | |
| if not parts: | |
| continue | |
| status = parts[0] | |
| paths = parts[1:] | |
| for p in paths: | |
| changed_paths.add(p) | |
| if status.startswith("R") and len(paths) >= 2: | |
| old_path, new_path = paths[0], paths[1] | |
| if not (in_scope(old_path) or in_scope(new_path)): | |
| continue | |
| is_md = old_path.endswith(".md") or new_path.endswith(".md") | |
| is_dir_rename = is_module_dir(old_path) or is_module_dir(new_path) | |
| if is_md or is_dir_rename: | |
| renamed_items.append((old_path, new_path)) | |
| if not renamed_items: | |
| print("No governed renames detected in 30/40/50/10.50; rename-triggered maintenance guard passed.") | |
| sys.exit(0) | |
| required_paths = {AUTO_GLOSSARY, AUTO_REGISTRY} | |
| required_paths.update(IDENTITY_TABLES) | |
| rename_touches_50 = any( | |
| old.startswith("thought_simulator/50_thought_simulator_design/") | |
| or new.startswith("thought_simulator/50_thought_simulator_design/") | |
| for old, new in renamed_items | |
| ) | |
| rename_touches_30 = any( | |
| old.startswith("thought_simulator/30_verification/") | |
| or new.startswith("thought_simulator/30_verification/") | |
| for old, new in renamed_items | |
| ) | |
| rename_touches_1050 = any( | |
| old.startswith("thought_simulator/10_thought_simulator_req/50_design/") | |
| or new.startswith("thought_simulator/10_thought_simulator_req/50_design/") | |
| for old, new in renamed_items | |
| ) | |
| rename_touches_40 = any( | |
| old.startswith("thought_simulator/40_thought_simulator_playground/") | |
| or new.startswith("thought_simulator/40_thought_simulator_playground/") | |
| for old, new in renamed_items | |
| ) | |
| if rename_touches_50: | |
| required_paths.add(AUTO_50_INDEX) | |
| if rename_touches_30 or rename_touches_1050: | |
| required_paths.add(AUTO_30_INDEX) | |
| if rename_touches_40: | |
| required_paths.add(AUTO_40_INVENTORY) | |
| required_paths.add(AUTO_40_README) | |
| missing = sorted(p for p in required_paths if p not in changed_paths) | |
| if missing: | |
| print("ERROR: rename-triggered maintenance guard failed.") | |
| print("Detected governed renames:") | |
| for old, new in renamed_items: | |
| print(f"- {old} -> {new}") | |
| print("Required auto-maintenance updates missing from this change set:") | |
| for path in missing: | |
| print(f"- {path}") | |
| if rename_touches_30 and rename_touches_1050: | |
| print("Note: 30 <-> 10.50 coupled renames must update both peers atomically.") | |
| sys.exit(1) | |
| print("Rename-triggered maintenance guard passed.") | |
| print("Detected governed renames:") | |
| for old, new in renamed_items: | |
| print(f"- {old} -> {new}") | |
| print("Required auto-maintenance paths were updated.") | |
| PY | |
| - name: Run frontmatter and ID validation | |
| run: python thought_simulator/scripts/validate_doc_frontmatter_and_ids.py --require-frontmatter --strict-ids | |
| - name: Run relation semantics validation | |
| run: python thought_simulator/scripts/validate_relation_semantics.py | |
| - name: Run naming prefix validation | |
| run: python thought_simulator/scripts/validate_doc_naming_prefixes.py | |
| - name: Run glossary alignment warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_glossary_alignment.py | |
| - name: Run 20 glossary alignment warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_requirements_glossary_alignment.py | |
| - name: Run 20 glossary scope warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_requirements_glossary_scope.py | |
| - name: Run 50 glossary alignment warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_50_glossary_alignment.py | |
| - name: Run README link validation | |
| run: python thought_simulator/scripts/validate_readme_links.py | |
| - name: Run README coverage warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_readme_coverage.py | |
| - name: Run 30 inventory index warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_30_inventory_index.py | |
| - name: Run 30/10.50 pairing warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_30_10_50_pairing.py | |
| - name: Run 50 traceability index warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_50_traceability_index.py | |
| - name: Run identity name table warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_name_tables.py | |
| - name: Run shorthand usage warning check (non-blocking) | |
| run: python thought_simulator/scripts/validate_shorthand_usage.py | |
| - name: Run document reference validation (blocking) | |
| run: python thought_simulator/scripts/validate_doc_reference_targets.py --strict --check-headings | |
| - name: Run 20 traceability matrix validation (blocking) | |
| run: python thought_simulator/scripts/validate_20_traceability_matrix.py |