@renoxar/koolie 1.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +16 -0
- package/.gitignore +51 -0
- package/.koolie/QUELLREPOSITORIUM.md +18 -0
- package/.koolie/core/CHANGELOG.md +11832 -0
- package/.koolie/core/LICENSE +674 -0
- package/.koolie/core/LICENSE-HINWEIS.md +98 -0
- package/.koolie/core/OWNERS.md +36 -0
- package/.koolie/core/VERSION +1 -0
- package/.koolie/core/banner.py +397 -0
- package/.koolie/core/build/README.md +34 -0
- package/.koolie/core/build/assemble.py +354 -0
- package/.koolie/core/build/build-docx.py +194 -0
- package/.koolie/core/build/doc/00-kopf.md +18 -0
- package/.koolie/core/build/doc/01-executive-summary.md +24 -0
- package/.koolie/core/build/doc/02-zielbild.md +13 -0
- package/.koolie/core/build/doc/03-ziele-nichtziele.md +28 -0
- package/.koolie/core/build/doc/04-geltungsbereich.md +25 -0
- package/.koolie/core/build/doc/05-glossar.md +47 -0
- package/.koolie/core/build/doc/06-leitprinzipien.md +5 -0
- package/.koolie/core/build/doc/07-architektur.md +60 -0
- package/.koolie/core/build/doc/07a-abbildungsschicht.md +66 -0
- package/.koolie/core/build/doc/08-trennung.md +24 -0
- package/.koolie/core/build/doc/09-betriebsmodi.md +18 -0
- package/.koolie/core/build/doc/10-arbeitsablauf.md +5 -0
- package/.koolie/core/build/doc/11-datenschutz.md +5 -0
- package/.koolie/core/build/doc/12-sicherheit.md +5 -0
- package/.koolie/core/build/doc/13-risiko.md +5 -0
- package/.koolie/core/build/doc/14-rollen.md +9 -0
- package/.koolie/core/build/doc/15-referenzstruktur.md +124 -0
- package/.koolie/core/build/doc/16-agentenanweisung.md +8 -0
- package/.koolie/core/build/doc/17-overlay.md +29 -0
- package/.koolie/core/build/doc/18-skill-standard.md +5 -0
- package/.koolie/core/build/doc/19-skill-template.md +5 -0
- package/.koolie/core/build/doc/20-referenz-skills.md +70 -0
- package/.koolie/core/build/doc/21-prompts.md +53 -0
- package/.koolie/core/build/doc/22-checklisten.md +49 -0
- package/.koolie/core/build/doc/23-entscheidungsbaeume.md +29 -0
- package/.koolie/core/build/doc/24-onboarding.md +33 -0
- package/.koolie/core/build/doc/25-governance.md +35 -0
- package/.koolie/core/build/doc/26-qs-test.md +9 -0
- package/.koolie/core/build/doc/27-pilot.md +13 -0
- package/.koolie/core/build/doc/28-uebernahme.md +5 -0
- package/.koolie/core/build/doc/29-grenzen.md +87 -0
- package/.koolie/core/build/doc/30-roadmap.md +5 -0
- package/.koolie/core/build/doc/31-anhaenge.md +151 -0
- package/.koolie/core/build/doc/32-abschluss.md +92 -0
- package/.koolie/core/build/ref-a4.docx +0 -0
- package/.koolie/core/checklists/01-preflight.md +54 -0
- package/.koolie/core/checklists/02-privacy-context.md +51 -0
- package/.koolie/core/checklists/03-before-code-change.md +51 -0
- package/.koolie/core/checklists/04-review-ai-code.md +58 -0
- package/.koolie/core/checklists/05-testing.md +48 -0
- package/.koolie/core/checklists/06-security.md +50 -0
- package/.koolie/core/checklists/07-new-dependency.md +57 -0
- package/.koolie/core/checklists/08-merge-request.md +47 -0
- package/.koolie/core/checklists/09-onboarding.md +52 -0
- package/.koolie/core/checklists/10-project-adoption.md +74 -0
- package/.koolie/core/checklists/11-framework-release.md +71 -0
- package/.koolie/core/checklists/README.md +28 -0
- package/.koolie/core/clientmap.py +1358 -0
- package/.koolie/core/clients/README.md +113 -0
- package/.koolie/core/clients/_template/CLIENT_PACK.md +197 -0
- package/.koolie/core/clients/claude-code/CLIENT_PACK.md +383 -0
- package/.koolie/core/clients/claude-code/manifest.json +232 -0
- package/.koolie/core/clients/claude-code/root-template/.claude/README.md +127 -0
- package/.koolie/core/clients/cursor/CLIENT_PACK.md +229 -0
- package/.koolie/core/clients/cursor/manifest.json +330 -0
- package/.koolie/core/clients/cursor/root-template/.cursor/README.md +36 -0
- package/.koolie/core/clients/devin-desktop/CLIENT_PACK.md +251 -0
- package/.koolie/core/clients/devin-desktop/manifest.json +163 -0
- package/.koolie/core/clients/devin-desktop/root-template/.devin/README.md +79 -0
- package/.koolie/core/clients/kiro/CLIENT_PACK.md +223 -0
- package/.koolie/core/clients/kiro/manifest.json +300 -0
- package/.koolie/core/clients/kiro/root-template/.kiro/README.md +37 -0
- package/.koolie/core/clients/openai-codex/CLIENT_PACK.md +257 -0
- package/.koolie/core/clients/openai-codex/manifest.json +208 -0
- package/.koolie/core/clients/openai-codex/root-template/.codex/README.md +35 -0
- package/.koolie/core/decision-trees/01-context-allowed.md +46 -0
- package/.koolie/core/decision-trees/02-may-ai-do-task.md +47 -0
- package/.koolie/core/decision-trees/03-analyze-or-modify.md +50 -0
- package/.koolie/core/decision-trees/04-required-review.md +49 -0
- package/.koolie/core/decision-trees/05-stop-or-escalate.md +47 -0
- package/.koolie/core/decision-trees/06-rule-placement.md +58 -0
- package/.koolie/core/decision-trees/README.md +14 -0
- package/.koolie/core/docs/ADOPTION_GUIDE.md +582 -0
- package/.koolie/core/docs/DOCUMENTATION_STANDARD.md +91 -0
- package/.koolie/core/docs/PLACEHOLDER_REGISTRY.md +79 -0
- package/.koolie/core/docs/ROADMAP.md +848 -0
- package/.koolie/core/docs/RUNTIME_GLOSSARY.md +113 -0
- package/.koolie/core/examples/README.md +11 -0
- package/.koolie/core/examples/example-ergebnisbericht.md +31 -0
- package/.koolie/core/examples/example-mr-description.md +31 -0
- package/.koolie/core/examples/example-overlay-runtime.md +48 -0
- package/.koolie/core/framework/core/00-principles.md +93 -0
- package/.koolie/core/framework/core/01-governance.md +58 -0
- package/.koolie/core/framework/core/02-privacy.md +141 -0
- package/.koolie/core/framework/core/03-security.md +86 -0
- package/.koolie/core/framework/core/04-quality.md +48 -0
- package/.koolie/core/framework/core/05-working-model.md +199 -0
- package/.koolie/core/framework/core/06-prompting-rules.md +51 -0
- package/.koolie/core/framework/core/07-review-rules.md +52 -0
- package/.koolie/core/framework/core/08-skill-conventions.md +115 -0
- package/.koolie/core/framework/core/09-risk-model.md +87 -0
- package/.koolie/core/framework/core/10-error-escalation.md +53 -0
- package/.koolie/core/framework/org-policies/MAPPING_CLASSIFICATION.md +16 -0
- package/.koolie/core/framework/org-policies/README.md +29 -0
- package/.koolie/core/framework/overlay-patterns/general/documents/branching-strategy/muster-general.md +43 -0
- package/.koolie/core/framework/overlay-patterns/general/documents/coding-guidelines/muster-general.md +82 -0
- package/.koolie/core/framework/overlay-patterns/general/documents/definition-of-done/muster-general.md +52 -0
- package/.koolie/core/framework/overlay-patterns/general/documents/definition-of-ready/muster-general.md +54 -0
- package/.koolie/core/framework/overlay-patterns/general/documents/quality/muster-general.md +59 -0
- package/.koolie/core/framework/overlay-patterns/general/documents/security/muster-general.md +52 -0
- package/.koolie/core/framework/overlay-patterns/general.md +150 -0
- package/.koolie/core/framework/role-packs/README.md +63 -0
- package/.koolie/core/framework/role-packs/_template/ROLE_PACK.md +58 -0
- package/.koolie/core/framework/role-packs/requirements-engineering/ROLE_PACK.md +158 -0
- package/.koolie/core/framework/role-packs/requirements-engineering/runtime/30-role-requirements-engineering.md +88 -0
- package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/CHANGELOG.md +10 -0
- package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/EXAMPLES.md +148 -0
- package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/SKILL.md +195 -0
- package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/TESTS.md +22 -0
- package/.koolie/core/framework/role-packs/software-development/ROLE_PACK.md +95 -0
- package/.koolie/core/framework/role-packs/software-development/runtime/30-role-software-development.md +26 -0
- package/.koolie/core/framework/runtime/agents/fw-reviewer.md +34 -0
- package/.koolie/core/framework/runtime/client-settings.json +3 -0
- package/.koolie/core/framework/runtime/hooks.json +20 -0
- package/.koolie/core/framework/runtime/mcp-config.example.json +4 -0
- package/.koolie/core/framework/runtime/permissions.json +106 -0
- package/.koolie/core/framework/runtime/root-instruction-local.example.md +19 -0
- package/.koolie/core/framework/runtime/root-instruction.md +116 -0
- package/.koolie/core/framework/runtime/rules/00-framework-core.md +49 -0
- package/.koolie/core/framework/runtime/rules/10-privacy-security.md +49 -0
- package/.koolie/core/framework/runtime/rules/15-development-rules.md +41 -0
- package/.koolie/core/framework/runtime/rules/16-plan-spezifikation.md +32 -0
- package/.koolie/core/framework/runtime/rules/20-project-overlay.md +60 -0
- package/.koolie/core/framework/skills/fw-bugfix-prepare/CHANGELOG.md +14 -0
- package/.koolie/core/framework/skills/fw-bugfix-prepare/EXAMPLES.md +57 -0
- package/.koolie/core/framework/skills/fw-bugfix-prepare/SKILL.md +177 -0
- package/.koolie/core/framework/skills/fw-bugfix-prepare/TESTS.md +15 -0
- package/.koolie/core/framework/skills/fw-change-analyze/CHANGELOG.md +12 -0
- package/.koolie/core/framework/skills/fw-change-analyze/EXAMPLES.md +66 -0
- package/.koolie/core/framework/skills/fw-change-analyze/SKILL.md +167 -0
- package/.koolie/core/framework/skills/fw-change-analyze/TESTS.md +16 -0
- package/.koolie/core/framework/skills/fw-change-small/CHANGELOG.md +13 -0
- package/.koolie/core/framework/skills/fw-change-small/EXAMPLES.md +68 -0
- package/.koolie/core/framework/skills/fw-change-small/SKILL.md +175 -0
- package/.koolie/core/framework/skills/fw-change-small/TESTS.md +13 -0
- package/.koolie/core/framework/skills/fw-code-explain/CHANGELOG.md +11 -0
- package/.koolie/core/framework/skills/fw-code-explain/EXAMPLES.md +61 -0
- package/.koolie/core/framework/skills/fw-code-explain/SKILL.md +163 -0
- package/.koolie/core/framework/skills/fw-code-explain/TESTS.md +11 -0
- package/.koolie/core/framework/skills/fw-docs-update/CHANGELOG.md +10 -0
- package/.koolie/core/framework/skills/fw-docs-update/EXAMPLES.md +59 -0
- package/.koolie/core/framework/skills/fw-docs-update/SKILL.md +160 -0
- package/.koolie/core/framework/skills/fw-docs-update/TESTS.md +12 -0
- package/.koolie/core/framework/skills/fw-error-analyze/CHANGELOG.md +10 -0
- package/.koolie/core/framework/skills/fw-error-analyze/EXAMPLES.md +67 -0
- package/.koolie/core/framework/skills/fw-error-analyze/SKILL.md +160 -0
- package/.koolie/core/framework/skills/fw-error-analyze/TESTS.md +12 -0
- package/.koolie/core/framework/skills/fw-mr-description/CHANGELOG.md +12 -0
- package/.koolie/core/framework/skills/fw-mr-description/EXAMPLES.md +69 -0
- package/.koolie/core/framework/skills/fw-mr-description/SKILL.md +170 -0
- package/.koolie/core/framework/skills/fw-mr-description/TESTS.md +12 -0
- package/.koolie/core/framework/skills/fw-overlay-pflege/CHANGELOG.md +7 -0
- package/.koolie/core/framework/skills/fw-overlay-pflege/EXAMPLES.md +48 -0
- package/.koolie/core/framework/skills/fw-overlay-pflege/SKILL.md +147 -0
- package/.koolie/core/framework/skills/fw-overlay-pflege/TESTS.md +13 -0
- package/.koolie/core/framework/skills/fw-plan/CHANGELOG.md +14 -0
- package/.koolie/core/framework/skills/fw-plan/EXAMPLES.md +69 -0
- package/.koolie/core/framework/skills/fw-plan/SKILL.md +168 -0
- package/.koolie/core/framework/skills/fw-plan/TESTS.md +14 -0
- package/.koolie/core/framework/skills/fw-refactor/CHANGELOG.md +10 -0
- package/.koolie/core/framework/skills/fw-refactor/EXAMPLES.md +70 -0
- package/.koolie/core/framework/skills/fw-refactor/SKILL.md +173 -0
- package/.koolie/core/framework/skills/fw-refactor/TESTS.md +14 -0
- package/.koolie/core/framework/skills/fw-repo-analyze/CHANGELOG.md +10 -0
- package/.koolie/core/framework/skills/fw-repo-analyze/EXAMPLES.md +52 -0
- package/.koolie/core/framework/skills/fw-repo-analyze/SKILL.md +149 -0
- package/.koolie/core/framework/skills/fw-repo-analyze/TESTS.md +11 -0
- package/.koolie/core/framework/skills/fw-review-support/CHANGELOG.md +12 -0
- package/.koolie/core/framework/skills/fw-review-support/EXAMPLES.md +69 -0
- package/.koolie/core/framework/skills/fw-review-support/SKILL.md +179 -0
- package/.koolie/core/framework/skills/fw-review-support/TESTS.md +13 -0
- package/.koolie/core/framework/skills/fw-tests/CHANGELOG.md +9 -0
- package/.koolie/core/framework/skills/fw-tests/EXAMPLES.md +65 -0
- package/.koolie/core/framework/skills/fw-tests/SKILL.md +169 -0
- package/.koolie/core/framework/skills/fw-tests/TESTS.md +12 -0
- package/.koolie/core/framework/tech-packs/README.md +15 -0
- package/.koolie/core/framework/tech-packs/_template/TECH_PACK.md +61 -0
- package/.koolie/core/governance/ADOPTION_REGISTRY.md +89 -0
- package/.koolie/core/governance/CHANGE_REQUEST_TEMPLATE.md +60 -0
- package/.koolie/core/governance/DECISION_LOG.md +779 -0
- package/.koolie/core/governance/EXCEPTION_PROCESS.md +31 -0
- package/.koolie/core/governance/FEEDBACK_PROCESS.md +34 -0
- package/.koolie/core/governance/FRAMEWORK_DEV_PROFILE.md +135 -0
- package/.koolie/core/governance/INCIDENT_HANDLING.md +47 -0
- package/.koolie/core/governance/PRIORITY_HIERARCHY.md +61 -0
- package/.koolie/core/governance/RACI.md +37 -0
- package/.koolie/core/governance/RELEASE_PROCESS.md +183 -0
- package/.koolie/core/governance/change-requests/CR-2026-001-definition-release-1-0-0.md +67 -0
- package/.koolie/core/governance/change-requests/CR-2026-002-client-packs.md +63 -0
- package/.koolie/core/governance/change-requests/CR-2026-003-install-client-schalter.md +70 -0
- package/.koolie/core/governance/change-requests/CR-2026-004-client-pack-claude-code.md +82 -0
- package/.koolie/core/governance/change-requests/CR-2026-005-kern-neutralisierung.md +75 -0
- package/.koolie/core/governance/change-requests/CR-2026-006-gemeinsame-skill-quelle.md +77 -0
- package/.koolie/core/governance/change-requests/CR-2026-007-geteilte-kernbestandteile.md +80 -0
- package/.koolie/core/governance/change-requests/CR-2026-008-berechtigungen-und-hooks.md +85 -0
- package/.koolie/core/governance/change-requests/CR-2026-009-umbenennung-leitwerk.md +77 -0
- package/.koolie/core/governance/change-requests/CR-2026-010-restduplikation.md +73 -0
- package/.koolie/core/governance/change-requests/CR-2026-011-hauptdokument.md +72 -0
- package/.koolie/core/governance/change-requests/CR-2026-012-schreibschutz-kernverzeichnis.md +106 -0
- package/.koolie/core/governance/change-requests/CR-2026-013-validator-blindstellen.md +128 -0
- package/.koolie/core/governance/change-requests/CR-2026-014-kurzform-langform.md +125 -0
- package/.koolie/core/governance/change-requests/CR-2026-015-versionskette.md +150 -0
- package/.koolie/core/governance/change-requests/CR-2026-016-ap2-claude-code.md +127 -0
- package/.koolie/core/governance/change-requests/CR-2026-017-ladebedingungen-claude-code.md +173 -0
- package/.koolie/core/governance/change-requests/CR-2026-018-quellenliste-claude-code.md +121 -0
- package/.koolie/core/governance/change-requests/CR-2026-019-strukturentscheidungen-fortschreiben.md +143 -0
- package/.koolie/core/governance/change-requests/CR-2026-020-akteursbezeichnung.md +118 -0
- package/.koolie/core/governance/change-requests/CR-2026-021-hook-interpreter.md +113 -0
- package/.koolie/core/governance/change-requests/CR-2026-022-artefaktversionen.md +73 -0
- package/.koolie/core/governance/change-requests/CR-2026-023-shell-lesesperre.md +128 -0
- package/.koolie/core/governance/change-requests/CR-2026-024-clientbindungen.md +78 -0
- package/.koolie/core/governance/change-requests/CR-2026-025-betriebsmodi.md +110 -0
- package/.koolie/core/governance/change-requests/CR-2026-026-fail-closed.md +134 -0
- package/.koolie/core/governance/change-requests/CR-2026-027-zeichenlimit-einstufung.md +105 -0
- package/.koolie/core/governance/change-requests/CR-2026-028-berechtigungsmodi.md +130 -0
- package/.koolie/core/governance/change-requests/CR-2026-029-hook-ablageort.md +115 -0
- package/.koolie/core/governance/change-requests/CR-2026-030-lesende-werkzeuge.md +143 -0
- package/.koolie/core/governance/change-requests/CR-2026-031-regelquellen-ausserhalb.md +182 -0
- package/.koolie/core/governance/change-requests/CR-2026-032-fremde-skill-ablage.md +151 -0
- package/.koolie/core/governance/change-requests/CR-2026-033-modusabhaengige-durchsetzung.md +131 -0
- package/.koolie/core/governance/change-requests/CR-2026-034-nachweisbedingungen.md +116 -0
- package/.koolie/core/governance/change-requests/CR-2026-035-readme-in-der-regelablage.md +115 -0
- package/.koolie/core/governance/change-requests/CR-2026-036-ortsangaben-hook-konfiguration.md +108 -0
- package/.koolie/core/governance/change-requests/CR-2026-037-meldender-hook-clientgebunden.md +133 -0
- package/.koolie/core/governance/change-requests/CR-2026-038-importsteuerung.md +159 -0
- package/.koolie/core/governance/change-requests/CR-2026-039-normative-saetze-in-kommentaren.md +124 -0
- package/.koolie/core/governance/change-requests/CR-2026-040-erh01-ist-clientgebunden.md +115 -0
- package/.koolie/core/governance/change-requests/CR-2026-041-s5-nicht-abbildbar.md +128 -0
- package/.koolie/core/governance/change-requests/CR-2026-042-abwesenheitsnachweis-suchwerkzeug.md +102 -0
- package/.koolie/core/governance/change-requests/CR-2026-043-validator-gibt-trefferwerte-aus.md +135 -0
- package/.koolie/core/governance/change-requests/CR-2026-044-aktivierungspruefung-clientgebunden.md +112 -0
- package/.koolie/core/governance/change-requests/CR-2026-045-update-verliert-die-clientwahl.md +116 -0
- package/.koolie/core/governance/change-requests/CR-2026-046-erstinstallation-ueberschreibt-projektdatei.md +125 -0
- package/.koolie/core/governance/change-requests/CR-2026-047-zusagen-je-zugriffskanal.md +133 -0
- package/.koolie/core/governance/change-requests/CR-2026-048-modusgrenze-ohne-durchsetzung.md +137 -0
- package/.koolie/core/governance/change-requests/CR-2026-049-sondenlauf-kodierungsabhaengig.md +126 -0
- package/.koolie/core/governance/change-requests/CR-2026-050-allowed-tools-und-verworfene-permissions.md +110 -0
- package/.koolie/core/governance/change-requests/CR-2026-051-quellenkarte-und-ueberholter-stand.md +110 -0
- package/.koolie/core/governance/change-requests/CR-2026-052-drei-regelkonflikte.md +166 -0
- package/.koolie/core/governance/change-requests/CR-2026-053-lesesperre-und-entwicklungsprofil.md +144 -0
- package/.koolie/core/governance/change-requests/CR-2026-054-aktivierung-verlangt-aktivitaet.md +124 -0
- package/.koolie/core/governance/change-requests/CR-2026-055-domain-ausnahme-ohne-mechanismus.md +173 -0
- package/.koolie/core/governance/change-requests/CR-2026-056-eingabeschema-und-pfadidentitaet.md +245 -0
- package/.koolie/core/governance/change-requests/CR-2026-057-disallowed-tools-und-s3.md +148 -0
- package/.koolie/core/governance/change-requests/CR-2026-058-unteragent-reichweite.md +203 -0
- package/.koolie/core/governance/change-requests/CR-2026-059-unteragent-tiefe-und-widerspruch.md +125 -0
- package/.koolie/core/governance/change-requests/CR-2026-060-stumme-brueche.md +170 -0
- package/.koolie/core/governance/change-requests/CR-2026-061-berechtigungsdatei-ohne-pruefung.md +169 -0
- package/.koolie/core/governance/change-requests/CR-2026-062-werkzeugabbildung-des-frontmatters.md +178 -0
- package/.koolie/core/governance/change-requests/CR-2026-063-skillaufruf-ohne-freigabe.md +207 -0
- package/.koolie/core/governance/change-requests/CR-2026-064-pruefregister-nicht-nachgezaehlt.md +141 -0
- package/.koolie/core/governance/change-requests/CR-2026-065-devin-suchwerkzeuge-erhoben.md +170 -0
- package/.koolie/core/governance/change-requests/CR-2026-066-schlitzdeckung-ohne-abgleich.md +153 -0
- package/.koolie/core/governance/change-requests/CR-2026-067-hookblock-und-praeparationsregister.md +140 -0
- package/.koolie/core/governance/change-requests/CR-2026-068-sondenlauf-nebenlaeufig.md +106 -0
- package/.koolie/core/governance/change-requests/CR-2026-069-bytecode-des-kerns.md +108 -0
- package/.koolie/core/governance/change-requests/CR-2026-070-d11-zaehler.md +114 -0
- package/.koolie/core/governance/change-requests/CR-2026-071-strukturentscheidungen-bestaetigen.md +322 -0
- package/.koolie/core/governance/change-requests/CR-2026-072-modulstatus-heben.md +315 -0
- package/.koolie/core/governance/change-requests/CR-2026-073-nicht-skill-traeger-heben.md +246 -0
- package/.koolie/core/governance/change-requests/CR-2026-074-restliche-nicht-skill-traeger-heben.md +271 -0
- package/.koolie/core/governance/change-requests/CR-2026-075-ap2-zielversion-devin-desktop.md +335 -0
- package/.koolie/core/governance/change-requests/CR-2026-076-erster-sitzungstest.md +455 -0
- package/.koolie/core/governance/change-requests/CR-2026-077-sitzungstest-schranken.md +425 -0
- package/.koolie/core/governance/change-requests/CR-2026-078-planung-nach-1-0-0.md +294 -0
- package/.koolie/core/governance/change-requests/CR-2026-079-umbenennung-vorziehen.md +233 -0
- package/.koolie/core/governance/change-requests/CR-2026-080-clientbindung-des-kerns.md +321 -0
- package/.koolie/core/governance/change-requests/CR-2026-081-produktnamen-im-kern.md +297 -0
- package/.koolie/core/governance/change-requests/CR-2026-082-sitzungstest-pi-ds-2.md +145 -0
- package/.koolie/core/governance/change-requests/CR-2026-083-sitzungstest-ne-sc.md +300 -0
- package/.koolie/core/governance/change-requests/CR-2026-084-trockenlauf-gegen-den-committeten-stand.md +117 -0
- package/.koolie/core/governance/change-requests/CR-2026-085-vorbedingungen-sitzungstest-5.md +182 -0
- package/.koolie/core/governance/change-requests/CR-2026-086-grenzfaelle-gegen-die-fassungen.md +164 -0
- package/.koolie/core/governance/change-requests/CR-2026-087-produktbeobachtung-quellenliste.md +206 -0
- package/.koolie/core/governance/change-requests/CR-2026-088-vorbedingungen-testblaetter.md +127 -0
- package/.koolie/core/governance/change-requests/CR-2026-089-herrichtung-uebungsrepositorium.md +226 -0
- package/.koolie/core/governance/change-requests/CR-2026-090-vorbedingungen-sitzungstest-5-zweiter-durchgang.md +255 -0
- package/.koolie/core/governance/change-requests/CR-2026-091-sitzungstest-5.md +163 -0
- package/.koolie/core/governance/change-requests/CR-2026-092-pruefmittelwort-und-buendelschnitt.md +226 -0
- package/.koolie/core/governance/change-requests/CR-2026-093-sechzehnte-praeparation.md +151 -0
- package/.koolie/core/governance/change-requests/CR-2026-094-testblaetter-buendel-1.md +113 -0
- package/.koolie/core/governance/change-requests/CR-2026-095-pruefapparat-filter.md +65 -0
- package/.koolie/core/governance/change-requests/CR-2026-096-vorbedingungen-buendel-2.md +225 -0
- package/.koolie/core/governance/change-requests/CR-2026-097-testblaetter-buendel-2.md +162 -0
- package/.koolie/core/governance/change-requests/CR-2026-098-anforderungen-auslieferung.md +93 -0
- package/.koolie/core/governance/change-requests/CR-2026-099-k74-und-vorbedingungen-buendel-3.md +119 -0
- package/.koolie/core/governance/change-requests/CR-2026-100-testblaetter-buendel-3.md +120 -0
- package/.koolie/core/governance/change-requests/CR-2026-101-k77-eigener-posten.md +165 -0
- package/.koolie/core/governance/change-requests/CR-2026-102-k77-entschieden.md +118 -0
- package/.koolie/core/governance/change-requests/CR-2026-103-vorbedingungen-buendel-4.md +76 -0
- package/.koolie/core/governance/change-requests/CR-2026-104-herrichtung-buendel-4.md +82 -0
- package/.koolie/core/governance/change-requests/CR-2026-105-messapparat-buendel-4.md +227 -0
- package/.koolie/core/governance/change-requests/CR-2026-106-uebergabe-einchecken.md +91 -0
- package/.koolie/core/governance/change-requests/CR-2026-107-uebergabe-im-release-commit.md +111 -0
- package/.koolie/core/governance/change-requests/CR-2026-108-testblaetter-buendel-4.md +118 -0
- package/.koolie/core/governance/change-requests/CR-2026-109-berichtsweg-des-aufraeumers.md +108 -0
- package/.koolie/core/governance/change-requests/CR-2026-110-vorbedingungen-des-nachlaufs.md +184 -0
- package/.koolie/core/governance/change-requests/CR-2026-111-der-apparat-auf-dem-weg-der-wiederaufnahme.md +127 -0
- package/.koolie/core/governance/change-requests/CR-2026-112-der-arbeitsplatz-im-kern.md +103 -0
- package/.koolie/core/governance/change-requests/CR-2026-113-nachlauf-buendel-4.md +103 -0
- package/.koolie/core/governance/change-requests/CR-2026-114-vorbedingungen-buendel-5.md +317 -0
- package/.koolie/core/governance/change-requests/CR-2026-115-herrichtung-buendel-5.md +244 -0
- package/.koolie/core/governance/change-requests/CR-2026-116-messtag-buendel-5.md +178 -0
- package/.koolie/core/governance/change-requests/CR-2026-117-sammelzellen-zentraler-katalog.md +251 -0
- package/.koolie/core/governance/change-requests/CR-2026-118-quellenzuordnung-matrixzeilen.md +115 -0
- package/.koolie/core/governance/change-requests/CR-2026-119-umbenennung-koolie.md +204 -0
- package/.koolie/core/governance/change-requests/CR-2026-120-ap2-rest-devin-desktop.md +96 -0
- package/.koolie/core/governance/change-requests/CR-2026-121-verify-marker-abschaffen.md +185 -0
- package/.koolie/core/governance/change-requests/CR-2026-122-umbenennung-koolie-lauf.md +131 -0
- package/.koolie/core/governance/change-requests/CR-2026-123-vortrag-und-namensabsatz.md +170 -0
- package/.koolie/core/governance/change-requests/CR-2026-124-hauptdokument-ap11.md +237 -0
- package/.koolie/core/governance/change-requests/CR-2026-125-word-fassung-und-blinder-fleck.md +204 -0
- package/.koolie/core/governance/change-requests/CR-2026-126-lizenz-gpl3.md +112 -0
- package/.koolie/core/governance/change-requests/CR-2026-127-gegenzeichnung-rollenfrage.md +96 -0
- package/.koolie/core/governance/change-requests/CR-2026-128-freigabelauf-1.0.0.md +278 -0
- package/.koolie/core/governance/change-requests/CR-2026-129-archiv-zeilenenden.md +90 -0
- package/.koolie/core/governance/change-requests/CR-2026-130-reihenfolge-des-hebens.md +204 -0
- package/.koolie/core/governance/change-requests/CR-2026-131-chronik-und-vorlage.md +194 -0
- package/.koolie/core/governance/change-requests/CR-2026-132-erhebung-openai-codex.md +185 -0
- package/.koolie/core/governance/change-requests/CR-2026-133-bau-openai-codex.md +97 -0
- package/.koolie/core/governance/change-requests/CR-2026-134-uebergabe-lokal.md +117 -0
- package/.koolie/core/governance/change-requests/CR-2026-135-pfadlisten-nul-getrennt.md +139 -0
- package/.koolie/core/governance/change-requests/CR-2026-136-overlay-werte-einordnung.md +156 -0
- package/.koolie/core/governance/change-requests/CR-2026-137-kopierweg-kern.md +144 -0
- package/.koolie/core/governance/change-requests/CR-2026-138-overlay-muster-general.md +118 -0
- package/.koolie/core/governance/change-requests/CR-2026-139-overlay-muster-dokumente.md +105 -0
- package/.koolie/core/governance/change-requests/CR-2026-140-installer-je-zielsystem.md +120 -0
- package/.koolie/core/governance/change-requests/CR-2026-141-lieferumfang.md +123 -0
- package/.koolie/core/governance/change-requests/CR-2026-142-dokumentationsstandard.md +90 -0
- package/.koolie/core/governance/change-requests/CR-2026-143-klasse-b-core-laufzeit.md +89 -0
- package/.koolie/core/governance/change-requests/CR-2026-144-klasse-b-governance.md +90 -0
- package/.koolie/core/governance/change-requests/CR-2026-145-klasse-b-skills.md +81 -0
- package/.koolie/core/governance/change-requests/CR-2026-146-code-pack-posten.md +84 -0
- package/.koolie/core/governance/change-requests/CR-2026-147-regel-register-posten.md +78 -0
- package/.koolie/core/governance/change-requests/CR-2026-148-mehrprojekt-tokenlast.md +70 -0
- package/.koolie/core/governance/change-requests/CR-2026-149-regelablage-pfadtoken.md +71 -0
- package/.koolie/core/governance/change-requests/CR-2026-150-client-pack-kiro.md +76 -0
- package/.koolie/core/governance/change-requests/CR-2026-151-skill-anweisungen.md +71 -0
- package/.koolie/core/governance/change-requests/CR-2026-152-testblaetter-modellwechsel.md +78 -0
- package/.koolie/core/governance/change-requests/CR-2026-153-attributionszeile.md +88 -0
- package/.koolie/core/governance/change-requests/CR-2026-154-auffindbarkeit.md +102 -0
- package/.koolie/core/governance/change-requests/CR-2026-155-client-pack-cursor.md +80 -0
- package/.koolie/core/governance/change-requests/CR-2026-156-mandat-und-reibung.md +100 -0
- package/.koolie/core/governance/change-requests/CR-2026-157-mcp-anbindung.md +93 -0
- package/.koolie/core/governance/change-requests/CR-2026-158-registerpflege.md +69 -0
- package/.koolie/core/governance/change-requests/CR-2026-159-powershell.md +49 -0
- package/.koolie/core/governance/change-requests/CR-2026-160-messapparat.md +59 -0
- package/.koolie/core/governance/change-requests/CR-2026-161-pruefwerkzeuge.md +52 -0
- package/.koolie/core/governance/change-requests/CR-2026-162-schutzschicht.md +65 -0
- package/.koolie/core/governance/change-requests/CR-2026-163-pfadsemantik.md +61 -0
- package/.koolie/core/governance/change-requests/CR-2026-164-modi-ausnahmen.md +65 -0
- package/.koolie/core/governance/change-requests/CR-2026-165-installer-banner.md +406 -0
- package/.koolie/core/governance/change-requests/CR-2026-166-nachlauf-aufzeichnungen.md +59 -0
- package/.koolie/core/governance/change-requests/CR-2026-167-einsatzarchitektur.md +60 -0
- package/.koolie/core/governance/change-requests/CR-2026-168-paketquellen.md +64 -0
- package/.koolie/core/governance/change-requests/CR-2026-169-modusbindung-messfragen.md +58 -0
- package/.koolie/core/governance/change-requests/CR-2026-170-erste-veroeffentlichung.md +62 -0
- package/.koolie/core/governance/change-requests/CR-2026-171-befehl-im-projektverzeichnis.md +57 -0
- package/.koolie/core/governance/change-requests/CR-2026-172-auftritt-npm-suche.md +58 -0
- package/.koolie/core/install.py +2402 -0
- package/.koolie/core/install_dialog.py +227 -0
- package/.koolie/core/koexistenz.py +112 -0
- package/.koolie/core/mandat.py +605 -0
- package/.koolie/core/onboarding/COMPLETION_CRITERIA.md +37 -0
- package/.koolie/core/onboarding/GUIDE.md +103 -0
- package/.koolie/core/onboarding/KNOWLEDGE_CHECK.md +48 -0
- package/.koolie/core/onboarding/MENTOR_CHECKLIST.md +40 -0
- package/.koolie/core/onboarding/QUICKSTART.md +50 -0
- package/.koolie/core/onboarding/REFERENCE.md +69 -0
- package/.koolie/core/onboarding/exercises/EXERCISES.md +78 -0
- package/.koolie/core/onboarding/exercises/README.md +120 -0
- package/.koolie/core/pilot/METRICS.md +59 -0
- package/.koolie/core/pilot/PILOT_CONCEPT.md +42 -0
- package/.koolie/core/prompts/01-understand-codebase.md +99 -0
- package/.koolie/core/prompts/02-impact-analysis.md +104 -0
- package/.koolie/core/prompts/03-implementation-planning.md +102 -0
- package/.koolie/core/prompts/04-code-generation.md +100 -0
- package/.koolie/core/prompts/05-test-generation.md +103 -0
- package/.koolie/core/prompts/06-refactoring.md +102 -0
- package/.koolie/core/prompts/07-debugging.md +97 -0
- package/.koolie/core/prompts/08-security-review.md +92 -0
- package/.koolie/core/prompts/09-performance-analysis.md +89 -0
- package/.koolie/core/prompts/10-documentation.md +91 -0
- package/.koolie/core/prompts/11-merge-request-review.md +94 -0
- package/.koolie/core/prompts/12-developer-training.md +90 -0
- package/.koolie/core/prompts/README.md +88 -0
- package/.koolie/core/templates/MR_AI_DISCLOSURE.md +37 -0
- package/.koolie/core/templates/PLAN_TEMPLATE.md +57 -0
- package/.koolie/core/templates/SKILL_TEMPLATE.md +159 -0
- package/.koolie/core/templates/project-overlay/OVERLAY.md +315 -0
- package/.koolie/core/templates/project-overlay/documents/README.md +43 -0
- package/.koolie/core/templates/project-overlay/documents/ai-governance/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/ai-process-model/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/architecture/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/architecture/decisions/README.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/branching-strategy/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/coding-guidelines/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/definition-of-done/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/definition-of-ready/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/deployment/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/glossary/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/quality/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/roadmap/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/roles/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/documents/security/.gitkeep.md +3 -0
- package/.koolie/core/templates/project-overlay/exceptions/EXCEPTIONS.md +9 -0
- package/.koolie/core/templates/project-overlay/forbidden-terms.txt +8 -0
- package/.koolie/core/templates/project-overlay/overlay-manifest.yaml +73 -0
- package/.koolie/core/templates/rules/21-overlay-TEMPLATE.md.template +28 -0
- package/.koolie/core/templates/rules/40-tech-TEMPLATE.md.template +33 -0
- package/.koolie/core/tests/EDGE_CASES.md +67 -0
- package/.koolie/core/tests/TEST_CATALOG.md +170 -0
- package/.koolie/core/tests/erhebungen/README.md +326 -0
- package/.koolie/core/tests/erhebungen/ablage.py +357 -0
- package/.koolie/core/tests/erhebungen/apparat/__init__.py +22 -0
- package/.koolie/core/tests/erhebungen/apparat/baum.py +214 -0
- package/.koolie/core/tests/erhebungen/apparat/belege.py +91 -0
- package/.koolie/core/tests/erhebungen/apparat/clients.py +321 -0
- package/.koolie/core/tests/erhebungen/apparat/freigabe.py +74 -0
- package/.koolie/core/tests/erhebungen/apparat/kontingent.py +64 -0
- package/.koolie/core/tests/erhebungen/apparat/laeufer.py +155 -0
- package/.koolie/core/tests/erhebungen/apparat/reihe.py +202 -0
- package/.koolie/core/tests/erhebungen/apparat/selbsttest.py +280 -0
- package/.koolie/core/tests/erhebungen/apparat/stand.py +30 -0
- package/.koolie/core/tests/erhebungen/apparat/vorpruefung.py +70 -0
- package/.koolie/core/tests/erhebungen/auswerten-b4.py +468 -0
- package/.koolie/core/tests/erhebungen/auswerten-b5.py +517 -0
- package/.koolie/core/tests/erhebungen/auswerten-dd.py +172 -0
- package/.koolie/core/tests/erhebungen/baeume-b4.py +334 -0
- package/.koolie/core/tests/erhebungen/baeume-b5.py +339 -0
- package/.koolie/core/tests/erhebungen/baeume_loeschen.py +138 -0
- package/.koolie/core/tests/erhebungen/cc-overlay-fuellen.py +277 -0
- package/.koolie/core/tests/erhebungen/dossier-b4.py +178 -0
- package/.koolie/core/tests/erhebungen/dossier-b5.py +202 -0
- package/.koolie/core/tests/erhebungen/historie-bauen-b4.py +642 -0
- package/.koolie/core/tests/erhebungen/k-bauen-b3.py +841 -0
- package/.koolie/core/tests/erhebungen/lauf-dd.py +146 -0
- package/.koolie/core/tests/erhebungen/lauf.py +114 -0
- package/.koolie/core/tests/erhebungen/mcp-waechter.py +278 -0
- package/.koolie/core/tests/erhebungen/messbaum-schnitt.py +256 -0
- package/.koolie/core/tests/erhebungen/messen.py +72 -0
- package/.koolie/core/tests/erhebungen/node-waechter.py +74 -0
- package/.koolie/core/tests/erhebungen/packaktivierung.py +403 -0
- package/.koolie/core/tests/erhebungen/prompts-schreiben-b4.py +210 -0
- package/.koolie/core/tests/erhebungen/prompts-schreiben-b5.py +251 -0
- package/.koolie/core/tests/erhebungen/reihe-b4.py +171 -0
- package/.koolie/core/tests/erhebungen/reihe-b5.py +172 -0
- package/.koolie/core/tests/erhebungen/stand-b4.py +135 -0
- package/.koolie/core/tests/erhebungen/stand-b5.py +137 -0
- package/.koolie/core/tests/erhebungen/trust-b4.py +56 -0
- package/.koolie/core/tests/erhebungen/trust-b5.py +56 -0
- package/.koolie/core/tests/erhebungen/turn2-schreiben-b4.py +105 -0
- package/.koolie/core/tests/erhebungen/umgebungen-bauen-b4.py +377 -0
- package/.koolie/core/tests/erhebungen/umgebungen-bauen-b5.py +363 -0
- package/.koolie/core/tests/erhebungen/zaehlen46.py +74 -0
- package/.koolie/core/tests/erhebungen/zustand-b4.py +82 -0
- package/.koolie/core/tests/erhebungen/zustand-b5.py +82 -0
- package/.koolie/core/tests/protocols/2026-09-10-AP2-claude-code-wirkungsnachweise.md +194 -0
- package/.koolie/core/tests/protocols/2026-09-10-AP2-claude-code.md +468 -0
- package/.koolie/core/tests/protocols/2026-09-10-CR-2026-020-akteursbezeichnung.md +99 -0
- package/.koolie/core/tests/protocols/2026-09-10-CR-2026-021-hook-interpreter.md +138 -0
- package/.koolie/core/tests/protocols/2026-09-10-CR-2026-022-artefaktversionen.md +87 -0
- package/.koolie/core/tests/protocols/2026-09-10-CR-2026-023-shell-lesesperre.md +135 -0
- package/.koolie/core/tests/protocols/2026-09-10-CR-2026-024-clientbindungen.md +98 -0
- package/.koolie/core/tests/protocols/2026-09-10-FW-DS-03.md +90 -0
- package/.koolie/core/tests/protocols/2026-09-10-FW-KO-01.md +105 -0
- package/.koolie/core/tests/protocols/2026-09-10-FW-KO-02.md +123 -0
- package/.koolie/core/tests/protocols/2026-09-10-FW-KO-04.md +73 -0
- package/.koolie/core/tests/protocols/2026-09-10-FW-RE-02.md +99 -0
- package/.koolie/core/tests/protocols/2026-09-10-FW-VN-01-wiederholung.md +108 -0
- package/.koolie/core/tests/protocols/2026-09-10-FW-VN-01.md +249 -0
- package/.koolie/core/tests/protocols/2026-09-10-FW-ZA-05.md +99 -0
- package/.koolie/core/tests/protocols/2026-09-11-AP2-devin-desktop.md +257 -0
- package/.koolie/core/tests/protocols/2026-09-11-CR-2026-026-fail-closed.md +113 -0
- package/.koolie/core/tests/protocols/2026-09-11-erhebungen-K21-K26.md +243 -0
- package/.koolie/core/tests/protocols/2026-09-11-wirkungsnachweise-0.26.0.md +101 -0
- package/.koolie/core/tests/protocols/2026-09-12-B01-allowed-tools.md +152 -0
- package/.koolie/core/tests/protocols/2026-09-12-B04-B05-gegenpruefung.md +204 -0
- package/.koolie/core/tests/protocols/2026-09-12-erhebungen-K28-S5-B9-bypass.md +268 -0
- package/.koolie/core/tests/protocols/2026-09-12-mehrprojekt-arbeitsbereich.md +154 -0
- package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.26.1.md +126 -0
- package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.27.0.md +114 -0
- package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.28.0.md +129 -0
- package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.29.0.md +121 -0
- package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.30.0.md +112 -0
- package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.31.0.md +107 -0
- package/.koolie/core/tests/protocols/2026-09-13-B06-gegenpruefung.md +370 -0
- package/.koolie/core/tests/protocols/2026-09-13-B07-B09-gegenpruefung.md +211 -0
- package/.koolie/core/tests/protocols/2026-09-13-B08-B11-gegenpruefung.md +179 -0
- package/.koolie/core/tests/protocols/2026-09-13-erhebung-disallowed-tools.md +147 -0
- package/.koolie/core/tests/protocols/2026-09-13-erhebung-unteragent-tiefe.md +139 -0
- package/.koolie/core/tests/protocols/2026-09-13-erhebung-unteragent.md +214 -0
- package/.koolie/core/tests/protocols/2026-09-13-gegenpruefung-berechtigungsdatei.md +253 -0
- package/.koolie/core/tests/protocols/2026-09-13-gegenpruefung-stumme-brueche.md +202 -0
- package/.koolie/core/tests/protocols/2026-09-13-gegenpruefung-werkzeugabbildung.md +219 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.32.0.md +133 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.33.0.md +169 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.34.0.md +187 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.35.0.md +187 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.36.0.md +137 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.37.0.md +112 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.38.0.md +154 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.39.0.md +188 -0
- package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.40.0.md +214 -0
- package/.koolie/core/tests/protocols/2026-09-14-erhebung-devin-werkzeuge.md +267 -0
- package/.koolie/core/tests/protocols/2026-09-14-erhebung-skillaufruf.md +238 -0
- package/.koolie/core/tests/protocols/2026-09-14-gegenpruefung-pruefregister.md +156 -0
- package/.koolie/core/tests/protocols/2026-09-14-gegenpruefung-schlitzdeckung.md +206 -0
- package/.koolie/core/tests/protocols/2026-09-14-gegenpruefung-skillwahl.md +127 -0
- package/.koolie/core/tests/protocols/2026-09-14-migrationslauf-pilot.md +134 -0
- package/.koolie/core/tests/protocols/2026-09-14-wirkungsnachweise-0.41.0.md +175 -0
- package/.koolie/core/tests/protocols/2026-09-14-wirkungsnachweise-0.42.0.md +180 -0
- package/.koolie/core/tests/protocols/2026-09-14-wirkungsnachweise-0.43.0.md +165 -0
- package/.koolie/core/tests/protocols/2026-09-14-wirkungsnachweise-0.44.0.md +130 -0
- package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-d11-zaehlregeln.md +311 -0
- package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-modulstatus.md +524 -0
- package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-nicht-skill-traeger.md +225 -0
- package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-restliche-nicht-skill-traeger.md +345 -0
- package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-strukturentscheidungen.md +392 -0
- package/.koolie/core/tests/protocols/2026-09-15-herrichtung-uebungsrepositorium.md +213 -0
- package/.koolie/core/tests/protocols/2026-09-15-migrationslauf-pilot-0.46.0.md +143 -0
- package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.45.0.md +127 -0
- package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.46.0.md +193 -0
- package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.47.0.md +149 -0
- package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.49.0.md +202 -0
- package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.50.0.md +183 -0
- package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.51.0.md +202 -0
- package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.52.0.md +168 -0
- package/.koolie/core/tests/protocols/2026-09-16-AP2-zielversion-devin-desktop.md +231 -0
- package/.koolie/core/tests/protocols/2026-09-16-wirkungsnachweise-0.53.0.md +350 -0
- package/.koolie/core/tests/protocols/2026-09-17-nachtrag-migrationshinweis-0.54.1.md +121 -0
- package/.koolie/core/tests/protocols/2026-09-17-sitzungstest-pi-ds.md +523 -0
- package/.koolie/core/tests/protocols/2026-09-17-sitzungstest-schranken.md +433 -0
- package/.koolie/core/tests/protocols/2026-09-17-wirkungsnachweise-0.54.0.md +159 -0
- package/.koolie/core/tests/protocols/2026-09-18-FW-AK-01.md +442 -0
- package/.koolie/core/tests/protocols/2026-09-18-FW-KO-05.md +231 -0
- package/.koolie/core/tests/protocols/2026-09-18-herrichtung-uebungsrepositorium.md +273 -0
- package/.koolie/core/tests/protocols/2026-09-18-nachtrag-preis-umbenennung-0.56.1.md +102 -0
- package/.koolie/core/tests/protocols/2026-09-18-sitzungstest-5.md +349 -0
- package/.koolie/core/tests/protocols/2026-09-18-sitzungstest-ne-sc.md +430 -0
- package/.koolie/core/tests/protocols/2026-09-18-sitzungstest-pi-ds-2.md +499 -0
- package/.koolie/core/tests/protocols/2026-09-18-vorbedingungen-sitzungstest-5-zweiter-durchgang.md +170 -0
- package/.koolie/core/tests/protocols/2026-09-18-vorbedingungen-testblaetter.md +184 -0
- package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.55.0.md +202 -0
- package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.56.0.md +135 -0
- package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.56.2.md +154 -0
- package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.57.0.md +228 -0
- package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.57.1.md +262 -0
- package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.58.0.md +135 -0
- package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.59.0.md +150 -0
- package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.60.0.md +340 -0
- package/.koolie/core/tests/protocols/2026-09-19-herrichtung-buendel-4.md +235 -0
- package/.koolie/core/tests/protocols/2026-09-19-k77-zurechenbarkeit.md +236 -0
- package/.koolie/core/tests/protocols/2026-09-19-pruefapparat-filter.md +50 -0
- package/.koolie/core/tests/protocols/2026-09-19-pruefmittelwort-und-buendelschnitt.md +239 -0
- package/.koolie/core/tests/protocols/2026-09-19-sechzehnte-praeparation.md +135 -0
- package/.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-1.md +250 -0
- package/.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-2.md +229 -0
- package/.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md +293 -0
- package/.koolie/core/tests/protocols/2026-09-19-vorbedingungen-buendel-2.md +236 -0
- package/.koolie/core/tests/protocols/2026-09-19-vorbedingungen-buendel-3.md +253 -0
- package/.koolie/core/tests/protocols/2026-09-19-vorbedingungen-buendel-4.md +138 -0
- package/.koolie/core/tests/protocols/2026-09-20-messapparat-buendel-4.md +433 -0
- package/.koolie/core/tests/protocols/2026-09-20-testblaetter-buendel-4.md +321 -0
- package/.koolie/core/tests/protocols/2026-09-20-uebergabe-im-release-commit.md +146 -0
- package/.koolie/core/tests/protocols/2026-09-20-vorbedingungen-nachlauf-b4.md +259 -0
- package/.koolie/core/tests/protocols/2026-09-21-arbeitsplatz-im-kern.md +127 -0
- package/.koolie/core/tests/protocols/2026-09-21-nachlauf-buendel-4.md +157 -0
- package/.koolie/core/tests/protocols/2026-09-21-vorbedingungen-buendel-5.md +247 -0
- package/.koolie/core/tests/protocols/2026-09-21-wiederaufnahme-nachlauf-b4.md +190 -0
- package/.koolie/core/tests/protocols/2026-09-22-ap2-rest-devin-desktop.md +614 -0
- package/.koolie/core/tests/protocols/2026-09-22-hauptdokument-ap11.md +443 -0
- package/.koolie/core/tests/protocols/2026-09-22-herrichtung-buendel-5.md +224 -0
- package/.koolie/core/tests/protocols/2026-09-22-messtag-buendel-5.md +327 -0
- package/.koolie/core/tests/protocols/2026-09-22-quellenzuordnung-matrixzeilen.md +230 -0
- package/.koolie/core/tests/protocols/2026-09-22-sammelzellen-zentraler-katalog.md +354 -0
- package/.koolie/core/tests/protocols/2026-09-22-umbenennung-koolie.md +296 -0
- package/.koolie/core/tests/protocols/2026-09-22-verify-marker-abschaffen.md +283 -0
- package/.koolie/core/tests/protocols/2026-09-22-vortrag-und-name.md +261 -0
- package/.koolie/core/tests/protocols/2026-09-22-wirkungsnachweise-0.86.0.md +158 -0
- package/.koolie/core/tests/protocols/2026-09-23-archiv-zeilenenden.md +113 -0
- package/.koolie/core/tests/protocols/2026-09-23-bau-openai-codex.md +168 -0
- package/.koolie/core/tests/protocols/2026-09-23-chronik-und-vorlage.md +224 -0
- package/.koolie/core/tests/protocols/2026-09-23-erhebung-openai-codex.md +309 -0
- package/.koolie/core/tests/protocols/2026-09-23-freigabelauf-1.0.0-vorbereitung.md +119 -0
- package/.koolie/core/tests/protocols/2026-09-23-freigabelauf-1.0.0.md +150 -0
- package/.koolie/core/tests/protocols/2026-09-23-gegenzeichnung-rollenfrage.md +198 -0
- package/.koolie/core/tests/protocols/2026-09-23-reihenfolge-des-hebens.md +220 -0
- package/.koolie/core/tests/protocols/2026-09-23-word-fassung-und-blinder-fleck.md +307 -0
- package/.koolie/core/tests/protocols/2026-09-24-kopierweg-kern.md +98 -0
- package/.koolie/core/tests/protocols/2026-09-24-overlay-werte-einordnung.md +111 -0
- package/.koolie/core/tests/protocols/2026-09-24-pfadlisten-nul-getrennt.md +128 -0
- package/.koolie/core/tests/protocols/2026-09-24-uebergabe-lokal.md +85 -0
- package/.koolie/core/tests/protocols/2026-09-25-code-pack-posten.md +86 -0
- package/.koolie/core/tests/protocols/2026-09-25-dokumentationsstandard.md +101 -0
- package/.koolie/core/tests/protocols/2026-09-25-installer-je-zielsystem.md +134 -0
- package/.koolie/core/tests/protocols/2026-09-25-klasse-b-core-laufzeit.md +126 -0
- package/.koolie/core/tests/protocols/2026-09-25-klasse-b-governance.md +133 -0
- package/.koolie/core/tests/protocols/2026-09-25-klasse-b-skills.md +91 -0
- package/.koolie/core/tests/protocols/2026-09-25-lieferumfang.md +76 -0
- package/.koolie/core/tests/protocols/2026-09-25-overlay-muster-dokumente.md +107 -0
- package/.koolie/core/tests/protocols/2026-09-25-overlay-muster-general.md +100 -0
- package/.koolie/core/tests/protocols/2026-09-25-regel-register-posten.md +87 -0
- package/.koolie/core/tests/protocols/2026-09-26-attributionszeile.md +83 -0
- package/.koolie/core/tests/protocols/2026-09-26-auffindbarkeit.md +85 -0
- package/.koolie/core/tests/protocols/2026-09-26-bau-cursor.md +68 -0
- package/.koolie/core/tests/protocols/2026-09-26-bau-kiro.md +75 -0
- package/.koolie/core/tests/protocols/2026-09-26-mehrprojekt-tokenlast.md +174 -0
- package/.koolie/core/tests/protocols/2026-09-26-regelablage-pfadtoken.md +133 -0
- package/.koolie/core/tests/protocols/2026-09-26-skill-anweisungen.md +111 -0
- package/.koolie/core/tests/protocols/2026-09-26-testblaetter-modellwechsel.md +106 -0
- package/.koolie/core/tests/protocols/2026-09-27-mandat-und-reibung.md +58 -0
- package/.koolie/core/tests/protocols/2026-09-28-mcp-anbindung.md +72 -0
- package/.koolie/core/tests/protocols/2026-09-29-messapparat.md +75 -0
- package/.koolie/core/tests/protocols/2026-09-29-powershell.md +58 -0
- package/.koolie/core/tests/protocols/2026-09-29-pruefwerkzeuge.md +64 -0
- package/.koolie/core/tests/protocols/2026-09-29-registerpflege.md +228 -0
- package/.koolie/core/tests/protocols/2026-09-29-schutzschicht.md +95 -0
- package/.koolie/core/tests/protocols/2026-09-30-einsatzarchitektur.md +104 -0
- package/.koolie/core/tests/protocols/2026-09-30-modi-ausnahmen.md +77 -0
- package/.koolie/core/tests/protocols/2026-09-30-nachlauf-banner.md +85 -0
- package/.koolie/core/tests/protocols/2026-09-30-paketquellen.md +65 -0
- package/.koolie/core/tests/protocols/2026-09-30-pfadsemantik.md +79 -0
- package/.koolie/core/tests/protocols/2026-10-01-auftritt-und-suche.md +58 -0
- package/.koolie/core/tests/protocols/2026-10-01-befehl-im-projektverzeichnis.md +47 -0
- package/.koolie/core/tests/protocols/2026-10-01-erste-veroeffentlichung.md +60 -0
- package/.koolie/core/tests/protocols/2026-10-01-modusbindung-messfragen.md +107 -0
- package/.koolie/core/tests/protocols/README.md +14 -0
- package/.koolie/core/tests/scripts/hook-check-secrets.py +1307 -0
- package/.koolie/core/tests/scripts/hook-overlay-status.py +120 -0
- package/.koolie/core/tests/scripts/mermaid_renderer.py +67 -0
- package/.koolie/core/tests/scripts/overlay_status.py +130 -0
- package/.koolie/core/tests/scripts/probe-pruefungen.py +110 -0
- package/.koolie/core/tests/scripts/pruefungen/__init__.py +4 -0
- package/.koolie/core/tests/scripts/pruefungen/berechtigungen.py +1559 -0
- package/.koolie/core/tests/scripts/pruefungen/bestand.py +1433 -0
- package/.koolie/core/tests/scripts/pruefungen/dokumente.py +1262 -0
- package/.koolie/core/tests/scripts/pruefungen/gemeinsam.py +784 -0
- package/.koolie/core/tests/scripts/pruefungen/hooks.py +1188 -0
- package/.koolie/core/tests/scripts/pruefungen/overlay.py +1251 -0
- package/.koolie/core/tests/scripts/pruefungen/packs.py +1314 -0
- package/.koolie/core/tests/scripts/pruefungen/register.py +950 -0
- package/.koolie/core/tests/scripts/pruefungen/testkatalog.py +1202 -0
- package/.koolie/core/tests/scripts/pruefungen/werkzeuge.py +957 -0
- package/.koolie/core/tests/scripts/sonden/__init__.py +4 -0
- package/.koolie/core/tests/scripts/sonden/apparat.py +653 -0
- package/.koolie/core/tests/scripts/sonden/teil01_grundbestand_und_installation.py +999 -0
- package/.koolie/core/tests/scripts/sonden/teil02_packs_mandat_mcp.py +942 -0
- package/.koolie/core/tests/scripts/sonden/teil03_pruefungen_26_bis_36.py +1184 -0
- package/.koolie/core/tests/scripts/sonden/teil04_pruefungen_37_bis_45.py +1491 -0
- package/.koolie/core/tests/scripts/sonden/teil05_pruefungen_46_bis_55.py +1447 -0
- package/.koolie/core/tests/scripts/sonden/teil06_pruefungen_57_bis_65.py +739 -0
- package/.koolie/core/tests/scripts/sonden/teil07_overlay_und_lieferung.py +1014 -0
- package/.koolie/core/tests/scripts/sonden/teil08_pruefungen_66_bis_80.py +1325 -0
- package/.koolie/core/tests/scripts/sonden/teil09_pruefmittel_81_und_82.py +505 -0
- package/.koolie/core/tests/scripts/sonden/teil10_pruefungen_83_bis_95.py +1218 -0
- package/.koolie/core/tests/scripts/sonden/teil11_pruefungen_104_und_105.py +149 -0
- package/.koolie/core/tests/scripts/sonden/teil12_pruefungen_106_und_107.py +136 -0
- package/.koolie/core/tests/scripts/sonden/teil13_pfad_und_mustersemantik.py +150 -0
- package/.koolie/core/tests/scripts/sonden/teil14_modi_ausnahmen_skills.py +204 -0
- package/.koolie/core/tests/scripts/sonden/teil15_banner_und_nachlauf.py +193 -0
- package/.koolie/core/tests/scripts/sonden/teil16_koexistenz.py +114 -0
- package/.koolie/core/tests/scripts/sonden/teil17_paketquellen.py +115 -0
- package/.koolie/core/tests/scripts/sonden/teil18_modusbindung_m3_m5.py +113 -0
- package/.koolie/core/tests/scripts/validate-framework.py +1104 -0
- package/.koolie/core/tests/scripts/validate-output.py +296 -0
- package/.koolie/core/wirksamkeit.py +430 -0
- package/CONTRIBUTING.md +119 -0
- package/LICENSE +674 -0
- package/QUICKSTART.en.md +135 -0
- package/QUICKSTART.md +129 -0
- package/README.en.md +108 -0
- package/README.md +107 -0
- package/install.cmd +44 -0
- package/install.command +46 -0
- package/package.json +21 -0
- package/paketquellen/README.md +41 -0
- package/paketquellen/bauen.py +411 -0
- package/paketquellen/koolie.cmd +23 -0
- package/paketquellen/koolie_befehl.py +82 -0
- package/paketquellen/npm/koolie.js +26 -0
|
@@ -0,0 +1,950 @@
|
|
|
1
|
+
"""Die Register der Governance: Decision-Log-Zellen, Pruefregister, 1.0.0-Stand,
|
|
2
|
+
Statusvokabular, Klaerungsregister und seine Form, Releaseplan, Decision-Register und
|
|
3
|
+
Roadmapstand.
|
|
4
|
+
|
|
5
|
+
Pruefungen 36, 40, 46, 47, 50, 53, 58, 91 und 102. Teil des Validators validate-
|
|
6
|
+
framework.py, seit 1.19.1 nach Gegenstand in Module geteilt (K-174). Das Register aller
|
|
7
|
+
Pruefungen steht im Kopfkommentar des Einstiegs, die Grenze jeder einzelnen in ihrem
|
|
8
|
+
Kopfkommentar hier."""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import re
|
|
13
|
+
|
|
14
|
+
from .gemeinsam import (
|
|
15
|
+
DOK_WURZEL, err, ist_quellrepositorium, iter_text_files, KERN, paketquelltext, read,
|
|
16
|
+
REGISTER_ANKER, REGISTER_ENDE, SKILL_STATUS, tabellenzellen)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Pruefung 36: Jede Tabellenzeile des Decision Logs fuehrt so viele Zellen wie der
|
|
20
|
+
# Kopf ihrer Tabelle (CR-2026-060 E4, D-75).
|
|
21
|
+
#
|
|
22
|
+
# Anlass: Vier zerrissene Zeilen in 0.34.0 - D-61 bis D-63 mit fuenf Zellen statt sechs,
|
|
23
|
+
# D-29 mit acht, dort teilte ein unmaskierter Strich in einem Codespan die Zeile. In der
|
|
24
|
+
# gerenderten Tabelle stand die Herkunft unter "Begruendung", das Datum unter
|
|
25
|
+
# "Alternativen", die Rolle unter "Status". D-29 stand so seit 0.10.x. Gefunden hat die
|
|
26
|
+
# Zeilen jedes Mal ein Mensch beim Eintragen einer anderen.
|
|
27
|
+
#
|
|
28
|
+
# WAS SIE HEUTE FAENGT: nichts. Alle Zeilen sind seit 0.35.0 in Ordnung, von Hand
|
|
29
|
+
# berichtigt. Das ist eine VERANKERUNG, keine Behebung - wie Pruefung 35 und der fuenfte
|
|
30
|
+
# Gegenstand der Pruefung 32. Der Unterschied: Ihr Gegenbeweis ist ein Abzaehlen und
|
|
31
|
+
# keine Konstruktion. Gegen 0.34.0 meldet sie vier Fundstellen, gegen 0.32.0 und 0.33.0
|
|
32
|
+
# je eine.
|
|
33
|
+
#
|
|
34
|
+
# WAS SIE NICHT LEISTET: Sie prueft die Anzahl, nicht den Inhalt. Eine Zeile, in der
|
|
35
|
+
# Begruendung und Alternativen vertauscht sind, besteht sie - dieselbe Grenze, die
|
|
36
|
+
# Pruefung 31 fuer ihre Arithmetik benennt. Und sie prueft nur diese eine Datei: Die
|
|
37
|
+
# uebrigen Tabellen des Repositoriums haben ihre eigenen Pruefungen (30, 31) oder keine.
|
|
38
|
+
DECISION_LOG_DATEI = KERN + "/governance/DECISION_LOG.md"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def check_decision_log_zellen(root: str) -> None:
|
|
42
|
+
"""Pruefung 36 (D-75): Die Tabellen des Decision Logs sind nicht zerrissen."""
|
|
43
|
+
pfad = os.path.join(root, DECISION_LOG_DATEI.replace("/", os.sep))
|
|
44
|
+
if not os.path.isfile(pfad):
|
|
45
|
+
err(f"{DECISION_LOG_DATEI}: fehlt. Ohne das Decision Log ist keine Entscheidung "
|
|
46
|
+
f"dieses Frameworks belegt")
|
|
47
|
+
return
|
|
48
|
+
zeilen = read(pfad).replace("\r\n", "\n").split("\n")
|
|
49
|
+
soll = None
|
|
50
|
+
ueberschrift = "(vor der ersten Ueberschrift)"
|
|
51
|
+
kopfzeile = 0
|
|
52
|
+
gesehen = 0
|
|
53
|
+
for nr, zeile in enumerate(zeilen, 1):
|
|
54
|
+
z = zeile.strip()
|
|
55
|
+
if z.startswith("## "):
|
|
56
|
+
ueberschrift = z[3:].strip()
|
|
57
|
+
soll = None
|
|
58
|
+
continue
|
|
59
|
+
if not z.startswith("|"):
|
|
60
|
+
# Eine Leerzeile beendet die Tabelle; Fliesstext zwischen zwei Tabellen
|
|
61
|
+
# darf die Zellenzahl nicht von der einen auf die andere uebertragen.
|
|
62
|
+
if not z:
|
|
63
|
+
soll = None
|
|
64
|
+
continue
|
|
65
|
+
zellen = tabellenzellen(z)
|
|
66
|
+
if soll is None:
|
|
67
|
+
soll = len(zellen)
|
|
68
|
+
kopfzeile = nr
|
|
69
|
+
gesehen += 1
|
|
70
|
+
continue
|
|
71
|
+
if len(zellen) != soll:
|
|
72
|
+
err(f"{DECISION_LOG_DATEI}:{nr}: Die Zeile fuehrt {len(zellen)} Zellen, der "
|
|
73
|
+
f"Kopf ihrer Tabelle ({ueberschrift}, Zeile {kopfzeile}) fuehrt {soll}. "
|
|
74
|
+
f"Eine zerrissene Zeile rendert die Werte unter den falschen Spalten; "
|
|
75
|
+
f"ein Strich innerhalb einer Zelle gehoert maskiert (\\|)")
|
|
76
|
+
if not gesehen:
|
|
77
|
+
err(f"{DECISION_LOG_DATEI}: keine Tabellenzeile gefunden. Der Anker dieser "
|
|
78
|
+
f"Pruefung ist die Zeilenform '| ... |'; ohne sie prueft sie nichts und "
|
|
79
|
+
f"bestuende leise (D-23)")
|
|
80
|
+
NACHWEIS_SATZ = "Der Wirksamkeitsnachweis nach D-23 fuer die Pruefungen {} laeuft"
|
|
81
|
+
SONDEN_SATZ = "Wirkungsnachweis nach D-23 fuer die Pruefungen {}"
|
|
82
|
+
KATALOG_SPANNE = "für die Prüfungen {} als Skript"
|
|
83
|
+
KATALOG_GRENZFAELLE = "Die {} Grenzfälle einzeln"
|
|
84
|
+
REGISTER_DATEIEN = ("tests/scripts/validate-framework.py",
|
|
85
|
+
"tests/scripts/probe-pruefungen.py",
|
|
86
|
+
"tests/TEST_CATALOG.md",
|
|
87
|
+
"tests/EDGE_CASES.md")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def nummernspanne(zahlen) -> str:
|
|
91
|
+
"""Kanonische Schreibweise einer Nummernmenge: '6 und 18 bis 40'.
|
|
92
|
+
|
|
93
|
+
Eine einzelne Nummer steht allein, eine luckenlose Folge als 'a bis b', mehrere
|
|
94
|
+
Bloecke durch Komma und ein abschliessendes 'und' getrennt. Diese Funktion ist die
|
|
95
|
+
einzige Quelle der Schreibweise; die drei Traeger vergleichen woertlich gegen sie.
|
|
96
|
+
"""
|
|
97
|
+
folge = sorted(zahlen)
|
|
98
|
+
bloecke, lauf = [], [folge[0]]
|
|
99
|
+
for z in folge[1:]:
|
|
100
|
+
if z == lauf[-1] + 1:
|
|
101
|
+
lauf.append(z)
|
|
102
|
+
else:
|
|
103
|
+
bloecke.append(lauf)
|
|
104
|
+
lauf = [z]
|
|
105
|
+
bloecke.append(lauf)
|
|
106
|
+
teile = [str(b[0]) if len(b) == 1 else f"{b[0]} bis {b[-1]}" for b in bloecke]
|
|
107
|
+
if len(teile) == 1:
|
|
108
|
+
return teile[0]
|
|
109
|
+
return ", ".join(teile[:-1]) + " und " + teile[-1]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def genannte_pruefungen(*texte: str) -> set:
|
|
113
|
+
"""Jede Pruefungsnummer, die ein Text als 'Pruefung N' oder 'Pruefungen N bis M' nennt.
|
|
114
|
+
|
|
115
|
+
Der Zuschnitt ist Absicht (CR-2026-064 E2): Ein Querverweis auf eine kleinere Nummer
|
|
116
|
+
stoert nicht, weil nur die hoechste zaehlt - und eine neue Pruefung nennt ihre Nummer
|
|
117
|
+
zwangslaeufig, spaetestens in ihrem eigenen Kopfkommentar.
|
|
118
|
+
"""
|
|
119
|
+
gefunden = set()
|
|
120
|
+
muster = re.compile(r"Pr[uü]efung(?:en)?\s+(\d+(?:\s*(?:,|und|bis)\s*\d+)*)")
|
|
121
|
+
for text in texte:
|
|
122
|
+
for treffer in muster.finditer(text):
|
|
123
|
+
teile = re.split(r"\s*(,|und|bis)\s*", treffer.group(1))
|
|
124
|
+
for i, teil in enumerate(teile):
|
|
125
|
+
if teil == "bis" and 0 < i < len(teile) - 1:
|
|
126
|
+
gefunden |= set(range(int(teile[i - 1]), int(teile[i + 1]) + 1))
|
|
127
|
+
elif teil.isdigit():
|
|
128
|
+
gefunden.add(int(teil))
|
|
129
|
+
return gefunden
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def check_pruefregister(root: str) -> None:
|
|
133
|
+
"""Pruefung 40 (D-85, D-86): Register und Bestand des Pruefapparats decken sich."""
|
|
134
|
+
texte = {}
|
|
135
|
+
for rel in REGISTER_DATEIEN:
|
|
136
|
+
pfad = os.path.join(root, KERN, *rel.split("/"))
|
|
137
|
+
if not os.path.exists(pfad):
|
|
138
|
+
err(f"{KERN}/{rel}: fehlt. Prüfung 40 hält dort das Register des "
|
|
139
|
+
f"Prüfapparats gegen den Bestand (D-85)")
|
|
140
|
+
return
|
|
141
|
+
texte[rel] = read(pfad) + paketquelltext(root, rel)
|
|
142
|
+
validator = texte["tests/scripts/validate-framework.py"]
|
|
143
|
+
sonden = texte["tests/scripts/probe-pruefungen.py"]
|
|
144
|
+
katalog = texte["tests/TEST_CATALOG.md"]
|
|
145
|
+
kanten = texte["tests/EDGE_CASES.md"]
|
|
146
|
+
|
|
147
|
+
# --- Gegenstand 1: die Anker ------------------------------------------------------
|
|
148
|
+
doc = validator.split('"""')[1] if validator.count('"""') >= 2 else ""
|
|
149
|
+
sondendoc = sonden.split('"""')[1] if sonden.count('"""') >= 2 else ""
|
|
150
|
+
if REGISTER_ANKER not in doc or REGISTER_ENDE not in doc:
|
|
151
|
+
err(f"{KERN}/tests/scripts/validate-framework.py: der Kopfkommentar führt kein "
|
|
152
|
+
f"Register mehr (gesucht: '{REGISTER_ANKER}' und '{REGISTER_ENDE}') – "
|
|
153
|
+
f"Prüfung 40 hat ihren Gegenstand verloren und würde sonst leise bestehen")
|
|
154
|
+
return
|
|
155
|
+
fwko01 = [z for z in katalog.splitlines() if z.startswith("| FW-KO-01")]
|
|
156
|
+
fwko05 = [z for z in katalog.splitlines() if z.startswith("| FW-KO-05")]
|
|
157
|
+
if len(fwko01) != 1 or len(fwko05) != 1:
|
|
158
|
+
err(f"{KERN}/tests/TEST_CATALOG.md: die Zeile FW-KO-01 oder FW-KO-05 steht nicht "
|
|
159
|
+
f"genau einmal (gefunden: {len(fwko01)} und {len(fwko05)}) – Prüfung 40 misst "
|
|
160
|
+
f"dort die Sondenmenge und die Grenzfallanzahl (D-85)")
|
|
161
|
+
return
|
|
162
|
+
|
|
163
|
+
# --- Gegenstand 2: das Register ist lueckenlos und vollstaendig --------------------
|
|
164
|
+
liste = doc.split(REGISTER_ANKER, 1)[1].split(REGISTER_ENDE, 1)[0]
|
|
165
|
+
gefuehrt = sorted({int(n) for n in re.findall(r"^\s{0,2}(\d+)[a-z]?\. ", liste, re.M)})
|
|
166
|
+
if not gefuehrt:
|
|
167
|
+
err(f"{KERN}/tests/scripts/validate-framework.py: das Register im Kopfkommentar "
|
|
168
|
+
f"führt keinen einzigen nummerierten Eintrag – Prüfung 40 hätte nichts zu "
|
|
169
|
+
f"vergleichen und bestünde leise")
|
|
170
|
+
return
|
|
171
|
+
luecken = [n for n in range(1, gefuehrt[-1] + 1) if n not in gefuehrt]
|
|
172
|
+
if luecken:
|
|
173
|
+
err(f"{KERN}/tests/scripts/validate-framework.py: das Register im Kopfkommentar "
|
|
174
|
+
f"hat Lücken – es fehlt {', '.join(str(n) for n in luecken)}. Eine Nummer "
|
|
175
|
+
f"ohne Eintrag ist eine Prüfung, die niemand findet (D-85)")
|
|
176
|
+
genannt = genannte_pruefungen(validator, sonden)
|
|
177
|
+
hoechste = max(genannt) if genannt else 0
|
|
178
|
+
if hoechste > gefuehrt[-1]:
|
|
179
|
+
err(f"{KERN}/tests/scripts/validate-framework.py: das Register im Kopfkommentar "
|
|
180
|
+
f"endet bei Prüfung {gefuehrt[-1]}; die Prüfskripte nennen Prüfung "
|
|
181
|
+
f"{hoechste}. Eine neue Prüfung ohne Registereintrag ist genau der Fall vom "
|
|
182
|
+
f"2026-09-14 – das Register ist die einzige Stelle, die sagt, was dieser "
|
|
183
|
+
f"Lauf prüft (D-85)")
|
|
184
|
+
elif hoechste and hoechste < gefuehrt[-1]:
|
|
185
|
+
err(f"{KERN}/tests/scripts/validate-framework.py: das Register im Kopfkommentar "
|
|
186
|
+
f"führt Prüfung {gefuehrt[-1]}; in den Prüfskripten wird sie nirgends bei "
|
|
187
|
+
f"ihrer Nummer genannt. Ein Eintrag ohne Prüfung verspricht mehr, als der "
|
|
188
|
+
f"Lauf leistet (D-85)")
|
|
189
|
+
|
|
190
|
+
# --- Gegenstand 3: die Sondenmenge an drei Stellen, wortgleich ---------------------
|
|
191
|
+
kennungen = (re.findall(r'\bsonde\("([^"]+)"', sonden)
|
|
192
|
+
+ re.findall(r'melde\("SONDE", "([^"]+)"', sonden))
|
|
193
|
+
mit_sonde = {int(m.group(1)) for m in (re.match(r"(\d+)", k) for k in kennungen) if m}
|
|
194
|
+
if not mit_sonde:
|
|
195
|
+
err(f"{KERN}/tests/scripts/probe-pruefungen.py: keine einzige Sonde mit einer "
|
|
196
|
+
f"Prüfungsnummer gefunden – Prüfung 40 rechnet daraus die Sondenmenge aus "
|
|
197
|
+
f"und hat ihren Gegenstand verloren")
|
|
198
|
+
return
|
|
199
|
+
spanne = nummernspanne(mit_sonde)
|
|
200
|
+
for rel, text, soll in (
|
|
201
|
+
("tests/scripts/validate-framework.py", doc, NACHWEIS_SATZ.format(spanne)),
|
|
202
|
+
("tests/scripts/probe-pruefungen.py", sondendoc, SONDEN_SATZ.format(spanne)),
|
|
203
|
+
("tests/TEST_CATALOG.md", fwko01[0], KATALOG_SPANNE.format(spanne))):
|
|
204
|
+
if soll not in text:
|
|
205
|
+
err(f"{KERN}/{rel}: die Sondenmenge ist dort nicht in der ausgerechneten "
|
|
206
|
+
f"Schreibweise genannt. Erwartet wörtlich: '{soll}'. "
|
|
207
|
+
f"probe-pruefungen.py führt Sonden für die Prüfungen {spanne} – eine "
|
|
208
|
+
f"gepflegte Zahl über den Prüfapparat lag am 2026-09-14 an allen drei "
|
|
209
|
+
f"Stellen daneben (D-86)")
|
|
210
|
+
|
|
211
|
+
# --- Gegenstand 4: die Grenzfallanzahl ausserhalb ihrer Quelle ---------------------
|
|
212
|
+
grenzfaelle = set(re.findall(r"\bG-(\d\d)\b", kanten))
|
|
213
|
+
if not grenzfaelle:
|
|
214
|
+
err(f"{KERN}/tests/EDGE_CASES.md: keine einzige Grenzfallkennung der Form G-NN "
|
|
215
|
+
f"gefunden – Prüfung 40 zählt sie dort und hat ihren Gegenstand verloren")
|
|
216
|
+
return
|
|
217
|
+
soll_gf = KATALOG_GRENZFAELLE.format(len(grenzfaelle))
|
|
218
|
+
if soll_gf not in fwko05[0]:
|
|
219
|
+
err(f"{KERN}/tests/TEST_CATALOG.md: FW-KO-05 nennt nicht die gezählte Anzahl der "
|
|
220
|
+
f"Grenzfälle. Erwartet wörtlich: '{soll_gf}'. Die Zeile ist eine "
|
|
221
|
+
f"Arbeitsanweisung für eine Sitzung; sie stand von 0.33.0 bis 0.41.0 auf "
|
|
222
|
+
f"zwölf, während der Bestand auf zwanzig wuchs – wer sie so fährt, prüft "
|
|
223
|
+
f"einen Teil und meldet das Ganze (D-86)")
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
# ---------------------------------------------------------------------------
|
|
227
|
+
# Pruefung 46: Der 1.0.0-Stand wird ausgerechnet, nicht gepflegt
|
|
228
|
+
# ---------------------------------------------------------------------------
|
|
229
|
+
#
|
|
230
|
+
# ANLASS. D-11 nennt fuenf Kriterien fuer 1.0.0; vier davon sind maschinell zaehlbar.
|
|
231
|
+
# Die Roadmap fuehrte dafuer seit 0.42.0 ausdruecklich KEINE Zahlen, sondern "die
|
|
232
|
+
# Befehle, die sie ausrechnen" - die richtige Lehre aus fuenf falschen Zahlen ueber den
|
|
233
|
+
# Pruefapparat. Am 2026-09-15 wurden diese Befehle zum ersten Mal ausgefuehrt
|
|
234
|
+
# (CR-2026-070, tests/protocols/2026-09-15-gegenpruefung-d11-zaehlregeln.md):
|
|
235
|
+
#
|
|
236
|
+
# Kriterium 1 geglaubt 27 gezaehlt 29 der grep kannte EINE von ZWEI registrierten
|
|
237
|
+
# Markerschreibweisen; die clientgebundene
|
|
238
|
+
# Altform (Produktname statt CLIENT) traegt
|
|
239
|
+
# allein im Pack devin-desktop sieben
|
|
240
|
+
# Fundstellen und zwei in dessen root-template
|
|
241
|
+
# Kriterium 2 geglaubt 103 gezaehlt 118 "die dezentralen TESTS.md je Skill" wurde als
|
|
242
|
+
# zwoelf Dateien gelesen; es sind dreizehn
|
|
243
|
+
# Kriterium 3 geglaubt 16 gezaehlt 69 die genannte Ablagenliste deckt ein Viertel
|
|
244
|
+
# des Bestands - und framework/core/ ist
|
|
245
|
+
# genannt und traegt gar keine Statuszeile
|
|
246
|
+
# Kriterium 4 geglaubt 16 gezaehlt 9 ein roher grep zaehlte die Legende, fuenf
|
|
247
|
+
# Klaerungspunkte und D-11 selbst mit
|
|
248
|
+
#
|
|
249
|
+
# Vier von vier. Keine der Zahlen ist je falsch geschrieben worden - jede ist das
|
|
250
|
+
# richtige Ergebnis einer Regel, die weniger kann als ihr Kriterium verlangt. Ein
|
|
251
|
+
# Befehl, den niemand ausfuehrt, ist keine Ausrechnung, sondern eine Zahl mit einem
|
|
252
|
+
# Zwischenschritt; und weil ihn niemand ausfuehrt, faellt auch nicht auf, dass er das
|
|
253
|
+
# Falsche zaehlt.
|
|
254
|
+
#
|
|
255
|
+
# BAUFORM (E1). Die von Pruefung 40 und 31: Der Stand steht AUSGERECHNET an genau einer
|
|
256
|
+
# Stelle - der Standzeile in docs/ROADMAP.md -, und diese Pruefung haelt die geschriebene
|
|
257
|
+
# Zahl gegen die gezaehlte. Nicht der offene Punkt ist der Fehler, sondern die falsche
|
|
258
|
+
# Zahl. Ein Zaehler, der jeden offenen Punkt meldete, ergaebe heute 225 Fehler, machte
|
|
259
|
+
# jeden Lauf rot und waere binnen eines Releases abgeschaltet; ein Zaehler, der nur
|
|
260
|
+
# berichtet, ist keine Pruefung. Der Preis dieser Bauform steht im Antrag und ist
|
|
261
|
+
# gewollt: JEDER Fortschritt macht den Lauf rot, bis die Zahl nachgezogen ist. Genau
|
|
262
|
+
# dieses Nachziehen ist der Vorgang, der bis 0.47.0 unterblieben ist.
|
|
263
|
+
#
|
|
264
|
+
# ZAEHLBEREICH (E2). Nur <CORE_DIR>/, ohne build/ (Erzeugnis), CHANGELOG.md,
|
|
265
|
+
# governance/change-requests/ und tests/protocols/ (datierte, abgeschlossene
|
|
266
|
+
# Aufzeichnungen). Der Kern ist in jeder Installation derselbe - install.py --check ist
|
|
267
|
+
# genau dafuer da -, also ist die Zahl installationsunabhaengig und dieselbe Standzeile
|
|
268
|
+
# gilt in jedem uebernehmenden Projekt. Fundstellen ausserhalb des Kerns zaehlen nicht,
|
|
269
|
+
# auch echte: README.md:165 war so eine und ist per Hand berichtigt.
|
|
270
|
+
#
|
|
271
|
+
# DER FALLSTRICK, DER BEIM BAUEN ZUSCHNAPPTE (E7). Die erste Fassung lief ueber
|
|
272
|
+
# glob.glob(..., recursive=True). glob ueberspringt Pfadbestandteile, die mit einem Punkt
|
|
273
|
+
# beginnen - damit fehlten fuenfzehn Dateien des Kerns, darunter genau die zwei Traeger
|
|
274
|
+
# clients/*/root-template/.devin/README.md und .../.claude/README.md, die den Befund zu
|
|
275
|
+
# Kriterium 1 tragen. Der Zaehler haette 27 gemeldet und damit zufaellig die geglaubte
|
|
276
|
+
# Zahl bestaetigt. Eine Zaehlregel, die einen Traeger still ueberspringt, war der Anlass
|
|
277
|
+
# dieses Antrags; sie ist beim Bauen der Abhilfe ein zweites Mal entstanden. Deshalb
|
|
278
|
+
# os.walk, und deshalb misst die Selbstprobe C1 des Sondenskripts beide Verfahren
|
|
279
|
+
# gegeneinander.
|
|
280
|
+
#
|
|
281
|
+
# WAS SIE NICHT LEISTET.
|
|
282
|
+
# * Kriterium 5 von D-11 ("Uebernahme in ein zweites Projekt nachgewiesen") zaehlt sie
|
|
283
|
+
# NICHT. Das ist keine Zahl, sondern eine Feststellung. Eine ENTHALTUNG, und sie
|
|
284
|
+
# steht hier statt in einem Gegenstand, der nichts misst.
|
|
285
|
+
# * Sie misst Zahlen, nicht Fortschritt. Ein Modulstatus, der von `entwurf` auf `pilot`
|
|
286
|
+
# gehoben wird, ohne dass jemand das Modul angesehen hat, senkt Kriterium 3 um eins.
|
|
287
|
+
# Die fachliche Abnahme ist nicht maschinell, und diese Pruefung behauptet es nicht.
|
|
288
|
+
# * Kriterium 1 zaehlt auch die Fundstellen, die den Marker nur NENNEN - Registerzeile,
|
|
289
|
+
# Glossarzeile, Arbeitsanweisung (E3). Die Zahl ist ein PEGEL, kein Arbeitsvorrat,
|
|
290
|
+
# und sie kann nicht auf null gehen, solange der Marker sein eigenes Register hat.
|
|
291
|
+
# Das ist richtig so: PLACEHOLDER_REGISTRY.md schreibt beiden Markerformen in der
|
|
292
|
+
# Spalte "Ersetzung/Frist" ausdruecklich "vor Version 1.0.0" vor. Ein Platzhalter,
|
|
293
|
+
# dessen letzte Aussage verifiziert ist, gehoert aus dem Register - sonst fuehrt das
|
|
294
|
+
# Repositorium einen Platzhalter ohne Gegenstand.
|
|
295
|
+
# * Sie sagt nicht "1.0.0-reif" (E8). Stehen alle vier Zahlen auf 0 und der Lauf ist
|
|
296
|
+
# gruen, IST das die Meldung - erzwungen statt behauptet, und ohne einen fuenften
|
|
297
|
+
# Gegenstand, der heute nichts faengt.
|
|
298
|
+
D11_DATEI = KERN + "/docs/ROADMAP.md"
|
|
299
|
+
D11_SATZ = ("Gezählt von Prüfung 46: Kriterium 1 = {}, Kriterium 2 = {}, "
|
|
300
|
+
"Kriterium 3 = {}, Kriterium 4 = {}")
|
|
301
|
+
D11_ANKER = "Gezählt von Prüfung 46: Kriterium 1 = "
|
|
302
|
+
# Beide Schreibweisen (E4). Bis 0.86.1 waren sie registriert; die Altform war nur im
|
|
303
|
+
# Client Pack devin-desktop zulaessig (Pruefung 14 setzte das durch) und trug dieselbe
|
|
304
|
+
# Frist "vor Version 1.0.0". Wer nur die neutrale Form zaehlt, haelt ein Client Pack mit
|
|
305
|
+
# sieben offenen Verifikationsbedarfen fuer fertig.
|
|
306
|
+
#
|
|
307
|
+
# MIT 0.87.0 SIND BEIDE FORMEN ABGESCHAFFT (CR-2026-121, D-291), und dieser Ausdruck
|
|
308
|
+
# bleibt unveraendert stehen. Was er zaehlt, hat sich nicht geaendert; wozu die Zahl
|
|
309
|
+
# dient, schon: Sie war ein Arbeitsvorrat und ist jetzt eine RUECKFALLSPERRE. Ausgebaut
|
|
310
|
+
# wird sie nicht - D-11 verloere damit seinen einzigen maschinellen Zaehler fuer
|
|
311
|
+
# Kriterium 1, die Standzeile fiele von vier Zahlen auf drei, und eine Wiedereinfuehrung
|
|
312
|
+
# der Form fiele niemandem auf. DER PREIS IST BENANNT: Eine Zahl, die dauerhaft auf null
|
|
313
|
+
# steht, wird nicht mehr gelesen; sie traegt nur, solange ihre Sonde laeuft.
|
|
314
|
+
D11_MARKER_RE = re.compile(r"<VERIFY AGAINST CURRENT (?:CLIENT|DEVIN) DOCUMENTATION>")
|
|
315
|
+
D11_AUSSER = ("build/", "CHANGELOG.md", "governance/change-requests/",
|
|
316
|
+
"tests/protocols/")
|
|
317
|
+
D11_MARKER_ENDUNGEN = (".md", ".json", ".py")
|
|
318
|
+
D11_STECKBRIEF_RE = re.compile(r"^\|\s*Status\s*\|\s*(.+?)\s*\|$")
|
|
319
|
+
# Die Steckbriefzeile steht im Kopf des Dokuments. Sechzig Zeilen sind grosszuegig
|
|
320
|
+
# gemessen (der spaeteste Treffer im Bestand steht auf Zeile 41) und halten zugleich die
|
|
321
|
+
# Lebenszyklustabelle aus 08-skill-conventions.md (Zeile 92) und die Vorfalltabelle aus
|
|
322
|
+
# INCIDENT_HANDLING.md (Zeile 37) draussen - beides Tabellen MIT einer Statusspalte, die
|
|
323
|
+
# keinen Modulstatus fuehren.
|
|
324
|
+
D11_STECKBRIEF_KOPF = 60
|
|
325
|
+
D11_KRITERIEN = ("kein unbearbeiteter VERIFY-Marker",
|
|
326
|
+
"Testkatalog und dezentrale Testblätter ohne `offen`",
|
|
327
|
+
"Modulstatus über `entwurf`",
|
|
328
|
+
"Decision Records ohne `entschieden (Vorschlag)`")
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def _d11_kerndateien(root: str, endungen: tuple):
|
|
332
|
+
"""(absoluter Pfad, Pfad unter <CORE_DIR>/) je Kerndatei im Zaehlbereich.
|
|
333
|
+
|
|
334
|
+
os.walk und NICHT glob: glob ueberspringt Pfadbestandteile, die mit einem Punkt
|
|
335
|
+
beginnen, und genau dort liegen zwei Traeger des Kerns (E7, Selbstprobe C1).
|
|
336
|
+
"""
|
|
337
|
+
wurzel = os.path.join(root, KERN)
|
|
338
|
+
for ordner, _, dateien in os.walk(wurzel):
|
|
339
|
+
for name in sorted(dateien):
|
|
340
|
+
if not name.endswith(endungen):
|
|
341
|
+
continue
|
|
342
|
+
pfad = os.path.join(ordner, name)
|
|
343
|
+
rest = os.path.relpath(pfad, wurzel).replace(os.sep, "/")
|
|
344
|
+
if any(rest == a or rest.startswith(a) for a in D11_AUSSER):
|
|
345
|
+
continue
|
|
346
|
+
yield pfad, rest
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def _d11_offene_zellen(text: str, praefix: str) -> int:
|
|
350
|
+
"""Tabellenzeilen mit `praefix`, deren letzte Zelle mit 'offen' beginnt."""
|
|
351
|
+
treffer = 0
|
|
352
|
+
for zeile in text.replace("\r\n", "\n").split("\n"):
|
|
353
|
+
z = zeile.strip()
|
|
354
|
+
if not z.startswith(praefix) or z.startswith("|---"):
|
|
355
|
+
continue
|
|
356
|
+
zellen = tabellenzellen(z)
|
|
357
|
+
if zellen and zellen[-1].startswith("offen"):
|
|
358
|
+
treffer += 1
|
|
359
|
+
return treffer
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _d11_zaehlen(root: str) -> list:
|
|
363
|
+
"""Die vier maschinell zaehlbaren Kriterien von D-11, in ihrer Reihenfolge."""
|
|
364
|
+
# --- 1: Markerfundstellen, beide Schreibweisen -----------------------------------
|
|
365
|
+
k1 = 0
|
|
366
|
+
for pfad, _ in _d11_kerndateien(root, D11_MARKER_ENDUNGEN):
|
|
367
|
+
k1 += len(D11_MARKER_RE.findall(read(pfad)))
|
|
368
|
+
|
|
369
|
+
# --- 2: offene Ergebniszellen im Katalog UND in jedem Testblatt -------------------
|
|
370
|
+
# Gefunden durch Baumdurchlauf, nicht durch eine Ablagenliste (E5): Eine Liste kann
|
|
371
|
+
# eine dreizehnte Datei uebersehen, und sie hat es.
|
|
372
|
+
katalog = os.path.join(root, KERN, "tests", "TEST_CATALOG.md")
|
|
373
|
+
k2 = _d11_offene_zellen(read(katalog), "| FW-") if os.path.isfile(katalog) else 0
|
|
374
|
+
for pfad, _ in _d11_kerndateien(root, ("TESTS.md",)):
|
|
375
|
+
k2 += _d11_offene_zellen(read(pfad), "| ")
|
|
376
|
+
|
|
377
|
+
# --- 3: Steckbriefe auf `entwurf`, im ganzen Bestand ------------------------------
|
|
378
|
+
# Verglichen wird das ERSTE WORT des Werts: role-packs/software-development traegt
|
|
379
|
+
# "entwurf (Referenzpack der Erstfassung)", und ein Gleichheitsvergleich saehe sie
|
|
380
|
+
# nicht (E6).
|
|
381
|
+
k3 = 0
|
|
382
|
+
for pfad, _ in _d11_kerndateien(root, (".md",)):
|
|
383
|
+
for zeile in read(pfad).replace("\r\n", "\n").split("\n")[:D11_STECKBRIEF_KOPF]:
|
|
384
|
+
treffer = D11_STECKBRIEF_RE.match(zeile.strip())
|
|
385
|
+
if not treffer:
|
|
386
|
+
continue
|
|
387
|
+
wert = treffer.group(1).strip().strip("`").strip()
|
|
388
|
+
if wert.split()[:1] == ["entwurf"]:
|
|
389
|
+
k3 += 1
|
|
390
|
+
break
|
|
391
|
+
|
|
392
|
+
# --- 4: Decision Records auf `entschieden (Vorschlag)` ----------------------------
|
|
393
|
+
# NUR Zeilen der Form | D-NN |. Nicht die Legende, nicht die Klaerungspunkte K-NN,
|
|
394
|
+
# nicht D-11 selbst: D-11 sagt "Decision Records", und ein Klaerungspunkt ist keiner.
|
|
395
|
+
log = os.path.join(root, KERN, "governance", "DECISION_LOG.md")
|
|
396
|
+
k4 = 0
|
|
397
|
+
if os.path.isfile(log):
|
|
398
|
+
for zeile in read(log).replace("\r\n", "\n").split("\n"):
|
|
399
|
+
z = zeile.strip()
|
|
400
|
+
if not re.match(r"^\|\s*D-\d+\s*\|", z):
|
|
401
|
+
continue
|
|
402
|
+
zellen = tabellenzellen(z)
|
|
403
|
+
if len(zellen) > 4 and zellen[4].startswith("entschieden (Vorschlag)"):
|
|
404
|
+
k4 += 1
|
|
405
|
+
return [k1, k2, k3, k4]
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
# --- Gegenstand 6 (seit 1.19.1, K-98, D-483): die Markerform AUSSERHALB des
|
|
409
|
+
# Zaehlbereichs. Kriterium 1 zaehlt die Marker im Kern (D-11). Die Einstiegsdokumente
|
|
410
|
+
# der Wurzel und die Quellen des Hauptdokuments unter build/doc/ liegen ausserhalb -
|
|
411
|
+
# Traeger, die der Zaehler nie gesehen hat; 0.87.0 hat dort sechs Fundstellen von Hand
|
|
412
|
+
# entfernt, und keine Pruefung hielt es fest (CR-2026-121, D-295). Eine Fundstelle dort
|
|
413
|
+
# ist ein FEHLER und zaehlt NICHT in Kriterium 1: Die Zahl bliebe sonst nicht die, die
|
|
414
|
+
# D-11 meint, und die Standzeile stiege, ohne dass der Kern sich bewegt hat.
|
|
415
|
+
# Die Wurzeldokumente nur im Quellrepositorium - in einem Projekt gehoeren sie dem
|
|
416
|
+
# Projekt (D-299).
|
|
417
|
+
def _d11_ausserhalb(root: str) -> None:
|
|
418
|
+
"""Markerform in den Wurzeldokumenten und unter build/doc/ - je Fundstelle."""
|
|
419
|
+
traeger = list(DOK_WURZEL) if ist_quellrepositorium(root) else []
|
|
420
|
+
doc = os.path.join(root, KERN, "build", "doc")
|
|
421
|
+
if os.path.isdir(doc):
|
|
422
|
+
traeger += [f"{KERN}/build/doc/{n}" for n in sorted(os.listdir(doc))
|
|
423
|
+
if n.endswith(".md")]
|
|
424
|
+
for rel in traeger:
|
|
425
|
+
pfad = os.path.join(root, *rel.split("/"))
|
|
426
|
+
if not os.path.isfile(pfad):
|
|
427
|
+
continue
|
|
428
|
+
treffer = len(D11_MARKER_RE.findall(read(pfad)))
|
|
429
|
+
if treffer:
|
|
430
|
+
err(f"{rel}: traegt die Markerform einer unverifizierten Aussage "
|
|
431
|
+
f"{treffer}x. Die Stelle liegt ausserhalb des Zaehlbereichs von "
|
|
432
|
+
f"Kriterium 1 und wird dort nie gezaehlt - deshalb meldet Pruefung 46 "
|
|
433
|
+
f"sie einzeln: verifizieren oder die Aussage streichen (K-98, D-295)")
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def check_d11_stand(root: str) -> None:
|
|
437
|
+
"""Pruefung 46 (D-98, D-99): Der 1.0.0-Stand ist ausgerechnet, nicht gepflegt."""
|
|
438
|
+
_d11_ausserhalb(root)
|
|
439
|
+
pfad = os.path.join(root, D11_DATEI.replace("/", os.sep))
|
|
440
|
+
if not os.path.isfile(pfad):
|
|
441
|
+
err(f"{D11_DATEI}: fehlt. Prüfung 46 hält dort den ausgerechneten 1.0.0-Stand "
|
|
442
|
+
f"gegen die geschriebene Standzeile (D-98)")
|
|
443
|
+
return
|
|
444
|
+
text = read(pfad)
|
|
445
|
+
|
|
446
|
+
# --- Gegenstand 1: der Anker ------------------------------------------------------
|
|
447
|
+
# Die Bauform der Pruefungen 28, 29, 31 und 40: Eine Konsistenzpruefung findet ihren
|
|
448
|
+
# Gegenstand ueber einen Suchtext. Geht er verloren, bestuende sie LEISE - und
|
|
449
|
+
# niemand saehe, dass der 1.0.0-Stand nicht mehr geprueft wird.
|
|
450
|
+
wie_oft = text.count(D11_ANKER)
|
|
451
|
+
if wie_oft != 1:
|
|
452
|
+
err(f"{D11_DATEI}: die Standzeile steht {wie_oft}x statt genau einmal "
|
|
453
|
+
f"(gesucht: '{D11_ANKER}…'). Prüfung 46 hat ihren Gegenstand verloren und "
|
|
454
|
+
f"würde sonst leise bestehen. Erwartet wörtlich, in einer Zeile: "
|
|
455
|
+
f"'{D11_SATZ.format(*_d11_zaehlen(root))}' (D-98)")
|
|
456
|
+
return
|
|
457
|
+
|
|
458
|
+
# --- Gegenstand 2 bis 5: die vier Zahlen -----------------------------------------
|
|
459
|
+
# Verglichen werden die ZAHLEN, nicht die Zeichenkette. Ein Vergleich per `in`
|
|
460
|
+
# bestuende bei jedem Praefix: "Kriterium 4 = 9" steckt in "Kriterium 4 = 99", und
|
|
461
|
+
# die Sonde 46a ist genau daran gefallen, bevor sie es meldete.
|
|
462
|
+
gezaehlt = _d11_zaehlen(root)
|
|
463
|
+
soll = D11_SATZ.format(*gezaehlt)
|
|
464
|
+
zeile = next((z.strip() for z in text.replace("\r\n", "\n").split("\n")
|
|
465
|
+
if D11_ANKER in z), "")
|
|
466
|
+
geschrieben = [int(n) for n in re.findall(r"Kriterium \d+ = (\d+)", zeile)]
|
|
467
|
+
if geschrieben == gezaehlt:
|
|
468
|
+
return
|
|
469
|
+
# Die Meldung nennt die gezaehlte Zahl je Kriterium einzeln - wer nur "stimmt nicht"
|
|
470
|
+
# liest, sucht selbst nach, und genau dieses Nachsuchen ist der Vorgang, der bis
|
|
471
|
+
# 0.47.0 unterblieben ist.
|
|
472
|
+
for i, (name, ist) in enumerate(zip(D11_KRITERIEN, gezaehlt)):
|
|
473
|
+
war = geschrieben[i] if i < len(geschrieben) else None
|
|
474
|
+
if war == ist:
|
|
475
|
+
continue
|
|
476
|
+
richtung = ("die Standzeile nennt keine Zahl dafür" if war is None else
|
|
477
|
+
f"die Standzeile nennt {war}" +
|
|
478
|
+
(" – entweder ist der Bestand zurückgefallen, oder der "
|
|
479
|
+
"Zählbereich sieht erstmals, was er vorher nicht sah; "
|
|
480
|
+
"ohne einen Vorstandsvergleich trennt der Zähler die beiden "
|
|
481
|
+
"Lesarten nicht (K-38)" if ist > war else
|
|
482
|
+
" – der Fortschritt ist nicht nachgezogen"))
|
|
483
|
+
err(f"{D11_DATEI}: Kriterium {i + 1} von D-11 ({name}) ist gezählt **{ist}**, "
|
|
484
|
+
f"{richtung}. Der 1.0.0-Stand gehört ausgerechnet und nicht gepflegt; am "
|
|
485
|
+
f"2026-09-15 lagen alle vier Zahlen daneben, ohne dass eine je falsch "
|
|
486
|
+
f"geschrieben worden wäre (CR-2026-070, D-98)")
|
|
487
|
+
if len(geschrieben) != len(gezaehlt):
|
|
488
|
+
err(f"{D11_DATEI}: die Standzeile führt {len(geschrieben)} Zahlen statt "
|
|
489
|
+
f"{len(gezaehlt)}. Erwartet wörtlich: '{soll}' (D-98)")
|
|
490
|
+
|
|
491
|
+
# ---------------------------------------------------------------------------
|
|
492
|
+
# Pruefung 47: Das Statusvokabular jedes Modultraegers
|
|
493
|
+
# ---------------------------------------------------------------------------
|
|
494
|
+
#
|
|
495
|
+
# ANLASS (CR-2026-073 E5, D-108). Das Lebenszyklusmodell gilt seit 0.50.0 fuer JEDEN
|
|
496
|
+
# Modultraeger (D-102) - durchgesetzt war das Vokabular fuer genau einen Dateityp. Die
|
|
497
|
+
# Skillpruefung meldet seit 0.12.0 einen unbekannten Statuswert, aber nur in einer
|
|
498
|
+
# SKILL.md; fuer die uebrigen 56 der 69 Statustraeger war jede Zeichenfolge
|
|
499
|
+
# zulaessig, und "| Status | banane |" waere durch jeden Lauf gelaufen. Genau
|
|
500
|
+
# dieser Fall stand fuer Skills bis 0.12.0 offen und ist mit FW-VN-01
|
|
501
|
+
# geschlossen worden - fuer die anderen Ablagen nie. Solange kein Nicht-Skill gehoben war, hatte die Luecke keinen
|
|
502
|
+
# Gegenstand; mit dem ersten gehobenen Nicht-Skill-Traeger hat sie einen (D-102, E5).
|
|
503
|
+
#
|
|
504
|
+
# DER ZWEITE ANLASS, UND ER IST DER GROESSERE (K-36, D-105). D-102 definierte den
|
|
505
|
+
# Modultraeger ueber das Merkmal, das er tragen soll: "jede versionierte Datei mit
|
|
506
|
+
# einer Steckbriefzeile Status". Eine solche Definition laesst jeden Traeger
|
|
507
|
+
# entkommen, indem er die Zeile weglaesst - und zwoelf taten das, darunter die elf
|
|
508
|
+
# normativen Kernmodule, fuer die checklists/11-framework-release.md unter Abschluss
|
|
509
|
+
# ausdruecklich einen Status oberhalb von entwurf verlangt. Ein Pruefpunkt ohne
|
|
510
|
+
# Gegenstand, in der Checkliste, die 1.0.0 freigibt. Gegenstand 2 dieser Pruefung
|
|
511
|
+
# schliesst das Loch: Wer einen Steckbrief fuehrt, fuehrt eine Statuszeile.
|
|
512
|
+
#
|
|
513
|
+
# WIE EIN STECKBRIEF ERKANNT WIRD (E5). Als die ERSTE Tabelle des Dokuments, die VOR
|
|
514
|
+
# der ersten Ueberschrift der Ebene 2 steht und die Kopfzeile "| Attribut | Wert |"
|
|
515
|
+
# traegt. Der Zuschnitt ist gemessen und nicht geraten: Eine blosse Suche nach dieser
|
|
516
|
+
# Kopfzeile in den ersten sechzig Zeilen trifft auch templates/PLAN_TEMPLATE.md, wo
|
|
517
|
+
# sie im KOERPER der Vorlage steht - hinter einer H2, als Formular fuer den Plan, der
|
|
518
|
+
# aus ihr entsteht. Das ist kein Steckbrief, und die Datei fuehrt zu Recht keinen
|
|
519
|
+
# Status. Gegen den Bestand gemessen erkennt die Regel 81 Steckbriefe (69 mit und 12
|
|
520
|
+
# ohne Statuszeile) und keinen Fehltreffer.
|
|
521
|
+
#
|
|
522
|
+
# VIER GEGENSTAENDE:
|
|
523
|
+
# 1. Der verlorene Anker. Findet der Lauf ueberhaupt keinen Steckbrief, bestuende
|
|
524
|
+
# diese Pruefung leise. Sie meldet es deshalb selbst - die Bauform der Pruefungen
|
|
525
|
+
# 28, 29, 31, 40 und 46 (D-23).
|
|
526
|
+
# 2. Vollstaendigkeit. Jeder Steckbrief fuehrt eine Statuszeile. Das ist der
|
|
527
|
+
# Mechanismus zu D-105; ohne ihn entkaeme der naechste Traeger genauso.
|
|
528
|
+
# 3. Vokabular. Das erste Wort des Werts ist einer der fuenf Statuswerte aus
|
|
529
|
+
# 08-skill-conventions.md Abschnitt 7. Das ERSTE WORT, weil
|
|
530
|
+
# role-packs/software-development einen Verlaufszusatz traegt ("entwurf
|
|
531
|
+
# (Referenzpack der Erstfassung)") - dieselbe Leseregel wie Pruefung 46 (E6 von
|
|
532
|
+
# CR-2026-070).
|
|
533
|
+
# 4. Der Ausfuellschlitz gehoert der Vorlage, und nur ihr (D-104). Eine Vorlage
|
|
534
|
+
# traegt in der Statuszelle einen Schlitz und KEINEN echten Wert - ein echter
|
|
535
|
+
# ginge unveraendert in jede Kopie ueber und waere damit unveraenderlich, ohne
|
|
536
|
+
# dass jemand das entschieden hat; genau dieser Defekt machte Kriterium 3 von
|
|
537
|
+
# D-11 unerreichbar. Umgekehrt traegt ein Traeger, der keine Vorlage ist, keinen
|
|
538
|
+
# Schlitz: Das ist der Preis, den D-104 benannt und nicht abgesichert hat - "wer
|
|
539
|
+
# eine Vorlage kopiert und den Schlitz nicht fuellt, hat ein Pack ohne
|
|
540
|
+
# Statuswert; bei einem Skill faengt das SKILL_STATUS, bei Client-, Role- und
|
|
541
|
+
# Technology-Pack heute nichts".
|
|
542
|
+
#
|
|
543
|
+
# WAS SIE NICHT LEISTET.
|
|
544
|
+
# * Sie prueft das VOKABULAR, nicht die BERECHTIGUNG. Ob ein Traeger auf pilot
|
|
545
|
+
# stehen darf, entscheidet das Review nach 01-governance.md Abschnitt 5 Punkt 3 -
|
|
546
|
+
# ein Protokoll, das ihn namentlich nennt. Das ist ausdruecklich nicht maschinell
|
|
547
|
+
# (D-102), und diese Pruefung behauptet es nicht.
|
|
548
|
+
# * Sie zaehlt nicht. Den Stand haelt Pruefung 46; hier geht es um die Frage, ob ein
|
|
549
|
+
# Wert ueberhaupt zum Vokabular gehoert.
|
|
550
|
+
# * Vorlagen erkennt sie am Ablageort (templates/ oder ein Verzeichnis _template),
|
|
551
|
+
# also an der Unterstrich-Konvention, die auch Pruefung 31 benutzt - nicht an einem
|
|
552
|
+
# Namen und nicht an einer gepflegten Liste.
|
|
553
|
+
STATUS_KOPF_RE = re.compile(r"^\|\s*Attribut\s*\|\s*Wert\s*\|$")
|
|
554
|
+
STATUS_ZEILE_RE = re.compile(r"^\|\s*Status\s*\|\s*(.+?)\s*\|$")
|
|
555
|
+
# Der Ausfuellhinweis einer Vorlage in der Form, die D-104 gesetzt hat: die Marke, ein
|
|
556
|
+
# Semikolon und der Satz, mit welchem Wert die Kopie beginnt.
|
|
557
|
+
STATUS_SCHLITZ_RE = re.compile(r"^<TBD: Status; .*\bbeginnt auf entwurf>$")
|
|
558
|
+
STATUS_ZELLE = "\\| Status \\| … \\|"
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
def _status_steckbrief(text: str):
|
|
562
|
+
"""Die Zeilen des Steckbriefs eines Dokuments, oder None.
|
|
563
|
+
|
|
564
|
+
Der Steckbrief ist die erste Tabelle des Dokuments; sie steht vor der ersten
|
|
565
|
+
Ueberschrift der Ebene 2 und traegt die Kopfzeile "| Attribut | Wert |". Eine
|
|
566
|
+
erste Tabelle mit anderer Kopfzeile bedeutet: kein Steckbrief - und eine Tabelle
|
|
567
|
+
weiter unten ist keiner, auch wenn sie so aussieht (PLAN_TEMPLATE.md).
|
|
568
|
+
"""
|
|
569
|
+
zeilen = text.replace("\r\n", "\n").split("\n")
|
|
570
|
+
for nr, roh in enumerate(zeilen):
|
|
571
|
+
z = roh.strip()
|
|
572
|
+
if z.startswith("## "):
|
|
573
|
+
return None
|
|
574
|
+
if not z.startswith("|"):
|
|
575
|
+
continue
|
|
576
|
+
if not STATUS_KOPF_RE.match(z):
|
|
577
|
+
return None
|
|
578
|
+
raus = []
|
|
579
|
+
for weiter in zeilen[nr:]:
|
|
580
|
+
if not weiter.strip().startswith("|"):
|
|
581
|
+
break
|
|
582
|
+
raus.append(weiter.strip())
|
|
583
|
+
return raus
|
|
584
|
+
return None
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
def _status_ist_vorlage(rest: str) -> bool:
|
|
588
|
+
"""Liegt die Datei in einer Vorlagenablage? Unterstrich-Konvention wie Pruefung 31."""
|
|
589
|
+
return rest.startswith("templates/") or "/_template/" in rest
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
def check_status_vokabular(root: str) -> None:
|
|
593
|
+
"""Pruefung 47 (D-105, D-108): Jeder Steckbrief fuehrt einen gueltigen Statuswert."""
|
|
594
|
+
gefunden = 0
|
|
595
|
+
for pfad, rest in _d11_kerndateien(root, (".md",)):
|
|
596
|
+
steckbrief = _status_steckbrief(read(pfad))
|
|
597
|
+
if steckbrief is None:
|
|
598
|
+
continue
|
|
599
|
+
gefunden += 1
|
|
600
|
+
werte = [m.group(1).strip() for m in
|
|
601
|
+
(STATUS_ZEILE_RE.match(z) for z in steckbrief) if m]
|
|
602
|
+
|
|
603
|
+
# --- Gegenstand 2: Vollstaendigkeit -------------------------------------------
|
|
604
|
+
if not werte:
|
|
605
|
+
err(f"{KERN}/{rest}: der Steckbrief führt keine Zeile `{STATUS_ZELLE}`. "
|
|
606
|
+
f"Jeder Träger mit einem Steckbrief durchläuft den Lebenszyklus "
|
|
607
|
+
f"(D-102); bis 0.50.0 definierte sich der Modulträger über genau diese "
|
|
608
|
+
f"Zeile und ließ damit jeden entkommen, der sie wegließ – zwölf taten "
|
|
609
|
+
f"es, darunter die elf normativen Kernmodule, für die FW-CL-11 einen "
|
|
610
|
+
f"Status oberhalb von `entwurf` verlangt (K-36, D-105)")
|
|
611
|
+
continue
|
|
612
|
+
|
|
613
|
+
wert = werte[0].strip("`").strip()
|
|
614
|
+
schlitz = wert.startswith("<TBD")
|
|
615
|
+
vorlage = _status_ist_vorlage(rest)
|
|
616
|
+
|
|
617
|
+
# --- Gegenstand 4: der Schlitz gehoert der Vorlage, und nur ihr ---------------
|
|
618
|
+
if schlitz and not vorlage:
|
|
619
|
+
err(f"{KERN}/{rest}: die Statuszelle trägt den Ausfüllschlitz '{wert}', "
|
|
620
|
+
f"obwohl die Datei keine Vorlage ist. Wer eine Vorlage kopiert, füllt "
|
|
621
|
+
f"den Schlitz – sonst steht ein Pack ohne Statuswert im Bestand. Das "
|
|
622
|
+
f"ist der Preis, den D-104 benannt und nicht abgesichert hat (D-108)")
|
|
623
|
+
continue
|
|
624
|
+
if vorlage and not schlitz:
|
|
625
|
+
err(f"{KERN}/{rest}: die Statuszelle einer Vorlage trägt den echten Wert "
|
|
626
|
+
f"'{wert}' statt eines Ausfüllschlitzes. Der Steckbrief einer Vorlage "
|
|
627
|
+
f"beschreibt die KOPIE; ein echter Wert geht unverändert in jede Kopie "
|
|
628
|
+
f"über und ist damit unveränderlich, ohne dass jemand das entschieden "
|
|
629
|
+
f"hätte. Genau so war Kriterium 3 von D-11 unerreichbar (D-104). "
|
|
630
|
+
f"Erwartet: '<TBD: Status; … beginnt auf entwurf>'")
|
|
631
|
+
continue
|
|
632
|
+
if schlitz:
|
|
633
|
+
if not STATUS_SCHLITZ_RE.match(wert):
|
|
634
|
+
err(f"{KERN}/{rest}: der Ausfüllschlitz '{wert}' folgt nicht der Form "
|
|
635
|
+
f"'<TBD: Status; … beginnt auf entwurf>'. Ein Schlitz, der den "
|
|
636
|
+
f"Anfangswert nicht nennt, lässt die Kopie raten (D-104)")
|
|
637
|
+
continue
|
|
638
|
+
|
|
639
|
+
# --- Gegenstand 3: das Vokabular ---------------------------------------------
|
|
640
|
+
erstes = wert.split()[:1]
|
|
641
|
+
if erstes and erstes[0] not in SKILL_STATUS:
|
|
642
|
+
err(f"{KERN}/{rest}: Statuswert '{wert}' gehört nicht zum Vokabular. "
|
|
643
|
+
f"Zulässig sind die fünf Werte aus "
|
|
644
|
+
f"framework/core/08-skill-conventions.md Abschnitt 7 "
|
|
645
|
+
f"({', '.join(sorted(SKILL_STATUS))}); verglichen wird das erste Wort, "
|
|
646
|
+
f"ein Verlaufszusatz in Klammern ist zulässig. Bis 0.50.0 griff diese "
|
|
647
|
+
f"Regel nur in einer SKILL.md – für 56 der 69 Statusträger war jede "
|
|
648
|
+
f"Zeichenfolge erlaubt (D-108)")
|
|
649
|
+
|
|
650
|
+
# --- Gegenstand 1: der Anker ------------------------------------------------------
|
|
651
|
+
if not gefunden:
|
|
652
|
+
err(f"{KERN}/: kein einziger Steckbrief gefunden (erste Tabelle des Dokuments "
|
|
653
|
+
f"vor der ersten Überschrift der Ebene 2, Kopfzeile `| Attribut | Wert |`). "
|
|
654
|
+
f"Prüfung 47 hat ihren Gegenstand verloren und würde sonst leise bestehen "
|
|
655
|
+
f"(D-108)")
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
# --- Pruefung 50 -------------------------------------------------------------------
|
|
659
|
+
# Die Ausnahmemenge steht in dem Dokument, das die REGEL traegt - nicht hier. Eine
|
|
660
|
+
# Ausnahme im Kopfkommentar einer Pruefung findet niemand, der die Regel liest (0.57.0).
|
|
661
|
+
SYNTH_ANKER = "**Belegte synthetische Kennungen"
|
|
662
|
+
KLAERUNG_RE = re.compile(r"\bK-\d+\b")
|
|
663
|
+
KLAERUNG_ZEILE_RE = re.compile(r"^\|\s*(K-\d+)\s*\|", re.M)
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
def _synthetische_kennungen(logtext: str) -> set:
|
|
667
|
+
"""Die belegten synthetischen Kennungen - aus dem Absatz des Decision Logs.
|
|
668
|
+
|
|
669
|
+
Sie gehoeren keinem Klaerungspunkt: Sonden und Gegenproben des Pruefapparats
|
|
670
|
+
brauchen Kennungen, die nie echt vergeben werden (D-23-Nachweis ohne Kollision).
|
|
671
|
+
Leere Menge heisst: der Anker ist verloren - der Aufrufer meldet das.
|
|
672
|
+
"""
|
|
673
|
+
for zeile in logtext.splitlines():
|
|
674
|
+
if zeile.lstrip().startswith(SYNTH_ANKER):
|
|
675
|
+
return set(re.findall(r"`([A-Z]+-\d+)`", zeile))
|
|
676
|
+
return set()
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
def check_klaerungsregister(root: str) -> None:
|
|
680
|
+
"""Pruefung 50 (D-147): Jede im Kern genannte Klaerungspunktkennung steht im Register."""
|
|
681
|
+
logpfad = os.path.join(root, KERN, "governance", "DECISION_LOG.md")
|
|
682
|
+
if not os.path.exists(logpfad):
|
|
683
|
+
err(f"{KERN}/governance/DECISION_LOG.md fehlt – Prüfung 50 hat ihren Gegenstand "
|
|
684
|
+
f"verloren; sie bestünde sonst leise (D-23)")
|
|
685
|
+
return
|
|
686
|
+
logtext = read(logpfad)
|
|
687
|
+
synth = _synthetische_kennungen(logtext)
|
|
688
|
+
if not synth:
|
|
689
|
+
err(f"{KERN}/governance/DECISION_LOG.md: der Absatz '{SYNTH_ANKER}…' fehlt oder "
|
|
690
|
+
f"nennt keine Kennung in Backticks – Prüfung 50 leitet ihre Ausnahmemenge "
|
|
691
|
+
f"daraus ab und hat ihren Anker verloren (D-23)")
|
|
692
|
+
return
|
|
693
|
+
gefuehrt = set(KLAERUNG_ZEILE_RE.findall(logtext))
|
|
694
|
+
if not gefuehrt:
|
|
695
|
+
err(f"{KERN}/governance/DECISION_LOG.md: keine Registerzeile '| K-NN |' gefunden – "
|
|
696
|
+
f"Prüfung 50 hat ihren Gegenstand verloren (D-23)")
|
|
697
|
+
return
|
|
698
|
+
fundorte: dict = {}
|
|
699
|
+
for path in iter_text_files(root):
|
|
700
|
+
rel = os.path.relpath(path, root).replace(os.sep, "/")
|
|
701
|
+
if not rel.startswith(KERN + "/"):
|
|
702
|
+
continue
|
|
703
|
+
if not path.endswith((".md", ".py", ".json", ".template")):
|
|
704
|
+
continue
|
|
705
|
+
for kennung in set(KLAERUNG_RE.findall(read(path))):
|
|
706
|
+
fundorte.setdefault(kennung, set()).add(rel)
|
|
707
|
+
for kennung in sorted(set(fundorte) - gefuehrt - synth,
|
|
708
|
+
key=lambda k: int(k.split("-")[1])):
|
|
709
|
+
traeger = sorted(fundorte[kennung])
|
|
710
|
+
err(f"{KERN}/governance/DECISION_LOG.md: '{kennung}' wird in "
|
|
711
|
+
f"{len(traeger)} Träger(n) genannt ({', '.join(traeger[:3])}"
|
|
712
|
+
f"{' …' if len(traeger) > 3 else ''}) und steht in keiner Registerzeile. "
|
|
713
|
+
f"Ein Register, das seinen Gegenstand nicht führt, ist keine Liste offener "
|
|
714
|
+
f"Punkte, sondern eine Auswahl (D-147)")
|
|
715
|
+
|
|
716
|
+
# --- Pruefung 102: die Form des Klaerungsregisters (CR-2026-158, D-465) -------------------
|
|
717
|
+
# ANLASS, NACHGEZAEHLT am 2026-09-29: 114 von 184 Klaerungspunkten standen in der
|
|
718
|
+
# Entscheidungstabelle (K-100 nannte 27), eine Leerzeile teilte die Klaerungstabelle, und elf
|
|
719
|
+
# erledigte Punkte trugen weiter "offen". Pruefung 50 fragt nur, OB eine Kennung eine Zeile
|
|
720
|
+
# hat - nicht, wo sie steht und womit ihr Status beginnt.
|
|
721
|
+
#
|
|
722
|
+
# ABGELEITET, NICHT GEPFLEGT: Das Vokabular steht in der Legende des Decision Logs, hinter
|
|
723
|
+
# '*Klärungspunkte:*' bis zum Satz 'Diese Aufzählung ist vollständig', je Wert in Backticks.
|
|
724
|
+
# Ein Wert mit Auslassungszeichen ('eingeplant (…)', 'zusammengelegt mit K-…') gilt als
|
|
725
|
+
# Praefix bis dorthin.
|
|
726
|
+
#
|
|
727
|
+
# WAS SIE NICHT LEISTET: Sie sieht den ANFANG der Statuszelle, nicht, ob er stimmt. Ein
|
|
728
|
+
# erledigter Punkt, der "offen" traegt, bleibt eine Frage der Durchsicht (D-465).
|
|
729
|
+
# AUSGENOMMEN wie in Pruefung 50: die belegten synthetischen Kennungen des Pruefapparats. Die
|
|
730
|
+
# Gegenprobe 46b braucht einen Klaerungspunkt mit dem Wert eines Decision Records - ein
|
|
731
|
+
# Sondenfall, kein Registerfall; der erste Abnahmelauf von 1.18.1 hat ihn gemeldet.
|
|
732
|
+
P102_LEGENDE = "*Klärungspunkte:*"
|
|
733
|
+
P102_LEGENDE_ENDE = "Diese Aufzählung ist vollständig"
|
|
734
|
+
P102_ABSCHNITT = "## 1. "
|
|
735
|
+
P102_ZUSAMMEN_RE = re.compile(r"^zusammengelegt mit (K-\d+)")
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
def _p102_vokabular(logtext: str) -> list:
|
|
739
|
+
for zeile in logtext.splitlines():
|
|
740
|
+
if P102_LEGENDE in zeile:
|
|
741
|
+
teil = zeile.split(P102_LEGENDE, 1)[1].split(P102_LEGENDE_ENDE, 1)[0]
|
|
742
|
+
return [w.split("…", 1)[0] for w in re.findall(r"`([^`]+)`", teil)]
|
|
743
|
+
return []
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
def _p102_kopf(zelle: str) -> str:
|
|
747
|
+
"""Der Anfang einer Statuszelle ohne Auszeichnung und ohne vorangestellte Zeichen."""
|
|
748
|
+
return re.sub(r"^[^\w(]+", "", re.sub(r"[*`]", "", zelle))
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
def check_klaerungsregister_form(root: str) -> None:
|
|
752
|
+
"""Pruefung 102 (D-465): Lage und Statusanfang jedes Klaerungspunkts."""
|
|
753
|
+
logpfad = os.path.join(root, KERN, "governance", "DECISION_LOG.md")
|
|
754
|
+
if not os.path.exists(logpfad):
|
|
755
|
+
return # Pruefung 50 meldet das bereits
|
|
756
|
+
rel = f"{KERN}/governance/DECISION_LOG.md"
|
|
757
|
+
logtext = read(logpfad).replace("\r\n", "\n")
|
|
758
|
+
vokabular = _p102_vokabular(logtext)
|
|
759
|
+
synth = _synthetische_kennungen(logtext)
|
|
760
|
+
if not vokabular:
|
|
761
|
+
err(f"{rel}: die Legende nennt hinter '{P102_LEGENDE}' keinen Statuswert in Backticks – "
|
|
762
|
+
f"Prüfung 102 leitet ihr Vokabular daraus ab und hat ihren Anker verloren (D-23)")
|
|
763
|
+
return
|
|
764
|
+
abschnitt = ""
|
|
765
|
+
status = {}
|
|
766
|
+
for nr, zeile in enumerate(logtext.split("\n"), 1):
|
|
767
|
+
if zeile.startswith("## "):
|
|
768
|
+
abschnitt = zeile
|
|
769
|
+
continue
|
|
770
|
+
m = KLAERUNG_ZEILE_RE.match(zeile)
|
|
771
|
+
if not m:
|
|
772
|
+
continue
|
|
773
|
+
kennung = m.group(1)
|
|
774
|
+
if kennung in synth:
|
|
775
|
+
continue
|
|
776
|
+
if not abschnitt.startswith(P102_ABSCHNITT):
|
|
777
|
+
err(f"{rel}:{nr}: '{kennung}' steht unter '{abschnitt[3:].strip() or 'keiner Überschrift'}' "
|
|
778
|
+
f"statt in der Klärungstabelle (Abschnitt 1). Dort rendert die Zeile unter fremden "
|
|
779
|
+
f"Spaltenköpfen, und wer die offenen Punkte zählt, zählt eine Tabelle zu wenig (D-465)")
|
|
780
|
+
zellen = tabellenzellen(zeile.strip())
|
|
781
|
+
kopf = _p102_kopf(zellen[-1]) if zellen else ""
|
|
782
|
+
status[kennung] = (nr, kopf)
|
|
783
|
+
if not any(kopf.startswith(w) for w in vokabular):
|
|
784
|
+
err(f"{rel}:{nr}: die Statuszelle von '{kennung}' beginnt mit „{kopf[:40]}“ – kein Wert "
|
|
785
|
+
f"der Legende ({', '.join(vokabular)}). Ein Status außerhalb des Vokabulars "
|
|
786
|
+
f"zählt niemand richtig: bis 1.18.1 trugen elf erledigte Punkte „offen“ (D-465)")
|
|
787
|
+
elif re.match(r"^eingeplant \(\s*\)", kopf):
|
|
788
|
+
err(f"{rel}:{nr}: '{kennung}' ist eingeplant, nennt aber kein Ziel in der Klammer (D-465)")
|
|
789
|
+
for kennung, (nr, kopf) in status.items():
|
|
790
|
+
m = P102_ZUSAMMEN_RE.match(kopf)
|
|
791
|
+
if not m:
|
|
792
|
+
continue
|
|
793
|
+
ziel = m.group(1)
|
|
794
|
+
if ziel not in status:
|
|
795
|
+
err(f"{rel}:{nr}: '{kennung}' ist mit '{ziel}' zusammengelegt, das keine Registerzeile "
|
|
796
|
+
f"hat – der Gegenstand wird nirgends geführt (D-465)")
|
|
797
|
+
elif P102_ZUSAMMEN_RE.match(status[ziel][1]):
|
|
798
|
+
err(f"{rel}:{nr}: '{kennung}' ist mit '{ziel}' zusammengelegt, das selbst "
|
|
799
|
+
f"zusammengelegt ist – eine Kette statt eines Ortes (D-465)")
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
# --- Pruefung 53 -------------------------------------------------------------------
|
|
803
|
+
# Der Releaseplan sagt je Posten voraus, wohin Kriterium 2 geht. Die Vorhersagen bilden
|
|
804
|
+
# eine KETTE: Was ein Posten erreicht, ist der Ausgangswert des naechsten. Bis 0.60.0 hat
|
|
805
|
+
# niemand sie nachgerechnet - und das Protokoll zu 0.56.0 hatte ausdruecklich entschieden,
|
|
806
|
+
# das nicht zu tun ("die Zwischenstaende sind Vorhersagen und tragen keinen Anspruch, den
|
|
807
|
+
# eine Pruefung einloesen muesste").
|
|
808
|
+
#
|
|
809
|
+
# DIE ENTSCHEIDUNG IST MIT 0.61.0 UMGEKEHRT, UND DER GRUND IST GEMESSEN (D-153): 0.60.0 hat
|
|
810
|
+
# eine Zelle aus einem Posten herausgenommen, die Zahl des Postens nachgezogen und die des
|
|
811
|
+
# FOLGEPOSTENS stehen lassen. Die Kette riss um eins, der Plan war in sich widerspruechlich,
|
|
812
|
+
# und er ist so gemergt worden.
|
|
813
|
+
#
|
|
814
|
+
# DIE PRUEFUNG BEURTEILT NICHT, OB EINE VORHERSAGE STIMMT - das kann sie nicht. Sie prueft,
|
|
815
|
+
# ob die Tabelle mit sich selbst uebereinstimmt: Kette geschlossen, und der letzte Wert ist
|
|
816
|
+
# null, weil Kriterium 2 dort ankommen muss (D-11).
|
|
817
|
+
#
|
|
818
|
+
# WAS SIE NICHT LEISTET: Die zweite Haelfte desselben Befundes war PROSA - die Zeile nannte
|
|
819
|
+
# weiter eine Klasse, die ihre eigene Zahl nicht mehr enthielt. Das ist nicht mechanisch zu
|
|
820
|
+
# finden und bleibt Gegenstand des Durchgangs vor dem Commit.
|
|
821
|
+
P53_ROADMAP = KERN + "/docs/ROADMAP.md"
|
|
822
|
+
P53_UEBERSCHRIFT = "#### Der Releaseplan bis 1.0.0 und darüber hinaus"
|
|
823
|
+
P53_KETTE_RE = re.compile(r"Kriterium 2:\s*\*\*(\d+)\s*→\s*(\d+)\*\*")
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
def check_releaseplan_kette(root: str) -> None:
|
|
827
|
+
"""Pruefung 53 (D-153): Die Kriterium-2-Kette des Releaseplans schliesst und endet bei 0."""
|
|
828
|
+
pfad = os.path.join(root, P53_ROADMAP.replace("/", os.sep))
|
|
829
|
+
if not os.path.isfile(pfad):
|
|
830
|
+
err(f"{P53_ROADMAP} fehlt – Prüfung 53 hat ihren Gegenstand verloren; sie bestünde "
|
|
831
|
+
f"sonst leise (D-23)")
|
|
832
|
+
return
|
|
833
|
+
text = read(pfad).replace("\r\n", "\n")
|
|
834
|
+
if P53_UEBERSCHRIFT not in text:
|
|
835
|
+
err(f"{P53_ROADMAP}: die Überschrift '{P53_UEBERSCHRIFT}' ist nicht mehr "
|
|
836
|
+
f"auffindbar. Prüfung 53 liest den Releaseplan darunter und hätte ohne sie "
|
|
837
|
+
f"nichts zu prüfen (D-23)")
|
|
838
|
+
return
|
|
839
|
+
rest = text.split(P53_UEBERSCHRIFT, 1)[1]
|
|
840
|
+
glieder = []
|
|
841
|
+
for zeile in rest.split("\n"):
|
|
842
|
+
if not zeile.startswith("|"):
|
|
843
|
+
if glieder and not zeile.strip():
|
|
844
|
+
continue
|
|
845
|
+
m = P53_KETTE_RE.search(zeile)
|
|
846
|
+
if m:
|
|
847
|
+
glieder.append((int(m.group(1)), int(m.group(2)), zeile.split("|")[1].strip()))
|
|
848
|
+
if len(glieder) < 2:
|
|
849
|
+
err(f"{P53_ROADMAP}: der Releaseplan führt weniger als zwei Vorhersagen zu "
|
|
850
|
+
f"Kriterium 2. Prüfung 53 rechnet eine Kette nach und hätte damit keinen "
|
|
851
|
+
f"Gegenstand mehr (D-23)")
|
|
852
|
+
return
|
|
853
|
+
for (_, ende, posten), (start, _, folge) in zip(glieder, glieder[1:]):
|
|
854
|
+
if ende != start:
|
|
855
|
+
err(f"{P53_ROADMAP}: Die Kriterium-2-Kette des Releaseplans reißt zwischen "
|
|
856
|
+
f"{posten} (endet bei {ende}) und {folge} (beginnt bei {start}). Was ein "
|
|
857
|
+
f"Posten erreicht, ist der Ausgangswert des nächsten; eine Tabelle, die "
|
|
858
|
+
f"sich selbst widerspricht, ist keine Vorhersage (D-153)")
|
|
859
|
+
if glieder[-1][1] != 0:
|
|
860
|
+
err(f"{P53_ROADMAP}: Die Kriterium-2-Kette des Releaseplans endet bei "
|
|
861
|
+
f"{glieder[-1][1]} statt bei 0 ({glieder[-1][2]}). Kriterium 2 von D-11 ist "
|
|
862
|
+
f"erfüllt, wenn der Testkatalog keine offene Zelle mehr führt – ein Plan, der "
|
|
863
|
+
f"nicht dort ankommt, führt nicht bis 1.0.0 (D-153)")
|
|
864
|
+
|
|
865
|
+
# --- Pruefung 58: Vollstaendigkeit des Decision-Record-Registers -------------------
|
|
866
|
+
#
|
|
867
|
+
# DIE SCHWESTER VON PRUEFUNG 50, eine Kennungsfamilie weiter. Der gemessene Fall stammt
|
|
868
|
+
# aus dem eigenen Pruefapparat: Die Registereintraege der Pruefungen 55 und 56 trugen
|
|
869
|
+
# seit 0.63.0 einen Platzhalter an der Stelle der Nummer, waehrend die Meldungen
|
|
870
|
+
# derselben Pruefungen die richtige Kennung nannten.
|
|
871
|
+
#
|
|
872
|
+
# WARUM DAS MUSTER EINEN SCHWANZ HAT. Ein Muster der Form D-\d+ mit abschliessender
|
|
873
|
+
# Wortgrenze findet den gemessenen Fall NICHT: Zwischen der letzten Ziffer und dem
|
|
874
|
+
# Platzhalterzeichen steht keine Wortgrenze. Deshalb wird alles gelesen, was auf die
|
|
875
|
+
# erste Ziffer folgt - und danach geprueft, ob die Form ueberhaupt stimmt. Eine Kennung,
|
|
876
|
+
# die die Form knapp verfehlt, ist fuer einen Zaehler sonst unsichtbar, und das ist die
|
|
877
|
+
# gefaehrlichere Haelfte: Sie sieht im Fliesstext wie eine Kennung aus.
|
|
878
|
+
D58_ERWAEHNUNG_RE = re.compile(r"(?<![\w-])D-\d[\w+]*")
|
|
879
|
+
D58_ZEILE_RE = re.compile(r"^\|\s*(D-\d+)\s*\|", re.M)
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
def check_decisionregister(root: str) -> None:
|
|
883
|
+
"""Pruefung 58 (D-169): Jede genannte D-Kennung steht im Register des Decision Logs."""
|
|
884
|
+
logpfad = os.path.join(root, KERN, "governance", "DECISION_LOG.md")
|
|
885
|
+
if not os.path.exists(logpfad):
|
|
886
|
+
return # Pruefung 50 meldet den fehlenden Traeger bereits
|
|
887
|
+
logtext = read(logpfad)
|
|
888
|
+
synth = _synthetische_kennungen(logtext)
|
|
889
|
+
gefuehrt = set(D58_ZEILE_RE.findall(logtext))
|
|
890
|
+
if not gefuehrt:
|
|
891
|
+
err(f"{KERN}/governance/DECISION_LOG.md: keine Registerzeile '| D-NNN |' "
|
|
892
|
+
f"gefunden - Prüfung 58 hat ihren Gegenstand verloren; sie bestünde sonst "
|
|
893
|
+
f"leise (D-23, D-169)")
|
|
894
|
+
return
|
|
895
|
+
fundorte: dict = {}
|
|
896
|
+
for path in iter_text_files(root):
|
|
897
|
+
rel = os.path.relpath(path, root).replace(os.sep, "/")
|
|
898
|
+
if not rel.startswith(KERN + "/"):
|
|
899
|
+
continue
|
|
900
|
+
if not path.endswith((".md", ".py", ".json", ".template")):
|
|
901
|
+
continue
|
|
902
|
+
for kennung in set(D58_ERWAEHNUNG_RE.findall(read(path))):
|
|
903
|
+
fundorte.setdefault(kennung, set()).add(rel)
|
|
904
|
+
for kennung in sorted(set(fundorte) - gefuehrt - synth):
|
|
905
|
+
traeger = sorted(fundorte[kennung])
|
|
906
|
+
ort = (f"{len(traeger)} Träger(n) ({', '.join(traeger[:3])}"
|
|
907
|
+
f"{' …' if len(traeger) > 3 else ''})")
|
|
908
|
+
if re.fullmatch(r"D-\d+", kennung) is None:
|
|
909
|
+
err(f"{KERN}/governance/DECISION_LOG.md: '{kennung}' wird in {ort} genannt "
|
|
910
|
+
f"und ist keine Kennung der Form D-NNN. Eine Kennung, die die Form knapp "
|
|
911
|
+
f"verfehlt, ist für jeden Zähler unsichtbar und liest sich im Fließtext "
|
|
912
|
+
f"trotzdem wie eine (D-169)")
|
|
913
|
+
else:
|
|
914
|
+
err(f"{KERN}/governance/DECISION_LOG.md: '{kennung}' wird in {ort} genannt "
|
|
915
|
+
f"und steht in keiner Registerzeile. Ein Register, das seinen Gegenstand "
|
|
916
|
+
f"nicht führt, ist keine Liste, sondern eine Auswahl (D-169)")
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
# --- Pruefung 91: die Standueberschrift der Roadmap (D-372) -------------------------
|
|
920
|
+
#
|
|
921
|
+
# ANLASS, gemessen beim Bau von 1.8.0: "## Stand nach Release 1.4.4" - vier Releases
|
|
922
|
+
# alt, direkt ueber "Wird mit jedem Release fortgeschrieben". Bis 0.88.1 stand sie auf
|
|
923
|
+
# 0.56.0, zweiunddreissig Releases lang. Eine Ueberschrift, die sagt, von wann sie ist,
|
|
924
|
+
# ist eine Zahl mit einem Gegenstand - und der liegt in VERSION.
|
|
925
|
+
# GRENZE: Sie prueft die ZAHL der Ueberschrift, nicht den Abschnitt darunter - dieselbe
|
|
926
|
+
# Bauform wie 77 (Version, nicht Inhalt). Das Datum in Klammern prueft sie nicht.
|
|
927
|
+
P91_ROADMAP = KERN + "/docs/ROADMAP.md"
|
|
928
|
+
P91_ANKER = "## Stand nach Release "
|
|
929
|
+
P91_RE = re.compile(r"^## Stand nach Release `?(\d+\.\d+\.\d+)`?", re.M)
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
def check_roadmapstand(root: str) -> None:
|
|
933
|
+
"""Pruefung 91 (D-372): Die Standueberschrift der Roadmap nennt VERSION."""
|
|
934
|
+
rpfad = os.path.join(root, *P91_ROADMAP.split("/"))
|
|
935
|
+
vpfad = os.path.join(root, KERN, "VERSION")
|
|
936
|
+
if not os.path.isfile(rpfad) or not os.path.isfile(vpfad):
|
|
937
|
+
return # Pruefungen 1 und 85 melden den fehlenden Traeger bereits
|
|
938
|
+
text = read(rpfad)
|
|
939
|
+
treffer = P91_RE.findall(text)
|
|
940
|
+
if len(treffer) != 1:
|
|
941
|
+
err(f"{P91_ROADMAP}: die Überschrift '{P91_ANKER}X.Y.Z' steht "
|
|
942
|
+
f"{len(treffer)}-mal statt genau einmal. Prüfung 91 hält sie gegen "
|
|
943
|
+
f"{KERN}/VERSION und bestünde ohne sie leise (D-23, D-372)")
|
|
944
|
+
return
|
|
945
|
+
stand = read(vpfad).strip()
|
|
946
|
+
if treffer[0] != stand:
|
|
947
|
+
err(f"{P91_ROADMAP}: die Standüberschrift nennt Release {treffer[0]}, "
|
|
948
|
+
f"{KERN}/VERSION führt {stand}. Die Überschrift sagt, von wann der Abschnitt "
|
|
949
|
+
f"darunter ist – bei 1.8.0 stand sie vier Releases zurück, direkt über dem "
|
|
950
|
+
f"Satz 'Wird mit jedem Release fortgeschrieben' (D-372)")
|