@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,957 @@
|
|
|
1
|
+
"""Die Werkzeuge des Kerns und ihre Lieferung: Bytecode, Erzeugnisse in .gitignore,
|
|
2
|
+
Praefixerfassung, Erhebungsablage, Werkzeugnamen, Arbeitsplatzpfade, Kernlage,
|
|
3
|
+
Lieferumfang und die Paketquellen.
|
|
4
|
+
|
|
5
|
+
Pruefungen 45, 68, 69, 70, 71, 76, 90, 107 und 112. Teil des Validators validate-framework.py,
|
|
6
|
+
seit 1.19.1 nach Gegenstand in Module geteilt (K-174). Das Register aller Pruefungen
|
|
7
|
+
steht im Kopfkommentar des Einstiegs, die Grenze jeder einzelnen in ihrem Kopfkommentar
|
|
8
|
+
hier."""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import ast
|
|
12
|
+
import builtins
|
|
13
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
import re
|
|
16
|
+
import symtable
|
|
17
|
+
import sys
|
|
18
|
+
|
|
19
|
+
from .gemeinsam import (
|
|
20
|
+
_clientmap, _verfolgte_dateien, err, hinweis, ist_quellrepositorium,
|
|
21
|
+
iter_text_files, KERN, nicht_geliefert, PAKET_JE_SKRIPT, read, warn)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# --- 45: Der Bytecode des Kerns gehoert nicht in die Versionierung (D-97) -----------
|
|
25
|
+
#
|
|
26
|
+
# ANLASS. Abgezaehlt am 2026-09-15 an **beiden** Projekten, die dieses Framework benutzen:
|
|
27
|
+
# Der Pilot fuehrte sechs .pyc-Dateien unter .koolie/core/ in der Versionierung, das
|
|
28
|
+
# Uebungsrepositorium zwei. Zwei von zwei. Der Uebernahmeleitfaden sagte zur .gitignore
|
|
29
|
+
# nur, welche Zeilen man **weglassen** soll - die vier, die im Framework-Repositorium die
|
|
30
|
+
# Wurzelbestandteile ausschliessen. Welche Zeile man **braucht**, sagte er nicht.
|
|
31
|
+
#
|
|
32
|
+
# **Das ist dieselbe Bauform wie der Befund von 0.45.0:** eine Anweisung, die die halbe
|
|
33
|
+
# Migration beschreibt, ist gefaehrlicher als keine. Wer dem Leitfaden woertlich folgt,
|
|
34
|
+
# schreibt eine eigene .gitignore - und versioniert danach den Bytecode eines Werkzeugs,
|
|
35
|
+
# das bei jedem Lauf neuen erzeugt.
|
|
36
|
+
#
|
|
37
|
+
# ZWEI GEGENSTAENDE, und der zweite ist der, der den Fall wirklich faengt:
|
|
38
|
+
#
|
|
39
|
+
# 1. DIE REGEL. Die .gitignore des Projekts deckt __pycache__ ab. Geprueft wird gegen
|
|
40
|
+
# eine kleine Liste gebraeuchlicher Schreibweisen (GITIGNORE_DECKUNG), nicht gegen
|
|
41
|
+
# eine einzige - ein Projekt, das `*.pyc` schreibt, ist richtig, und eine Pruefung,
|
|
42
|
+
# die es meldete, waere zu eng. Genau der Fehler, den Pruefung 37 einmal gemacht hat.
|
|
43
|
+
# 2. DER BESTAND. Wo git erreichbar und die Wurzel ein Repositorium ist: keine Datei
|
|
44
|
+
# unter <CORE_DIR>/ mit der Endung .pyc oder im Pfad __pycache__ darf verfolgt sein.
|
|
45
|
+
#
|
|
46
|
+
# WARUM BEIDE. Die Regel allein waere die halbe Migration ein zweites Mal: **git liest
|
|
47
|
+
# die .gitignore fuer bereits verfolgte Dateien nicht.** Wer die Zeile nachtraegt und
|
|
48
|
+
# `git rm --cached` vergisst, bekaeme einen gruenen Lauf und haette die sechs Dateien
|
|
49
|
+
# weiter im Repositorium. Der Bestand allein wiederum sagt dem Projekt nicht, wie es die
|
|
50
|
+
# Wiederholung verhindert - beim naechsten `git add` waeren sie zurueck.
|
|
51
|
+
#
|
|
52
|
+
# GRENZE. Gegenstand 2 laeuft nur, wo git erreichbar ist und die Wurzel ein Repositorium
|
|
53
|
+
# ist. Wo nicht, sagt die Pruefung das als **Warnung** - dieselbe Bauform, die dieses
|
|
54
|
+
# Skript fuer das fehlende PyYAML schon hat. Eine Pruefhaelfte, die stumm ausfaellt, waere
|
|
55
|
+
# genau der Befundtyp, gegen den D-23 gebaut ist.
|
|
56
|
+
# Und: Fehlt die .gitignore ganz, ist das eine **Warnung** und kein Fehler. Ob ein Projekt
|
|
57
|
+
# ueberhaupt versioniert, kann dieses Skript nicht wissen; Gegenstand 2 faengt den echten
|
|
58
|
+
# Fall ohnehin, sobald git da ist.
|
|
59
|
+
GITIGNORE_DECKUNG = ("__pycache__/", "__pycache__", "**/__pycache__/",
|
|
60
|
+
"*.pyc", "**/*.pyc")
|
|
61
|
+
BYTECODE_MARKER = "__pycache__"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def check_bytecode_versioniert(root: str) -> None:
|
|
65
|
+
"""Pruefung 45 (D-97): Der Bytecode des Kerns steht nicht in der Versionierung."""
|
|
66
|
+
# --- Gegenstand 1: die Regel ---------------------------------------------------
|
|
67
|
+
pfad = os.path.join(root, ".gitignore")
|
|
68
|
+
if not os.path.exists(pfad):
|
|
69
|
+
warn(".gitignore: nicht vorhanden. Prüfung 45 kann die Regel gegen den Bytecode "
|
|
70
|
+
"des Kerns nicht prüfen. Versioniert dieses Projekt, gehört `__pycache__/` "
|
|
71
|
+
"dort hinein – die Python-Werkzeuge des Kerns erzeugen bei jedem Lauf "
|
|
72
|
+
"Bytecode unter " + KERN + "/ (D-97)")
|
|
73
|
+
else:
|
|
74
|
+
zeilen = [z.strip() for z in read(pfad).splitlines()]
|
|
75
|
+
if not any(z in GITIGNORE_DECKUNG for z in zeilen):
|
|
76
|
+
err(f".gitignore: deckt den Bytecode des Kerns nicht ab. Die Python-Werkzeuge "
|
|
77
|
+
f"unter {KERN}/ erzeugen bei jedem Lauf `.pyc`-Dateien; versioniert, "
|
|
78
|
+
f"ändern sie sich mit jedem Lauf und überleben den Kern, aus dem sie "
|
|
79
|
+
f"entstanden sind. Eine dieser Zeilen gehört in die Datei: "
|
|
80
|
+
f"{', '.join('`%s`' % m for m in GITIGNORE_DECKUNG)} "
|
|
81
|
+
f"(docs/ADOPTION_GUIDE.md Abschnitt 2, D-97)")
|
|
82
|
+
|
|
83
|
+
# --- Gegenstand 2: der Bestand ---------------------------------------------------
|
|
84
|
+
verfolgt = _verfolgte_dateien(root)
|
|
85
|
+
if verfolgt is None:
|
|
86
|
+
warn(f"Gegenstand 2 der Prüfung 45 ist nicht gelaufen – git ist nicht erreichbar "
|
|
87
|
+
f"oder {root} ist kein Repositorium. Ob unter {KERN}/ Bytecode versioniert "
|
|
88
|
+
f"ist, sagt dieser Lauf damit **nicht**; die Regel in der .gitignore allein "
|
|
89
|
+
f"entfernt bereits verfolgte Dateien nicht (D-97)")
|
|
90
|
+
return
|
|
91
|
+
bytecode = sorted(p for p in verfolgt
|
|
92
|
+
if p.endswith(".pyc") or BYTECODE_MARKER in p)
|
|
93
|
+
if bytecode:
|
|
94
|
+
gezeigt = ", ".join(bytecode[:4]) + (" …" if len(bytecode) > 4 else "")
|
|
95
|
+
err(f"{len(bytecode)} Bytecode-Datei(en) unter {KERN}/ sind versioniert: "
|
|
96
|
+
f"{gezeigt}. **Die Regel in der .gitignore entfernt sie nicht** – git liest "
|
|
97
|
+
f"sie für bereits verfolgte Dateien nicht. Der Weg ist "
|
|
98
|
+
f"`git rm -r --cached {KERN}/**/__pycache__` und danach die Regel (D-97)")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# --- 45, Gegenstand 3: Die Erzeugnisse der Packs im Quellrepositorium (D-383, K-124) --
|
|
103
|
+
#
|
|
104
|
+
# Im Quellrepositorium sind Wurzel-Anweisungsdatei, Laufzeitschicht und Overlay
|
|
105
|
+
# ERZEUGNISSE von install.py und werden nicht versioniert (README, Abschnitt "Arbeiten an
|
|
106
|
+
# diesem Repository"). Bis 1.9.0 schloss die .gitignore nur die Erzeugnisse EINES Packs
|
|
107
|
+
# aus; nach `install.py --client` mit einem der anderen beiden waeren deren Dateien
|
|
108
|
+
# versionierbar gewesen (K-124).
|
|
109
|
+
#
|
|
110
|
+
# ABGELEITET, NICHT AUFGEZAEHLT: Was ein Pack in die Wurzel schreibt, steht in seinem
|
|
111
|
+
# Manifest (shared_core, shared_seed). Verlangt wird je Ziel der erste Pfadbestandteil
|
|
112
|
+
# (unter .koolie/ die ersten zwei - der Kern selbst ist versioniert). Ein neues Pack
|
|
113
|
+
# bringt seine Zeilen damit als Befund mit, statt still versionierbar zu sein.
|
|
114
|
+
# Nur im Quellrepositorium: In einem Projekt gilt das Gegenteil (D-383).
|
|
115
|
+
GITIGNORE_ERZEUGNIS_LISTEN = ("shared_core", "shared_seed")
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _erzeugnis_wurzeln(root: str) -> dict:
|
|
119
|
+
"""{Wurzelbestandteil: [Packs]} aller Ziele, die install.py im Quellrepositorium anlegt."""
|
|
120
|
+
kern = os.path.join(root, KERN)
|
|
121
|
+
if kern not in sys.path:
|
|
122
|
+
sys.path.insert(0, kern)
|
|
123
|
+
try:
|
|
124
|
+
import clientmap
|
|
125
|
+
except ImportError:
|
|
126
|
+
warn("clientmap.py nicht gefunden – Gegenstand 3 der Prüfung 45 ist nicht "
|
|
127
|
+
"gelaufen (D-383)")
|
|
128
|
+
return {}
|
|
129
|
+
wurzeln: dict = {}
|
|
130
|
+
clients = os.path.join(root, KERN, "clients")
|
|
131
|
+
for pack in sorted(os.listdir(clients)):
|
|
132
|
+
pfad = os.path.join(clients, pack, "manifest.json")
|
|
133
|
+
if pack.startswith("_") or not os.path.isfile(pfad):
|
|
134
|
+
continue
|
|
135
|
+
man = json.loads(read(pfad))
|
|
136
|
+
for liste in GITIGNORE_ERZEUGNIS_LISTEN:
|
|
137
|
+
for eintrag in man.get(liste, []):
|
|
138
|
+
ziel = clientmap.resolve_placeholders(eintrag["dst"], man).strip("/")
|
|
139
|
+
teile = ziel.split("/")
|
|
140
|
+
if teile[0] == ".koolie":
|
|
141
|
+
if len(teile) < 2 or teile[1] == "core":
|
|
142
|
+
continue
|
|
143
|
+
teile = teile[:2]
|
|
144
|
+
else:
|
|
145
|
+
teile = teile[:1]
|
|
146
|
+
wurzeln.setdefault("/".join(teile), []).append(pack)
|
|
147
|
+
return wurzeln
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def check_gitignore_erzeugnisse(root: str) -> None:
|
|
151
|
+
"""Pruefung 45, Gegenstand 3 (D-383): Die .gitignore des Quellrepositoriums schliesst
|
|
152
|
+
die Wurzelerzeugnisse jedes Packs aus."""
|
|
153
|
+
if not ist_quellrepositorium(root):
|
|
154
|
+
return
|
|
155
|
+
pfad = os.path.join(root, ".gitignore")
|
|
156
|
+
if not os.path.isfile(pfad):
|
|
157
|
+
return # Gegenstand 1 meldet die fehlende Datei
|
|
158
|
+
zeilen = {z.strip().strip("/") for z in read(pfad).splitlines()
|
|
159
|
+
if z.strip() and not z.strip().startswith(("#", "!"))}
|
|
160
|
+
for wurzel, packs in sorted(_erzeugnis_wurzeln(root).items()):
|
|
161
|
+
if wurzel not in zeilen:
|
|
162
|
+
err(f".gitignore: schließt das Erzeugnis `/{wurzel}` nicht aus "
|
|
163
|
+
f"({', '.join(sorted(set(packs)))}). Im Quellrepositorium sind "
|
|
164
|
+
f"Wurzel-Anweisungsdatei, Laufzeitschicht und Overlay Erzeugnisse von "
|
|
165
|
+
f"install.py und werden nicht versioniert (Prüfung 45, D-383)")
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def check_lieferumfang(root: str) -> None:
|
|
169
|
+
"""Pruefung 90 (D-367): Die Angabe des Lieferumfangs stimmt."""
|
|
170
|
+
cm = _clientmap(root)
|
|
171
|
+
if cm is None:
|
|
172
|
+
return # ohne clientmap.py meldet Pruefung 1 die fehlende Pflichtdatei
|
|
173
|
+
kern = os.path.join(root, KERN)
|
|
174
|
+
datei = f"{KERN}/{cm.LIEFERUMFANG_DATEI}"
|
|
175
|
+
vorhanden = os.path.isfile(os.path.join(kern, cm.LIEFERUMFANG_DATEI))
|
|
176
|
+
if ist_quellrepositorium(root):
|
|
177
|
+
if vorhanden:
|
|
178
|
+
err(f"{datei}: liegt im Quellrepositorium. Die Datei schreibt install.py in "
|
|
179
|
+
f"ein Projekt; hier behauptete sie eine Installation, und eine Quelle mit "
|
|
180
|
+
f"'nutzung' lieferte keinen vollen Kern mehr (D-367)")
|
|
181
|
+
return
|
|
182
|
+
wert = cm.lieferumfang(kern)
|
|
183
|
+
if wert not in cm.LIEFERUMFAENGE:
|
|
184
|
+
err(f"{datei}: trägt '{wert}' – bekannt sind {', '.join(cm.LIEFERUMFAENGE)}. "
|
|
185
|
+
f"Das nächste Heben hält daran an (D-367)")
|
|
186
|
+
return
|
|
187
|
+
if wert != "nutzung":
|
|
188
|
+
return
|
|
189
|
+
da = [a for a in cm.NACHWEIS_ABLAGEN if os.path.exists(os.path.join(kern, *a.split("/")))]
|
|
190
|
+
if da:
|
|
191
|
+
err(f"{datei}: sagt 'nutzung', aber {', '.join(f'{KERN}/{a}/' for a in da)} "
|
|
192
|
+
f"liegt da. Das nächste Heben mit diesem Umfang löscht es; wer den ganzen "
|
|
193
|
+
f"Kern will, hebt mit --lieferumfang voll (D-367)")
|
|
194
|
+
return
|
|
195
|
+
hinweis(f"Lieferumfang 'nutzung' ({datei}): ohne die Nachweisschicht "
|
|
196
|
+
f"({', '.join(cm.NACHWEIS_ABLAGEN)}). Verweise dorthin sind Herkunftsangaben "
|
|
197
|
+
f"und werden nicht gemeldet; Belege stehen im Release-Archiv (D-367)")
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# --- Pruefung 68: Das Praefix, das mehr sperrt als sein Befehl ----------------------
|
|
201
|
+
#
|
|
202
|
+
# ANLASS, UND ER IST GEMESSEN. permissions.json fuehrt je exec-Regel einen `command`
|
|
203
|
+
# (die woertliche Form) und optional einen `prefix` (die Form fuer Clients, die ueber
|
|
204
|
+
# ein Praefix sperren). Ist der `prefix` kuerzer, sperrt die Regel MEHR, als ihr
|
|
205
|
+
# Befehl nennt. Am 2026-09-20 hat genau das gekostet: Der Eintrag mit dem command
|
|
206
|
+
# "git branch -D" traegt den prefix "git branch" und sperrt damit auch das blosse
|
|
207
|
+
# Auflisten. Gemessen ueber 50 Laeufe des vierten Testblattbuendels: 25 Abweisungen
|
|
208
|
+
# in 23 Laeufen, elf davon auf "git branch" - und zwei Skills schreiben in
|
|
209
|
+
# Arbeitsschritt 1 und in ihrer Fehlerbehandlung eine Kandidatenliste vorhandener
|
|
210
|
+
# Branches vor, die sie damit nicht liefern koennen (D-219).
|
|
211
|
+
#
|
|
212
|
+
# WARUM DIE SPERRE TROTZDEM BLEIBT, UND WARUM DAS EINE PRUEFUNG BRAUCHT. Der
|
|
213
|
+
# allow-Korb dieser Datei ist praefixbasiert, und clientmap.py verbietet dort ein
|
|
214
|
+
# kuerzeres Praefix als der Befehl ("bei allow waere das eine Lockerung"). Er traegt
|
|
215
|
+
# deshalb bisher ausschliesslich Verben OHNE schreibende Form - git status, diff,
|
|
216
|
+
# log, show, blame. `git branch` waere das erste mit einer. Die Uebererfassung ist
|
|
217
|
+
# hier also GEWOLLT; was fehlte, war, dass sie irgendwo steht. Eine Schranke, die
|
|
218
|
+
# mehr sperrt als sie sagt, ist die Schwester des wiederkehrenden Befundtyps dieses
|
|
219
|
+
# Projekts mit umgekehrtem Vorzeichen - und sie faellt niemandem auf, weil ein
|
|
220
|
+
# ueberschiessendes Verbot wie Sorgfalt aussieht.
|
|
221
|
+
#
|
|
222
|
+
# DER WAECHTER, DER ES NICHT SAH. clientmap.py prueft, ob der prefix ein Praefix des
|
|
223
|
+
# command IST - sonst waere die Praefixform "nicht nachweislich breiter als die
|
|
224
|
+
# woertliche". Er prueft die Richtung, nicht das Mass. Das ist D-205 an vierter
|
|
225
|
+
# Stelle: ein Muster, das seinen Gegenstand enthaelt und mehr.
|
|
226
|
+
#
|
|
227
|
+
# GRENZE, UND SIE STEHT HIER. Geprueft wird die NENNUNG, nicht ihre Richtigkeit: Eine
|
|
228
|
+
# Begruendung, die nicht traegt, laeuft durch - dieselbe Enthaltung, die Pruefung 65
|
|
229
|
+
# fuer den Protokollverweis zieht und Pruefung 61 fuer das Pruefmittelwort.
|
|
230
|
+
P68_FELD = "_uebererfasst"
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def check_praefix_uebererfassung(root: str) -> None:
|
|
234
|
+
"""Pruefung 68 (D-219): Ein Praefix, das mehr sperrt als sein Befehl, sagt es."""
|
|
235
|
+
rel = f"{KERN}/framework/runtime/permissions.json"
|
|
236
|
+
pfad = os.path.join(root, KERN, "framework", "runtime", "permissions.json")
|
|
237
|
+
if not os.path.isfile(pfad):
|
|
238
|
+
return # Pruefung 1 und 39 melden die fehlende Kernquelle bereits
|
|
239
|
+
try:
|
|
240
|
+
quelle = json.loads(read(pfad))
|
|
241
|
+
except ValueError:
|
|
242
|
+
return # Pruefung 39 meldet die unlesbare Datei bereits
|
|
243
|
+
exec_regeln = 0
|
|
244
|
+
for korb in ("deny", "ask", "allow"):
|
|
245
|
+
eintraege = quelle.get(korb)
|
|
246
|
+
if not isinstance(eintraege, list):
|
|
247
|
+
continue
|
|
248
|
+
for regel in eintraege:
|
|
249
|
+
if not isinstance(regel, dict) or regel.get("tool") != "exec":
|
|
250
|
+
continue
|
|
251
|
+
exec_regeln += 1
|
|
252
|
+
befehl = str(regel.get("command", "")).strip()
|
|
253
|
+
praefix = str(regel.get("prefix", befehl)).strip()
|
|
254
|
+
if not befehl or praefix == befehl:
|
|
255
|
+
continue
|
|
256
|
+
if str(regel.get(P68_FELD, "")).strip():
|
|
257
|
+
continue
|
|
258
|
+
err(f"{rel}: die {korb}-Regel `{befehl}` sperrt über das Präfix "
|
|
259
|
+
f"`{praefix}` mehr, als ihr Befehl nennt – und sagt es nicht. Ein "
|
|
260
|
+
f"Feld `{P68_FELD}` mit der Begründung gehört dazu: Genau diese "
|
|
261
|
+
f"Bauform hat am 2026-09-20 fünfundzwanzig Abweisungen erzeugt und "
|
|
262
|
+
f"zwei Skills eine Zusage unmöglich gemacht, die sie selbst "
|
|
263
|
+
f"vorschreiben. Eine Schranke, die mehr sperrt als sie sagt, ist "
|
|
264
|
+
f"nicht weniger ein Befund als eine, die weniger hält (D-219)")
|
|
265
|
+
if exec_regeln == 0:
|
|
266
|
+
err(f"{rel}: keine einzige exec-Regel gefunden – Prüfung 68 rechnet ihre "
|
|
267
|
+
f"Präfixe gegen ihre Befehle und hat ihren Gegenstand verloren; sie "
|
|
268
|
+
f"bestünde sonst leise (D-23)")
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
# --- Pruefung 69: Der Messapparat schreibt nicht in das Repositorium ----------------
|
|
272
|
+
#
|
|
273
|
+
# ANLASS, UND ER IST GEMESSEN - ER KOSTETE NICHTS, WEIL ER VOR DEM LAUF KAM. D-222
|
|
274
|
+
# hat die Skripte der Erhebungen mit 0.79.0 ins Repositorium geholt und ihre Belege
|
|
275
|
+
# ausdruecklich DRAUSSEN gelassen: "203 Dateien, darunter fuenfzig
|
|
276
|
+
# Sitzungstranskripte mit Werkzeugeingaben; sie sind AUFZEICHNUNG, nicht Anweisung".
|
|
277
|
+
# Fuenf dieser Skripte legten ihre Belege aber schlicht NEBEN SICH ab:
|
|
278
|
+
#
|
|
279
|
+
# BELEGE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "belege")
|
|
280
|
+
#
|
|
281
|
+
# Solange das Skript daneben lag, war das richtig. Seit es im Kern liegt, zeigt
|
|
282
|
+
# derselbe Ausdruck HINEIN - und lauf.py legt das Verzeichnis selbst an. Ein
|
|
283
|
+
# Nachlauf haette die Mitschriften seiner Laeufe versioniert, ohne dass jemand es
|
|
284
|
+
# entschieden haette. Gefunden am 2026-09-20 im Vorbedingungsdurchgang des
|
|
285
|
+
# Nachlaufs, vor dem ersten bezahlten Lauf.
|
|
286
|
+
#
|
|
287
|
+
# Wer einen Apparat umzieht, zieht seine relativen Pfade mit um - oder er
|
|
288
|
+
# verschiebt ihr Ziel, ohne es zu merken.
|
|
289
|
+
#
|
|
290
|
+
# WAS GEPRUEFT WIRD, UND WARUM SO. Nicht die Quelltexte (ein Zaehler, der Ausdruecke
|
|
291
|
+
# liest, prueft die Schreibweise statt der Sache, D-223), sondern das ERGEBNIS: In
|
|
292
|
+
# <CORE_DIR>/tests/erhebungen/ liegen Skripte und eine README - sonst nichts. Eine
|
|
293
|
+
# Belegdatei, eine Zustandsaufnahme oder ein Promptverzeichnis dort ist der Befund
|
|
294
|
+
# selbst, unabhaengig davon, welcher Ausdruck sie erzeugt hat.
|
|
295
|
+
#
|
|
296
|
+
# GRENZE, UND SIE STEHT HIER. Die Pruefung sieht nur, was schon geschrieben IST.
|
|
297
|
+
# Den Wächter davor traegt `ablage.py`: Er verlangt die Erhebungsablage als Angabe
|
|
298
|
+
# und weist einen Pfad im Repositorium ab. Zwei Haelften desselben Gegenstands -
|
|
299
|
+
# dieselbe Aufteilung wie bei D-205 zwischen Schnitt und Waechter.
|
|
300
|
+
#
|
|
301
|
+
# SEIT 1.19.0 EIN VERZEICHNIS, BENANNT (D-473): Der Messapparat ist ein Paket
|
|
302
|
+
# (`apparat/`). Zugelassen ist genau dieser Name, und darin nur Python-Quelltext - ein
|
|
303
|
+
# Beleg, eine Reihe oder ein Unterverzeichnis dort ist derselbe Befund wie daneben.
|
|
304
|
+
P69_ERLAUBT_DATEI = (".py", ".md")
|
|
305
|
+
P69_PAKETE = ("apparat",)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def _p69_paket_rest(pfad: str) -> list:
|
|
309
|
+
"""Was in einem zugelassenen Paket liegt und kein Python-Quelltext ist."""
|
|
310
|
+
rest = []
|
|
311
|
+
for name in sorted(os.listdir(pfad)):
|
|
312
|
+
voll = os.path.join(pfad, name)
|
|
313
|
+
if name == "__pycache__" and os.path.isdir(voll):
|
|
314
|
+
continue
|
|
315
|
+
if os.path.isdir(voll) or not name.endswith(".py"):
|
|
316
|
+
rest.append(name)
|
|
317
|
+
return rest
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def check_erhebungen_sauber(root: str) -> None:
|
|
321
|
+
"""Pruefung 69 (D-222): In der Erhebungsablage des Kerns liegen nur Werkzeuge."""
|
|
322
|
+
rel = f"{KERN}/tests/erhebungen"
|
|
323
|
+
ordner = os.path.join(root, KERN, "tests", "erhebungen")
|
|
324
|
+
if not os.path.isdir(ordner):
|
|
325
|
+
return # ein uebernehmendes Projekt bekommt diese Ablage nicht ausgeliefert
|
|
326
|
+
gesehen = 0
|
|
327
|
+
for name in sorted(os.listdir(ordner)):
|
|
328
|
+
pfad = os.path.join(ordner, name)
|
|
329
|
+
if os.path.isdir(pfad):
|
|
330
|
+
if name == "__pycache__":
|
|
331
|
+
continue
|
|
332
|
+
if name in P69_PAKETE:
|
|
333
|
+
for fremd in _p69_paket_rest(pfad):
|
|
334
|
+
err(f"{rel}/{name}/{fremd}: im Werkzeugpaket der Erhebungsablage des "
|
|
335
|
+
f"Kerns liegt nur Python-Quelltext - Belege, Reihen und Prompts sind "
|
|
336
|
+
f"Aufzeichnung und gehoeren neben das Repositorium (D-222, D-473)")
|
|
337
|
+
continue
|
|
338
|
+
err(f"{rel}/{name}/: ein VERZEICHNIS in der Erhebungsablage des Kerns. "
|
|
339
|
+
f"Hier liegen Werkzeuge; Belege, Prompts und Zustandsaufnahmen sind "
|
|
340
|
+
f"Aufzeichnung und gehoeren neben das Repositorium (D-222). Die "
|
|
341
|
+
f"Ablage wird ueber LW_ERHEBUNG gesagt, nicht abgeleitet")
|
|
342
|
+
continue
|
|
343
|
+
gesehen += 1
|
|
344
|
+
if not name.endswith(P69_ERLAUBT_DATEI):
|
|
345
|
+
err(f"{rel}/{name}: keine Datei der zugelassenen Art "
|
|
346
|
+
f"({', '.join(P69_ERLAUBT_DATEI)}) in der Erhebungsablage des "
|
|
347
|
+
f"Kerns. Eine Belegdatei, ein Ergebnis-JSON oder eine "
|
|
348
|
+
f"Zustandsaufnahme ist hier der Befund selbst - unabhaengig davon, "
|
|
349
|
+
f"welcher Ausdruck sie erzeugt hat (D-222)")
|
|
350
|
+
if gesehen == 0:
|
|
351
|
+
err(f"{rel}: kein einziges Werkzeug gefunden – Prüfung 69 zaehlt den Inhalt "
|
|
352
|
+
f"dieser Ablage und hat ihren Gegenstand verloren; sie bestuende sonst "
|
|
353
|
+
f"leise (D-23)")
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
# --- Pruefung 70: Jedes Werkzeug des Kerns nennt nur Namen, die es gibt -------------
|
|
357
|
+
#
|
|
358
|
+
# ANLASS, UND ER IST GEMESSEN - ER KOSTETE NICHTS, WEIL ER VOR DEM LAUF KAM. Der
|
|
359
|
+
# Wiederaufnahmepunkt des halb gefahrenen Messtags fuehrte `stand-b4.py` als Befehl 1
|
|
360
|
+
# von 4 auf: das Skript, dessen Kopfkommentar sagt "EINE ZAHL IN EINER UEBERGABE IST
|
|
361
|
+
# EINE MOMENTAUFNAHME, DIESES SKRIPT IST DER STAND". Es brach beim Import ab:
|
|
362
|
+
#
|
|
363
|
+
# PROMPTS = os.path.join(os.path.dirname(S), "prompts")
|
|
364
|
+
#
|
|
365
|
+
# `S` trug bis D-222 den Ablageort NEBEN dem Skript. Der Umzug in den Kern hat ihn
|
|
366
|
+
# entfernt und zwei Lesestellen stehen lassen - eine im Modulrumpf, eine in `main()`.
|
|
367
|
+
# Seit 0.79.0 war das Werkzeug damit tot, und der Befund lag genau auf dem Weg der
|
|
368
|
+
# Wiederaufnahme. Gefunden am 2026-09-21, vor dem ersten bezahlten Kontrollauf.
|
|
369
|
+
#
|
|
370
|
+
# Ein Werkzeug, das niemand faehrt, verfaellt lautlos - und der Tag, an dem es
|
|
371
|
+
# gebraucht wird, ist der Tag, an dem es fehlt.
|
|
372
|
+
#
|
|
373
|
+
# WARUM KEINE DER 69 ES SAH, UND DAS IST DER EIGENTLICHE BEFUND. Pruefung 45 prueft,
|
|
374
|
+
# dass KEIN Bytecode versioniert ist - also die Abwesenheit einer Datei. Pruefung 69
|
|
375
|
+
# prueft die ART der Dateien in der Erhebungsablage - .py und .md, sonst nichts. Der
|
|
376
|
+
# Apparat hatte damit zwei Waechter ueber seinen Ablageort und keinen einzigen
|
|
377
|
+
# darueber, ob seine Werkzeuge laufen.
|
|
378
|
+
#
|
|
379
|
+
# WAS GEPRUEFT WIRD, UND WARUM SO. Nicht `import` - das fuehrt den Modulrumpf aus,
|
|
380
|
+
# und Werkzeuge dieses Kerns brechen dabei mit Absicht ab (`ablage.py` ohne
|
|
381
|
+
# LW_ERHEBUNG), waehrend `lauf.py` sein Belegverzeichnis anlegen wuerde: genau das,
|
|
382
|
+
# was D-222 verworfen hat. Eine Pruefung, die ihren Gegenstand veraendert, misst ihn
|
|
383
|
+
# nicht. Geprueft wird deshalb die SYMBOLTABELLE, die der Interpreter selbst baut:
|
|
384
|
+
# Sie kennt jede Bindung und jeden Gueltigkeitsbereich - Modul, Funktion, Klasse,
|
|
385
|
+
# Komprehension - und sagt je Name, ob er zugewiesen, importiert, Parameter, frei
|
|
386
|
+
# oder global ist. Ein global gelesener Name, den weder der Modulrumpf noch die
|
|
387
|
+
# eingebauten Namen binden, ist ein NameError, der auf seinen Lauf wartet.
|
|
388
|
+
#
|
|
389
|
+
# GRENZE, UND SIE STEHT HIER. Geprueft wird der NAME, nicht der WERT. Wer `S = None`
|
|
390
|
+
# schreibt und `os.path.dirname(S)` aufruft, laeuft durch - dieselbe Enthaltung wie
|
|
391
|
+
# bei Pruefung 68. Und ein Lauf des Werkzeugs bliebe der staerkere Nachweis; er
|
|
392
|
+
# kostet Kontingent und legt Dateien an, diese Pruefung nicht.
|
|
393
|
+
P70_EINGEBAUT = frozenset(dir(builtins))
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def _p70_offene_namen(quelle: str, name: str) -> list:
|
|
397
|
+
"""Die global gelesenen Namen einer Quelle, die nirgends gebunden sind."""
|
|
398
|
+
top = symtable.symtable(quelle, name, "exec")
|
|
399
|
+
modul = {sym.get_name() for sym in top.get_symbols()
|
|
400
|
+
if sym.is_assigned() or sym.is_imported() or sym.is_parameter()}
|
|
401
|
+
offen = []
|
|
402
|
+
|
|
403
|
+
def geh(tab) -> None:
|
|
404
|
+
for sym in tab.get_symbols():
|
|
405
|
+
n = sym.get_name()
|
|
406
|
+
if not sym.is_referenced():
|
|
407
|
+
continue
|
|
408
|
+
if sym.is_assigned() or sym.is_imported() or sym.is_parameter():
|
|
409
|
+
continue
|
|
410
|
+
# Die Modulglobalen, die der Interpreter selbst setzt (__file__,
|
|
411
|
+
# __name__, und was eine Python-Fassung sonst hinzufuegt). Ohne diese
|
|
412
|
+
# Ausnahme meldete die Pruefung zwoelf Werkzeuge dieses Kerns, und alle
|
|
413
|
+
# zwoelf laufen - ein Waechter, der bei jedem Lauf meldet, wird
|
|
414
|
+
# abgeschaltet.
|
|
415
|
+
if n.startswith("__") and n.endswith("__"):
|
|
416
|
+
continue
|
|
417
|
+
if n in P70_EINGEBAUT or n in modul:
|
|
418
|
+
continue
|
|
419
|
+
# Nur, was im Modulrumpf steht oder ausdruecklich global gelesen wird.
|
|
420
|
+
# Eine freie Variable aus einer umschliessenden Funktion ist gebunden,
|
|
421
|
+
# nur nicht hier - `is_global()` unterscheidet das.
|
|
422
|
+
if tab is top or sym.is_global():
|
|
423
|
+
offen.append((tab.get_name(), n))
|
|
424
|
+
for kind in tab.get_children():
|
|
425
|
+
geh(kind)
|
|
426
|
+
|
|
427
|
+
geh(top)
|
|
428
|
+
return offen
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def check_werkzeugnamen(root: str) -> None:
|
|
432
|
+
"""Pruefung 70 (D-229): Kein Werkzeug des Kerns liest einen Namen, den es nicht gibt."""
|
|
433
|
+
kern = os.path.join(root, KERN)
|
|
434
|
+
if not os.path.isdir(kern):
|
|
435
|
+
return
|
|
436
|
+
apparat = os.path.join(kern, "tests", "erhebungen")
|
|
437
|
+
im_apparat = 0
|
|
438
|
+
for basis, ordner, dateien in os.walk(kern):
|
|
439
|
+
ordner[:] = [o for o in ordner if o != "__pycache__"]
|
|
440
|
+
for name in sorted(dateien):
|
|
441
|
+
if not name.endswith(".py"):
|
|
442
|
+
continue
|
|
443
|
+
pfad = os.path.join(basis, name)
|
|
444
|
+
rel = os.path.relpath(pfad, root).replace(os.sep, "/")
|
|
445
|
+
if basis == apparat:
|
|
446
|
+
im_apparat += 1
|
|
447
|
+
try:
|
|
448
|
+
with open(pfad, encoding="utf-8") as f:
|
|
449
|
+
quelle = f.read()
|
|
450
|
+
except (OSError, UnicodeDecodeError) as e:
|
|
451
|
+
err(f"{rel}: nicht lesbar ({e}) - ein Werkzeug des Kerns, das sich "
|
|
452
|
+
f"nicht lesen laesst, laeuft auch nicht (D-229)")
|
|
453
|
+
continue
|
|
454
|
+
try:
|
|
455
|
+
offen = _p70_offene_namen(quelle, name)
|
|
456
|
+
except SyntaxError as e:
|
|
457
|
+
err(f"{rel}: laedt nicht - {e.msg} (Zeile {e.lineno}). Ein Werkzeug "
|
|
458
|
+
f"des Kerns, das der Interpreter nicht uebersetzt, ist tot, und "
|
|
459
|
+
f"es faellt erst an dem Tag auf, an dem es gebraucht wird (D-229)")
|
|
460
|
+
continue
|
|
461
|
+
for bereich, offener in offen:
|
|
462
|
+
wo = "im Modulrumpf" if bereich == name else f"in `{bereich}`"
|
|
463
|
+
err(f"{rel}: der Name `{offener}` wird {wo} gelesen und nirgends "
|
|
464
|
+
f"gebunden - weder als Zuweisung noch als Import, Parameter "
|
|
465
|
+
f"oder eingebauter Name. Das ist ein NameError, der auf seinen "
|
|
466
|
+
f"Lauf wartet; genau so war `stand-b4.py` seit dem Umzug nach "
|
|
467
|
+
f"D-222 tot (D-229)")
|
|
468
|
+
# DER ANKER, UND ER HAENGT AM MESSAPPARAT, NICHT AM KERN. Ein Anker `keine
|
|
469
|
+
# einzige .py-Datei im Kern` waere durch Konstruktion nie erreichbar: Dieses
|
|
470
|
+
# Skript ist selbst eine, und ohne es laeuft keine Pruefung. Eine Null durch
|
|
471
|
+
# Konstruktion sieht aus wie eine gemessene Null (0.59.1). Erreichbar - und der
|
|
472
|
+
# Gegenstand, um den es geht - ist der Messapparat: Steht seine Ablage und ist
|
|
473
|
+
# kein Werkzeug mehr darin, hat diese Pruefung den Anlass verloren, aus dem sie
|
|
474
|
+
# entstanden ist, und bestuende leise.
|
|
475
|
+
if os.path.isdir(apparat) and im_apparat == 0:
|
|
476
|
+
err(f"{KERN}/tests/erhebungen/: kein einziges Werkzeug geprueft - Pruefung "
|
|
477
|
+
f"70 hat den Gegenstand verloren, aus dem sie entstanden ist; sie "
|
|
478
|
+
f"bestuende sonst leise (D-23, D-229)")
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
# --- Pruefung 71: Kein Traeger des Kerns nennt einen Arbeitsplatz -------------------
|
|
482
|
+
#
|
|
483
|
+
# ANLASS, UND ER IST GEMESSEN. Am 2026-09-21, beim Bauen der Dossiers des Nachlaufs,
|
|
484
|
+
# brach `dossier-b4.py` ab - und im selben Blick fiel auf, was in seiner Zeile 33 stand:
|
|
485
|
+
#
|
|
486
|
+
# KERN = os.path.join(r"C:\Users\<konto>\Documents\devpacks\koolie", ...)
|
|
487
|
+
#
|
|
488
|
+
# Neun Werkzeuge des Messapparats fuehrten einen Pfad dieses Arbeitsplatzes, acht davon
|
|
489
|
+
# mit dem Ziel `...\devpacks\test-devin-framework`. Solange der Apparat NEBEN dem
|
|
490
|
+
# Repositorium lag, stand das in einer unversionierten Ablage. Mit D-222 ist er
|
|
491
|
+
# HINEINgewandert und hat die Pfade mitgebracht - in dasselbe Repositorium, fuer das
|
|
492
|
+
# `0.78.1` eigens `UEBERGABE.local.md` eingefuehrt hat, weil eine Uebergabe mit
|
|
493
|
+
# Servername und Konto den Validator mit drei Fehlern und drei Warnungen beantwortet.
|
|
494
|
+
#
|
|
495
|
+
# Wer einen Apparat umzieht, zieht seine Arbeitsplatzpfade mit um - und
|
|
496
|
+
# veroeffentlicht sie, ohne es zu entscheiden.
|
|
497
|
+
#
|
|
498
|
+
# WARUM KEINE DER SIEBZIG ES SAH. Pruefung 6 kennt Secret-Muster, E-Mail-Adressen,
|
|
499
|
+
# IP-Adressen, interne Hostnamen und URLs ausserhalb der Allowlist. Ein Pfad in ein
|
|
500
|
+
# Benutzerprofil ist nichts davon - und er traegt trotzdem den Namen eines Menschen.
|
|
501
|
+
#
|
|
502
|
+
# WAS GEPRUEFT WIRD, UND WARUM SO. Ein absoluter Pfad in ein Benutzerprofil, dessen
|
|
503
|
+
# Kontosegment KEIN Platzhalter ist. `<KONTO>`, `%USERNAME%` und `$HOME` laufen durch -
|
|
504
|
+
# sie nennen niemanden. Eine Zeile mit der Marke `SYNTHETISCH` laeuft ebenso durch:
|
|
505
|
+
# Dieselbe Bauform wie das Feld `_uebererfasst` von Pruefung 68 - wer einen solchen
|
|
506
|
+
# Pfad braucht, sagt es in derselben Zeile, statt dass die Pruefung raet.
|
|
507
|
+
#
|
|
508
|
+
# GRENZE, UND SIE STEHT HIER: DER BESTAND DER AUFZEICHNUNGEN IST AUSGENOMMEN, NICHT DIE
|
|
509
|
+
# GATTUNG (seit 1.20.3, D-508, `K-85`). `tests/protocols/` und
|
|
510
|
+
# `governance/change-requests/` halten fest, WO gemessen wurde; ein Protokoll, das man
|
|
511
|
+
# umschreibt, ist keines mehr (D-141). Zehn von ihnen tragen den Kontonamen des Owners
|
|
512
|
+
# weiter, und dabei bleibt es - der Name steht nach D-323 ohnehin im Lizenzhinweis.
|
|
513
|
+
# Bis 1.20.2 nahm die Pruefung aber die ganzen beiden Ordner aus und liess damit jede
|
|
514
|
+
# KUENFTIGE Aufzeichnung ungeprueft. Seither ist die Ausnahme eine geschlossene Liste:
|
|
515
|
+
# Wer eine neue Aufzeichnung schreibt, schreibt `<konto>` oder die Marke.
|
|
516
|
+
P71_MUSTER = re.compile(
|
|
517
|
+
r"(?:[A-Za-z]:[\\/]{1,2}Users|/home|/Users)[\\/]{1,2}([A-Za-z0-9._-]+)")
|
|
518
|
+
P71_AUSNAHME_ORDNER = (f"{KERN}/tests/protocols/",
|
|
519
|
+
f"{KERN}/governance/change-requests/")
|
|
520
|
+
P71_BESTAND = frozenset(f"{KERN}/{rel}" for rel in (
|
|
521
|
+
"governance/change-requests/CR-2026-076-erster-sitzungstest.md",
|
|
522
|
+
"governance/change-requests/CR-2026-077-sitzungstest-schranken.md",
|
|
523
|
+
"tests/protocols/2026-09-11-erhebungen-K21-K26.md",
|
|
524
|
+
"tests/protocols/2026-09-13-B06-gegenpruefung.md",
|
|
525
|
+
"tests/protocols/2026-09-17-sitzungstest-pi-ds.md",
|
|
526
|
+
"tests/protocols/2026-09-17-sitzungstest-schranken.md",
|
|
527
|
+
"tests/protocols/2026-09-18-sitzungstest-5.md",
|
|
528
|
+
"tests/protocols/2026-09-18-sitzungstest-ne-sc.md",
|
|
529
|
+
"tests/protocols/2026-09-18-sitzungstest-pi-ds-2.md",
|
|
530
|
+
"tests/protocols/2026-09-19-testblaetter-buendel-1.md"))
|
|
531
|
+
P71_MARKE = "SYNTHETISCH"
|
|
532
|
+
# Die Selbstprobe des Musters: Ohne sie koennte ein Ausdruck, der nichts mehr trifft,
|
|
533
|
+
# still bestehen - eine Null durch Konstruktion sieht aus wie eine gemessene Null
|
|
534
|
+
# (0.59.1). Der Anker haengt deshalb am MUSTER, nicht am Bestand: Der Bestand kann
|
|
535
|
+
# nicht verschwinden, solange dieses Skript selbst im Kern liegt.
|
|
536
|
+
P71_SELBSTPROBE = ("C:" + chr(92) + "Users" + chr(92) + "kontoname" + chr(92) + "x", # SYNTHETISCH
|
|
537
|
+
"/home/kontoname/x", # SYNTHETISCH
|
|
538
|
+
"/Users/kontoname/x") # SYNTHETISCH
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
def check_arbeitsplatzpfad(root: str) -> None:
|
|
542
|
+
"""Pruefung 71 (D-231): Kein Traeger des Kerns nennt einen Arbeitsplatz."""
|
|
543
|
+
kern = os.path.join(root, KERN)
|
|
544
|
+
if not os.path.isdir(kern):
|
|
545
|
+
return
|
|
546
|
+
for probe in P71_SELBSTPROBE:
|
|
547
|
+
if not P71_MUSTER.search(probe):
|
|
548
|
+
err(f"Pruefung 71: das eigene Muster trifft {probe!r} nicht mehr - sie "
|
|
549
|
+
f"haette ihren Gegenstand verloren und bestuende leise (D-23, D-231)")
|
|
550
|
+
return
|
|
551
|
+
for pfad in iter_text_files(root):
|
|
552
|
+
rel = os.path.relpath(pfad, root).replace(os.sep, "/")
|
|
553
|
+
if not rel.startswith(f"{KERN}/"):
|
|
554
|
+
continue
|
|
555
|
+
if rel.startswith(P71_AUSNAHME_ORDNER) and rel in P71_BESTAND:
|
|
556
|
+
continue
|
|
557
|
+
text = read(pfad)
|
|
558
|
+
for zeile in text.splitlines():
|
|
559
|
+
if P71_MARKE in zeile:
|
|
560
|
+
continue
|
|
561
|
+
for m in P71_MUSTER.finditer(zeile):
|
|
562
|
+
konto = m.group(1)
|
|
563
|
+
# Ein Platzhalter nennt niemanden. Die drei Schreibweisen, die
|
|
564
|
+
# dieses Repositorium und die beiden Betriebssysteme kennen.
|
|
565
|
+
davor = zeile[:m.start(1)]
|
|
566
|
+
if (konto.startswith(("<", "%", "$"))
|
|
567
|
+
or davor.endswith(("<", "%", "$", "{"))
|
|
568
|
+
or konto.upper() in ("USER", "USERNAME", "USERPROFILE")):
|
|
569
|
+
continue
|
|
570
|
+
err(f"{rel}: der Pfad {m.group(0)!r} nennt ein Benutzerprofil mit "
|
|
571
|
+
f"dem Kontosegment {konto!r}. Ein Arbeitsplatz gehoert nicht in "
|
|
572
|
+
f"den Kern - der Ort wird gesagt (LW_ERHEBUNG, LW_UEBUNG) oder "
|
|
573
|
+
f"abgeleitet (ablage.WURZEL). Ein Platzhalter oder die Marke "
|
|
574
|
+
f"{P71_MARKE} in derselben Zeile laeuft durch (D-231)")
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
# --- Pruefung 76: Die Lage des Kerns steht an vier Stellen - und ueberall gleich ----
|
|
578
|
+
#
|
|
579
|
+
# ANLASS (D-299). Bis 0.87.0 war der Kern EIN Verzeichnissegment, und vier Werkzeuge
|
|
580
|
+
# haben <CORE_DIR> deshalb mit os.path.basename() aus dem eigenen Ort gebunden -
|
|
581
|
+
# install.py, build/assemble.py, dieser Validator und der Schutz-Hook. In install.py
|
|
582
|
+
# stand dabei woertlich, die Zeile stehe dort, "damit eine spaetere Umbenennung nur
|
|
583
|
+
# eine Stelle beruehrt". Sie haette die Umbenennung nicht ueberlebt: os.path.basename
|
|
584
|
+
# liefert fuer ".koolie/core" den Wert "core".
|
|
585
|
+
#
|
|
586
|
+
# WARUM DAS KEIN VALIDATORFEHLER GEWESEN WAERE: Dieser Validator bindet <CORE_DIR> an
|
|
587
|
+
# derselben Stelle auf dieselbe Weise. Er haette denselben falschen Wert eingesetzt wie
|
|
588
|
+
# install.py - und deshalb nichts gemeldet. Zwei Stellen, die einander decken (0.57.0),
|
|
589
|
+
# diesmal ueber Werkzeuggrenzen hinweg.
|
|
590
|
+
#
|
|
591
|
+
# ZWEI GEGENSTAENDE, und sie sind dieselbe Frage aus zwei Richtungen:
|
|
592
|
+
# (1) Alle vier Angaben der Lage tragen denselben Wert.
|
|
593
|
+
# (2) Keine von ihnen leitet ihn ueber os.path.basename ab.
|
|
594
|
+
# Ohne (2) waere (1) erfuellbar, indem alle vier denselben Fehler machen - und genau
|
|
595
|
+
# das war der Zustand bis 0.87.0.
|
|
596
|
+
#
|
|
597
|
+
# WARUM VIER STELLEN UND NICHT EINE: Der Schutz-Hook darf nichts aus dem Kern
|
|
598
|
+
# importieren - er muss auch dann entscheiden, wenn eine Installation unvollstaendig
|
|
599
|
+
# ist (D-31). ablage.py laeuft ausserhalb des Kerns gegen fremde Messbaeume. Die
|
|
600
|
+
# Doppelung ist gewollt; diese Pruefung ist ihr Preis.
|
|
601
|
+
P76_WERT_RE = re.compile(r"^(?:CORE_REL|KERN)\s*=\s*\"([^\"]+)\"", re.M)
|
|
602
|
+
|
|
603
|
+
P76_STELLEN = (
|
|
604
|
+
"clientmap.py",
|
|
605
|
+
"tests/scripts/pruefungen/gemeinsam.py",
|
|
606
|
+
"tests/scripts/hook-check-secrets.py",
|
|
607
|
+
"tests/erhebungen/ablage.py",
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
P76_BASENAME_RE = re.compile(r"<CORE_DIR>\"\]\s*=\s*os\.path\.basename")
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
def check_kernlage(root: str) -> None:
|
|
614
|
+
"""Pruefung 76 (D-299): Die Lage des Kerns steht ueberall gleich - und nirgends
|
|
615
|
+
als basename eines Pfades."""
|
|
616
|
+
if not P76_WERT_RE.search("CORE_REL = \"x/y\"\n"):
|
|
617
|
+
err("Prüfung 76: das eigene Muster liest keine Lageangabe mehr – sie bestünde "
|
|
618
|
+
"leise, während die vier Werkzeuge auseinanderlaufen (D-23)")
|
|
619
|
+
return
|
|
620
|
+
werte = {}
|
|
621
|
+
for rel in P76_STELLEN:
|
|
622
|
+
pfad = os.path.join(root, KERN, *rel.split("/"))
|
|
623
|
+
if not os.path.isfile(pfad) and nicht_geliefert(root, f"{KERN}/{rel}"):
|
|
624
|
+
hinweis(f"Prüfung 76 hält die Kernlage an drei statt vier Stellen: "
|
|
625
|
+
f"{KERN}/{rel} gehört zur Nachweisschicht und ist nicht geliefert (D-367)")
|
|
626
|
+
continue
|
|
627
|
+
if not os.path.isfile(pfad):
|
|
628
|
+
err(f"{KERN}/{rel}: fehlt – Prüfung 76 hätte dort einen ihrer vier "
|
|
629
|
+
f"Gegenstände verloren (D-23)")
|
|
630
|
+
continue
|
|
631
|
+
text = read(pfad)
|
|
632
|
+
treffer = P76_WERT_RE.search(text)
|
|
633
|
+
if not treffer:
|
|
634
|
+
err(f"{KERN}/{rel}: führt keine Angabe der Kernlage mehr. Prüfung 76 hat "
|
|
635
|
+
f"dort ihren Anker verloren und bestünde sonst leise (D-23)")
|
|
636
|
+
else:
|
|
637
|
+
werte[rel] = treffer.group(1)
|
|
638
|
+
if P76_BASENAME_RE.search(text):
|
|
639
|
+
err(f"{KERN}/{rel}: bindet <CORE_DIR> über os.path.basename(). Der Kern "
|
|
640
|
+
f"liegt seit 0.88.0 zwei Segmente tief; basename() liefert davon nur "
|
|
641
|
+
f"das letzte, und jede gerenderte Regeldatei trüge einen Pfad, den es "
|
|
642
|
+
f"nicht gibt – ohne dass eine Prüfung es meldete (D-299)")
|
|
643
|
+
if len(set(werte.values())) > 1:
|
|
644
|
+
zeilen = ", ".join(f"{r} = '{w}'" for r, w in sorted(werte.items()))
|
|
645
|
+
err(f"Die Lage des Kerns steht in {len(werte)} Werkzeugen und nicht überall "
|
|
646
|
+
f"gleich: {zeilen}. Eine Installation läge dann je nach aufrufendem "
|
|
647
|
+
f"Werkzeug an einem anderen Ort (D-299)")
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
# ---------------------------------------------------------------------------
|
|
651
|
+
# Pruefung 104: Die Verdrahtung der Pruefwerkzeuge (CR-2026-161, D-481)
|
|
652
|
+
# ---------------------------------------------------------------------------
|
|
653
|
+
#
|
|
654
|
+
# ANLASS. Seit 1.19.1 liegen die Pruefungen in einem Paket, und der Einstieg ruft sie;
|
|
655
|
+
# die Sonden liegen in Teilen, die der Einstieg des Sondenlaufs laedt (D-479). Eine
|
|
656
|
+
# Pruefung, die in ein Modul wandert und von niemandem gerufen wird, laeuft nie - und
|
|
657
|
+
# der Lauf endet mit "0 Fehler". Ein Sondenteil, den niemand laedt, meldet seine
|
|
658
|
+
# Einheiten nie an - und der Sondenlauf endet mit "alle bestanden". Beides ist die
|
|
659
|
+
# Null durch Konstruktion (0.59.1).
|
|
660
|
+
#
|
|
661
|
+
# WAS SIE PRUEFT, AM SYNTAXBAUM, OHNE ETWAS AUSZUFUEHREN:
|
|
662
|
+
# (1) Jede Funktion check_* der obersten Ebene eines Moduls unter pruefungen/ wird
|
|
663
|
+
# gerufen - von main() im Einstieg oder von einer anderen Funktion des Pakets
|
|
664
|
+
# (check_skills ruft check_skills_in) -, und main() ruft keine zweimal und keine,
|
|
665
|
+
# die es nicht gibt.
|
|
666
|
+
# (2) Jeder Teil unter sonden/ wird vom Einstieg des Sondenlaufs geladen, und zwar in
|
|
667
|
+
# der Reihenfolge seiner Nummer: Die Reihenfolge des Ladens ist die der Ausgabe
|
|
668
|
+
# (D-49).
|
|
669
|
+
#
|
|
670
|
+
# GRENZE: Sie prueft die Verdrahtung, nicht, was eine Pruefung tut - das tun ihre
|
|
671
|
+
# Sonden. Sie sieht nur Funktionen mit dem Praefix check_ und Teile mit dem Praefix
|
|
672
|
+
# teil; eine Pruefung unter anderem Namen faellt durch.
|
|
673
|
+
P104_VALIDATOR = "tests/scripts/validate-framework.py"
|
|
674
|
+
P104_SONDEN = "tests/scripts/probe-pruefungen.py"
|
|
675
|
+
P104_TEIL_RE = re.compile(r"^teil(\d+)_\w+\.py$")
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
def _p104_baum(root: str, rel: str):
|
|
679
|
+
"""Der Syntaxbaum einer Datei unter dem Kern - oder None, dann ist gemeldet."""
|
|
680
|
+
pfad = os.path.join(root, KERN, *rel.split("/"))
|
|
681
|
+
if not os.path.isfile(pfad):
|
|
682
|
+
err(f"{KERN}/{rel}: fehlt - Pruefung 104 haelt dort die Verdrahtung der "
|
|
683
|
+
f"Pruefwerkzeuge (D-481)")
|
|
684
|
+
return None
|
|
685
|
+
try:
|
|
686
|
+
return ast.parse(read(pfad))
|
|
687
|
+
except SyntaxError as e:
|
|
688
|
+
err(f"{KERN}/{rel}: laedt nicht - {e.msg} (Zeile {e.lineno}); Pruefung 104 kann "
|
|
689
|
+
f"die Verdrahtung dort nicht lesen (D-481)")
|
|
690
|
+
return None
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
def _p104_aufrufe(knoten) -> dict:
|
|
694
|
+
"""{Name: Anzahl} der Aufrufe von check_* unterhalb eines Knotens."""
|
|
695
|
+
anzahl: dict = {}
|
|
696
|
+
for n in ast.walk(knoten):
|
|
697
|
+
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and \
|
|
698
|
+
n.func.id.startswith("check_"):
|
|
699
|
+
anzahl[n.func.id] = anzahl.get(n.func.id, 0) + 1
|
|
700
|
+
return anzahl
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
def check_verdrahtung(root: str) -> None:
|
|
704
|
+
"""Pruefung 104 (D-481): Jede Pruefung wird gerufen, jeder Sondenteil geladen."""
|
|
705
|
+
# --- Gegenstand 1: die Pruefungen -------------------------------------------------
|
|
706
|
+
einstieg = _p104_baum(root, P104_VALIDATOR)
|
|
707
|
+
paket = PAKET_JE_SKRIPT[P104_VALIDATOR]
|
|
708
|
+
ordner = os.path.join(root, KERN, *paket.split("/"))
|
|
709
|
+
definiert, im_paket = {}, {}
|
|
710
|
+
for name in sorted(os.listdir(ordner)) if os.path.isdir(ordner) else []:
|
|
711
|
+
if not name.endswith(".py"):
|
|
712
|
+
continue
|
|
713
|
+
modul = _p104_baum(root, f"{paket}/{name}")
|
|
714
|
+
if modul is None:
|
|
715
|
+
continue
|
|
716
|
+
for n in modul.body:
|
|
717
|
+
if isinstance(n, ast.FunctionDef) and n.name.startswith("check_"):
|
|
718
|
+
definiert[n.name] = f"{paket}/{name}"
|
|
719
|
+
for name_, zahl in _p104_aufrufe(modul).items():
|
|
720
|
+
im_paket[name_] = im_paket.get(name_, 0) + zahl
|
|
721
|
+
haupt = None if einstieg is None else next(
|
|
722
|
+
(n for n in einstieg.body if isinstance(n, ast.FunctionDef) and n.name == "main"),
|
|
723
|
+
None)
|
|
724
|
+
if not definiert or haupt is None:
|
|
725
|
+
err(f"Pruefung 104: {'keine Funktion check_* unter ' + KERN + '/' + paket + '/' if not definiert else 'keine Funktion main() in ' + KERN + '/' + P104_VALIDATOR} - "
|
|
726
|
+
f"sie hat ihren Gegenstand verloren und bestuende sonst leise (D-23, D-481)")
|
|
727
|
+
else:
|
|
728
|
+
in_main = _p104_aufrufe(haupt)
|
|
729
|
+
for name, wo in sorted(definiert.items()):
|
|
730
|
+
if not in_main.get(name) and not im_paket.get(name):
|
|
731
|
+
err(f"{KERN}/{wo}: {name}() wird von niemandem gerufen - weder von main() "
|
|
732
|
+
f"in {P104_VALIDATOR} noch im Paket. Eine Pruefung, die niemand ruft, "
|
|
733
|
+
f"laeuft nie, und der Lauf endet trotzdem mit 0 Fehlern (D-481)")
|
|
734
|
+
elif in_main.get(name, 0) > 1:
|
|
735
|
+
err(f"{KERN}/{P104_VALIDATOR}: main() ruft {name}() {in_main[name]}mal - "
|
|
736
|
+
f"jede Pruefung laeuft genau einmal, sonst meldet sie jeden Befund "
|
|
737
|
+
f"doppelt (D-481)")
|
|
738
|
+
for name in sorted(set(in_main) - set(definiert)):
|
|
739
|
+
err(f"{KERN}/{P104_VALIDATOR}: main() ruft {name}(), und kein Modul unter "
|
|
740
|
+
f"{paket}/ definiert sie (D-481)")
|
|
741
|
+
|
|
742
|
+
# --- Gegenstand 2: die Sondenteile ------------------------------------------------
|
|
743
|
+
einstieg = _p104_baum(root, P104_SONDEN)
|
|
744
|
+
paket = PAKET_JE_SKRIPT[P104_SONDEN]
|
|
745
|
+
ordner = os.path.join(root, KERN, *paket.split("/"))
|
|
746
|
+
teile = sorted((n[:-3] for n in (os.listdir(ordner) if os.path.isdir(ordner) else [])
|
|
747
|
+
if P104_TEIL_RE.match(n)),
|
|
748
|
+
key=lambda t: int(P104_TEIL_RE.match(t + ".py").group(1)))
|
|
749
|
+
if not teile:
|
|
750
|
+
err(f"Pruefung 104: kein Sondenteil teil<Nummer>_*.py unter {KERN}/{paket}/ - sie "
|
|
751
|
+
f"hat ihren Gegenstand verloren und bestuende sonst leise (D-23, D-481)")
|
|
752
|
+
return
|
|
753
|
+
if einstieg is None:
|
|
754
|
+
return
|
|
755
|
+
geladen = [a.name for n in einstieg.body if isinstance(n, ast.ImportFrom)
|
|
756
|
+
and n.module == os.path.basename(paket) for a in n.names]
|
|
757
|
+
for teil in teile:
|
|
758
|
+
if teil not in geladen:
|
|
759
|
+
err(f"{KERN}/{paket}/{teil}.py: wird von {P104_SONDEN} nicht geladen - seine "
|
|
760
|
+
f"Einheiten melden sich nie an, und der Sondenlauf endet trotzdem mit "
|
|
761
|
+
f"'alle bestanden' (D-481)")
|
|
762
|
+
for teil in geladen:
|
|
763
|
+
if teil not in teile:
|
|
764
|
+
err(f"{KERN}/{P104_SONDEN}: laedt {teil}, und unter {paket}/ gibt es keinen "
|
|
765
|
+
f"Teil dieses Namens (D-481)")
|
|
766
|
+
reihe = [t for t in geladen if t in teile]
|
|
767
|
+
if reihe != [t for t in teile if t in reihe]:
|
|
768
|
+
err(f"{KERN}/{P104_SONDEN}: laedt die Sondenteile nicht in der Reihenfolge ihrer "
|
|
769
|
+
f"Nummer. Die Reihenfolge des Ladens ist die Reihenfolge der Ausgabe, und die "
|
|
770
|
+
f"ist die zeilengleiche Abnahmeform (D-49, D-481)")
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
# Pruefung 107: Die Wirksamkeitsprobe haelt ihre Gegenfaelle (K-195, D-488, D-490).
|
|
774
|
+
#
|
|
775
|
+
# ANLASS. Die Hook-Vorpruefung des Messapparats hat seit 1.19.0 jeden Baum bestanden -
|
|
776
|
+
# auch einen ohne Hook-Skript: Unter Windows loeste 'cmd' $CLAUDE_PROJECT_DIR nicht auf,
|
|
777
|
+
# Python endete mit Exit 2, und Exit 2 galt als Sperre (D-490). Eine Probe, die auch das
|
|
778
|
+
# Fehlen ihres Gegenstands bestaetigt, ist die Null durch Konstruktion. Die Pruefung baut
|
|
779
|
+
# deshalb einen Wegwerfbaum mit der erzeugten Hook-Konfiguration von claude-code und
|
|
780
|
+
# verlangt von wirksamkeit.pruefe_hook drei Urteile:
|
|
781
|
+
# (a) intakter Baum: keine fehlende Muss-Kontrolle;
|
|
782
|
+
# (b) ohne Hook-Skript: H3 und H4 fehlen - Exit 2 ohne Sperrhinweis ist keine Sperre;
|
|
783
|
+
# (c) Matcher ohne die Klasse mcp: H2 fehlt.
|
|
784
|
+
# GRENZE: der Hook-Teil der Probe am Pack claude-code. Startmeldung und Vertrauen braucht
|
|
785
|
+
# einen Client und sind an der Messung belegt (Protokoll 2026-09-29-schutzschicht).
|
|
786
|
+
def check_wirksamkeitsprobe(root: str) -> None:
|
|
787
|
+
"""Pruefung 107 (K-195, D-488, D-490): Die Probe unterscheidet Wirkung von Fehlen."""
|
|
788
|
+
import importlib.util
|
|
789
|
+
import shutil
|
|
790
|
+
import tempfile
|
|
791
|
+
kern = os.path.join(root, *KERN.split("/"))
|
|
792
|
+
modul = os.path.join(kern, "wirksamkeit.py")
|
|
793
|
+
skript = os.path.join(kern, "tests", "scripts", "hook-check-secrets.py")
|
|
794
|
+
manifest = os.path.join(kern, "clients", "claude-code", "manifest.json")
|
|
795
|
+
if not all(os.path.isfile(p) for p in (modul, skript, manifest)):
|
|
796
|
+
return
|
|
797
|
+
try:
|
|
798
|
+
cm = _clientmap(root)
|
|
799
|
+
spec = importlib.util.spec_from_file_location("koolie_wirksamkeit_p107", modul)
|
|
800
|
+
wk = importlib.util.module_from_spec(spec)
|
|
801
|
+
spec.loader.exec_module(wk)
|
|
802
|
+
man = json.loads(read(manifest))
|
|
803
|
+
quelle = cm.load_source(kern, "hooks.json")
|
|
804
|
+
hooks = cm._hooks_objekt(quelle, man)
|
|
805
|
+
verben = [v for e in json.loads(quelle).get("PreToolUse", []) for v in e.get("on", [])
|
|
806
|
+
if any(h.get("enforcing") for h in e.get("hooks", []))]
|
|
807
|
+
except Exception as fehler: # noqa: BLE001 - jeder Ladefehler ist der Befund
|
|
808
|
+
err(f"Pruefung 107: Die Wirksamkeitsprobe laesst sich nicht laden "
|
|
809
|
+
f"({type(fehler).__name__}) - install.py --probe liefe nicht (K-195)")
|
|
810
|
+
return
|
|
811
|
+
|
|
812
|
+
def urteil(ohne_skript: bool = False, matcher_ohne_mcp: bool = False) -> set:
|
|
813
|
+
with tempfile.TemporaryDirectory(prefix="koolie-p107-") as w:
|
|
814
|
+
ziel = os.path.join(w, *KERN.split("/"), "tests", "scripts")
|
|
815
|
+
os.makedirs(ziel)
|
|
816
|
+
if not ohne_skript:
|
|
817
|
+
shutil.copy2(skript, ziel)
|
|
818
|
+
pack = os.path.join(w, *KERN.split("/"), "clients", "claude-code")
|
|
819
|
+
os.makedirs(pack)
|
|
820
|
+
shutil.copy2(manifest, pack)
|
|
821
|
+
h = json.loads(json.dumps(hooks))
|
|
822
|
+
if matcher_ohne_mcp:
|
|
823
|
+
for e in h.get("PreToolUse", []):
|
|
824
|
+
e["matcher"] = "|".join(x for x in e["matcher"].split("|")
|
|
825
|
+
if not x.startswith("mcp"))
|
|
826
|
+
os.makedirs(os.path.join(w, ".claude"))
|
|
827
|
+
with open(os.path.join(w, ".claude", "settings.json"), "w", encoding="utf-8") as fh:
|
|
828
|
+
json.dump({"hooks": h}, fh)
|
|
829
|
+
with open(os.path.join(w, "README.md"), "w", encoding="utf-8") as fh:
|
|
830
|
+
fh.write("# Wegwerfbaum\n")
|
|
831
|
+
erg = wk.Ergebnis()
|
|
832
|
+
wk.pruefe_hook(w, man, verben, erg)
|
|
833
|
+
return {k.split()[0] for _, k, _ in erg.verletzt}
|
|
834
|
+
|
|
835
|
+
intakt = urteil()
|
|
836
|
+
if intakt:
|
|
837
|
+
err(f"Pruefung 107: Die Wirksamkeitsprobe meldet an einem intakten Baum fehlende "
|
|
838
|
+
f"Kontrollen ({', '.join(sorted(intakt))}) - sie truege keinen Befund (K-195)")
|
|
839
|
+
ohne = urteil(ohne_skript=True)
|
|
840
|
+
if not {"H3", "H4"} <= ohne:
|
|
841
|
+
err(f"Pruefung 107: Die Wirksamkeitsprobe besteht einen Baum ohne Hook-Skript "
|
|
842
|
+
f"(gemeldet: {', '.join(sorted(ohne)) or 'nichts'}) - ein Exit 2 ohne "
|
|
843
|
+
f"Sperrhinweis ist keine Sperre (D-490)")
|
|
844
|
+
alt = urteil(matcher_ohne_mcp=True)
|
|
845
|
+
if "H2" not in alt:
|
|
846
|
+
err("Pruefung 107: Die Wirksamkeitsprobe erkennt einen Matcher ohne die "
|
|
847
|
+
"Werkzeugklasse mcp nicht - ein veralteter Matcher fiele nicht auf (K-184, D-488)")
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
# --- Pruefung 112: Die Paketquellen und das Banner (CR-2026-168, D-518 bis D-521, K-155) --
|
|
851
|
+
#
|
|
852
|
+
# ANLASS, GEMESSEN (2026-09-30): Eine Paketquelle legt Koolie auf den Rechner, ins Projekt
|
|
853
|
+
# kommt es erst durch den Befehl `koolie` - und nur dieser Aufruf laeuft bei jeder
|
|
854
|
+
# Paketquelle im Terminal des Nutzers. pip fuehrt beim Installieren eines Wheels nichts
|
|
855
|
+
# aus, npm verschluckt die Ausgabe eines Installationsskripts, Chocolatey gibt ihm kein
|
|
856
|
+
# Terminal. Das Banner, das der Owner auf diesen Wegen verlangt, steht deshalb im Befehl
|
|
857
|
+
# (D-519), und die Pakete entstehen aus dem Release-Archiv mit paketquellen/bauen.py
|
|
858
|
+
# (D-520). Beides kann still brechen: ein Befehl, der install.py ohne Banner startet, und
|
|
859
|
+
# ein Bau, dessen Paket auf eine Datei zeigt, die es nicht traegt.
|
|
860
|
+
#
|
|
861
|
+
# GEPRUEFT, nur im Quellrepositorium (Projekte bekommen paketquellen/ nicht):
|
|
862
|
+
# (a) die vier Dateien unter paketquellen/ liegen da;
|
|
863
|
+
# (b) der Befehl: `--version` nennt die Version aus VERSION; ueber eine Pipe steht vor
|
|
864
|
+
# der Ausgabe von install.py die Textvariante des Banners mit dieser Version; mit
|
|
865
|
+
# KOOLIE_NO_BANNER=1 steht sie nicht da; ohne Argumente nimmt der Dialog das
|
|
866
|
+
# Verzeichnis des Aufrufs mit Enter als Projekt (seit 1.24.1, D-532);
|
|
867
|
+
# (c) der Bau: bauen.py baut aus einem Wegwerfarchiv mit den Dateien unter
|
|
868
|
+
# paketquellen/ ohne Befund - seine Nachpruefung haelt Dateimenge, Version, RECORD,
|
|
869
|
+
# die Ziele der Befehle, das Fehlen eines npm-Installationsskripts und die
|
|
870
|
+
# Pruefsumme in beiden Manifesten; seit 1.24.0 auch die Beschreibung fuer PyPI und
|
|
871
|
+
# npm ohne relativen Link (D-528) - und dasselbe fuer die Vorabversion --vorab 1 (D-529).
|
|
872
|
+
# GRENZE: Ob eine Paketquelle dem Befehl ein Terminal gibt, prueft keine Pruefung - das ist
|
|
873
|
+
# gemessen (Protokoll 2026-09-30-paketquellen: pip, uv, npm, Scoop). Die Homebrew-Formel ist
|
|
874
|
+
# gebaut, nicht gemessen. Die Veroeffentlichung erreicht keine Pruefung (D-521); ob die
|
|
875
|
+
# Paketseite die Beschreibung darstellt, ist gemessen (Protokoll 2026-10-01-erste-veroeffentlichung).
|
|
876
|
+
P112_DATEIEN = ("paketquellen/bauen.py", "paketquellen/koolie_befehl.py",
|
|
877
|
+
"paketquellen/koolie.cmd", "paketquellen/npm/koolie.js")
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
def _p112_befehl(root: str, *argv: str, ohne_banner: bool = False, cwd: str | None = None,
|
|
881
|
+
eingabe: str | None = None) -> str:
|
|
882
|
+
import subprocess
|
|
883
|
+
umgebung = {k: v for k, v in os.environ.items()
|
|
884
|
+
if k not in ("KOOLIE_NO_BANNER", "NO_COLOR", "COLUMNS")}
|
|
885
|
+
umgebung["PYTHONIOENCODING"] = "utf-8"
|
|
886
|
+
if ohne_banner:
|
|
887
|
+
umgebung["KOOLIE_NO_BANNER"] = "1"
|
|
888
|
+
p = subprocess.run([sys.executable, os.path.join(root, "paketquellen", "koolie_befehl.py"),
|
|
889
|
+
*argv], capture_output=True, encoding="utf-8", errors="replace",
|
|
890
|
+
env=umgebung, timeout=120, cwd=cwd, input=eingabe)
|
|
891
|
+
return p.stdout or ""
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
def check_paketquellen(root: str) -> None:
|
|
895
|
+
"""Pruefung 112 (D-519, D-520, K-155): Der Befehl gibt das Banner aus, der Bau traegt."""
|
|
896
|
+
if not ist_quellrepositorium(root):
|
|
897
|
+
return
|
|
898
|
+
fehlend = [rel for rel in P112_DATEIEN if not os.path.isfile(os.path.join(root, *rel.split("/")))]
|
|
899
|
+
if fehlend:
|
|
900
|
+
err(f"{fehlend[0]}: fehlt - ohne diese Datei baut keine Paketquelle den Befehl "
|
|
901
|
+
f"'koolie' (Pruefung 112, D-520)")
|
|
902
|
+
return
|
|
903
|
+
version = read(os.path.join(root, *KERN.split("/"), "VERSION")).strip()
|
|
904
|
+
try:
|
|
905
|
+
aus = _p112_befehl(root, "--version")
|
|
906
|
+
if aus.strip() != f"koolie {version}":
|
|
907
|
+
err(f"paketquellen/koolie_befehl.py: '--version' liefert {aus.strip()[:40]!r} statt "
|
|
908
|
+
f"'koolie {version}' (Pruefung 112)")
|
|
909
|
+
aus = _p112_befehl(root, "--help")
|
|
910
|
+
b, u = aus.find(f"KOOLIE v{version}"), aus.find("usage:")
|
|
911
|
+
if b < 0 or u < 0 or b > u:
|
|
912
|
+
err("paketquellen/koolie_befehl.py: startet install.py ohne das Banner davor - auf "
|
|
913
|
+
"den Wegen der Paketquellen erschiene es nicht (Pruefung 112, D-519)")
|
|
914
|
+
aus = _p112_befehl(root, "--help", ohne_banner=True)
|
|
915
|
+
if "KOOLIE v" in aus or "usage:" not in aus:
|
|
916
|
+
err("paketquellen/koolie_befehl.py: KOOLIE_NO_BANNER=1 schaltet das Banner nicht ab "
|
|
917
|
+
"oder unterdrueckt install.py mit (Pruefung 112, D-506)")
|
|
918
|
+
import tempfile as _tf
|
|
919
|
+
with _tf.TemporaryDirectory(prefix="koolie-p112-hier-") as hier:
|
|
920
|
+
aus = _p112_befehl(root, ohne_banner=True, cwd=hier, eingabe="\nq\n")
|
|
921
|
+
if "Welcher KI-Client" not in aus:
|
|
922
|
+
err("paketquellen/koolie_befehl.py: der Dialog nimmt das Verzeichnis des Aufrufs "
|
|
923
|
+
"nicht mit Enter als Projekt - uvx, pipx run und npx starten ihn dort "
|
|
924
|
+
"(Pruefung 112, D-532)")
|
|
925
|
+
except Exception as fehler: # noqa: BLE001 - jeder Startfehler ist der Befund
|
|
926
|
+
err(f"paketquellen/koolie_befehl.py: laesst sich nicht starten ({type(fehler).__name__}) "
|
|
927
|
+
f"(Pruefung 112)")
|
|
928
|
+
import contextlib
|
|
929
|
+
import importlib.util
|
|
930
|
+
import io
|
|
931
|
+
import tarfile
|
|
932
|
+
import tempfile
|
|
933
|
+
with tempfile.TemporaryDirectory(prefix="koolie-p112-") as w:
|
|
934
|
+
archiv = os.path.join(w, f"koolie-{version}.tar.gz")
|
|
935
|
+
with tarfile.open(archiv, "w:gz") as tf:
|
|
936
|
+
for rel in P112_DATEIEN + (f"{KERN}/VERSION", "LICENSE", "README.en.md"):
|
|
937
|
+
tf.add(os.path.join(root, *rel.split("/")), arcname=f"koolie-{version}/{rel}")
|
|
938
|
+
# einmal die Version der Marke, einmal die Vorabversion fuer TestPyPI (D-529)
|
|
939
|
+
for art, zusatz in (("", []), (", als Vorabversion gebaut", ["--vorab", "1"])):
|
|
940
|
+
puffer = io.StringIO()
|
|
941
|
+
try:
|
|
942
|
+
spec = importlib.util.spec_from_file_location(
|
|
943
|
+
"koolie_bauen_p112", os.path.join(root, "paketquellen", "bauen.py"))
|
|
944
|
+
bauen = importlib.util.module_from_spec(spec)
|
|
945
|
+
spec.loader.exec_module(bauen)
|
|
946
|
+
with contextlib.redirect_stdout(puffer), contextlib.redirect_stderr(puffer):
|
|
947
|
+
rc = bauen.main(["--archiv", archiv, "--aus", os.path.join(w, "aus"), *zusatz])
|
|
948
|
+
except Exception as fehler: # noqa: BLE001
|
|
949
|
+
rc, puffer = 1, io.StringIO(f"{type(fehler).__name__}: {fehler}")
|
|
950
|
+
if rc != 0:
|
|
951
|
+
text = puffer.getvalue()
|
|
952
|
+
befunde = ([z.strip() for z in text.split("BEFUNDE:", 1)[1].splitlines()
|
|
953
|
+
if z.strip()]
|
|
954
|
+
if "BEFUNDE:" in text else text.strip().splitlines()[-1:])[:3]
|
|
955
|
+
err(f"paketquellen/bauen.py: baut aus einem Wegwerfarchiv nicht ohne Befund{art} "
|
|
956
|
+
f"({' | '.join(befunde)}) (Pruefung 112, D-520)")
|
|
957
|
+
return
|