@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,1447 @@
|
|
|
1
|
+
"""Sonden zu den Pruefungen 46 bis 55 und zur Platzhalterbindung; Selbstprobe des
|
|
2
|
+
Baumdurchlaufs.
|
|
3
|
+
|
|
4
|
+
Teil des Sondenskripts probe-pruefungen.py, seit 1.19.1 in Module geteilt (K-174). Die
|
|
5
|
+
Einheiten melden sich beim Laden dieses Moduls an; der Einstieg laedt die Module in der
|
|
6
|
+
Reihenfolge ihrer Nummer, und das ist die Reihenfolge der Ausgabe (D-49). Ein Modul
|
|
7
|
+
liest nur aus dem Apparat und aus frueheren Teilen."""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import glob
|
|
11
|
+
import json
|
|
12
|
+
import os
|
|
13
|
+
import re
|
|
14
|
+
|
|
15
|
+
from .apparat import (
|
|
16
|
+
aufraeumen, buendel, ersetze, ersetzt, frei, gegenprobe, installation, lies, melde,
|
|
17
|
+
notiz, P, Praeparationsfehler, QUELLE, schreib, sonde, strict_ausgabe,
|
|
18
|
+
validator_ausgabe, zeile_nach)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# --- Pruefung 46: der 1.0.0-Stand (CR-2026-070, D-98, D-99) --------------------------
|
|
22
|
+
#
|
|
23
|
+
# Sechs Sonden, je eine auf einen eigenen Gegenstand, und zwei davon fuer die zwei
|
|
24
|
+
# Richtungen: Ein Kriterium, das ZURUECKFAELLT, und ein Fortschritt, der NICHT
|
|
25
|
+
# NACHGEZOGEN ist, sind beide ein Fehler. Ohne die zweite Richtung waere der Zaehler ein
|
|
26
|
+
# Fortschrittsbalken - er hielte still, solange sich nichts verschlechtert, und der
|
|
27
|
+
# Stand stuende wieder daneben.
|
|
28
|
+
#
|
|
29
|
+
# Drei Gegenproben, und sie treffen genau die Stellen, an denen die alten Zaehlregeln zu
|
|
30
|
+
# breit oder zu schmal waren: ein Klaerungspunkt mit demselben Statuswort (die alte
|
|
31
|
+
# Regel zaehlte fuenf davon mit) und ein Marker in einem datierten Protokoll (der
|
|
32
|
+
# Zaehlbereich schliesst ihn aus, und das muss er auch tun).
|
|
33
|
+
M46_ANKER = "die Standzeile steht 0x statt genau einmal"
|
|
34
|
+
M46_K1 = "Kriterium 1 von D-11"
|
|
35
|
+
M46_K2 = "Kriterium 2 von D-11"
|
|
36
|
+
M46_K3 = "Kriterium 3 von D-11"
|
|
37
|
+
M46_K4 = "Kriterium 4 von D-11"
|
|
38
|
+
M46_NICHT_NACHGEZOGEN = "der Fortschritt ist nicht nachgezogen"
|
|
39
|
+
M46_RUECKFALL = ("entweder ist der Bestand zur\u00fcckgefallen, oder der "
|
|
40
|
+
"Z\u00e4hlbereich sieht erstmals")
|
|
41
|
+
M46_AUSSERHALB = "ausserhalb des Zaehlbereichs von Kriterium 1"
|
|
42
|
+
P46_ROADMAP = ".koolie/core/docs/ROADMAP.md".replace("/", os.sep)
|
|
43
|
+
P46_STAND = "Gezählt von Prüfung 46: Kriterium 1 = "
|
|
44
|
+
# Der Marker in seiner clientneutralen Form - zusammengesetzt, weil eine woertliche
|
|
45
|
+
# Nennung in diesem Skript selbst eine Fundstelle waere und Kriterium 1 um eins hoebe.
|
|
46
|
+
# Dieses Skript liegt im Zaehlbereich.
|
|
47
|
+
P46_MARKER = "<VERIFY AGAINST CURRENT " + "CLIENT" + " DOCUMENTATION>"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _46_zahl_verstellen(root: str, welche: int, neu: str) -> None:
|
|
51
|
+
"""Eine der vier Zahlen der Standzeile auf einen anderen Wert setzen."""
|
|
52
|
+
pfad = P(root, P46_ROADMAP)
|
|
53
|
+
zeilen = lies(pfad).split("\r\n")
|
|
54
|
+
treffer = [i for i, z in enumerate(zeilen) if P46_STAND in z]
|
|
55
|
+
if len(treffer) != 1:
|
|
56
|
+
raise Praeparationsfehler(
|
|
57
|
+
"ROADMAP.md: Standzeile steht %dx, erwartet genau einmal" % len(treffer))
|
|
58
|
+
teile = re.split(r"(= \d+)", zeilen[treffer[0]])
|
|
59
|
+
stellen = [i for i, s in enumerate(teile) if s.startswith("= ")]
|
|
60
|
+
if len(stellen) != 4:
|
|
61
|
+
raise Praeparationsfehler(
|
|
62
|
+
"ROADMAP.md: Standzeile fuehrt %d Zahlen, erwartet vier" % len(stellen))
|
|
63
|
+
teile[stellen[welche]] = "= " + neu
|
|
64
|
+
zeilen[treffer[0]] = "".join(teile)
|
|
65
|
+
schreib(pfad, "\r\n".join(zeilen))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _46_standzeile_weg(root: str) -> None:
|
|
69
|
+
"""Die Standzeile ganz entfernen - der verlorene Anker."""
|
|
70
|
+
pfad = P(root, P46_ROADMAP)
|
|
71
|
+
zeilen = lies(pfad).split("\r\n")
|
|
72
|
+
behalten = [z for z in zeilen if P46_STAND not in z]
|
|
73
|
+
if len(behalten) == len(zeilen):
|
|
74
|
+
raise Praeparationsfehler("ROADMAP.md: keine Standzeile gefunden")
|
|
75
|
+
schreib(pfad, "\r\n".join(behalten))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _46_marker_dazu(root: str) -> None:
|
|
79
|
+
"""Eine neue unverifizierte Aussage im Kern - Kriterium 1 steigt um eins."""
|
|
80
|
+
pfad = P(root, ".koolie/core/framework/core/03-security.md".replace("/", os.sep))
|
|
81
|
+
schreib(pfad, lies(pfad) + "\r\n> Sondenzeile: Wirkung der Sandbox je "
|
|
82
|
+
"Betriebssystem " + P46_MARKER + ".\r\n")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _46_testblatt_dazu(root: str) -> None:
|
|
86
|
+
"""Ein Testblatt an einem Ort, den eine Ablagenliste uebersaehe.
|
|
87
|
+
|
|
88
|
+
Genau der Befund, der Pruefung 46 ausgeloest hat: Die alte Regel las "die dezentralen
|
|
89
|
+
TESTS.md je Skill" als zwoelf Dateien, und die dreizehnte lag unter role-packs/.
|
|
90
|
+
Diese Sonde legt eine vierzehnte unter tech-packs/ an - eine Ablagenliste, die die
|
|
91
|
+
dreizehnte uebersah, uebersaehe sie ebenso.
|
|
92
|
+
"""
|
|
93
|
+
ordner = P(root, ".koolie/core/framework/tech-packs/_template".replace("/", os.sep))
|
|
94
|
+
schreib(os.path.join(ordner, "TESTS.md"),
|
|
95
|
+
"# Sondentestblatt\r\n\r\n"
|
|
96
|
+
"| Test-ID | Ziel | Prüfmethode | Ergebnisstatus |\r\n"
|
|
97
|
+
"|---|---|---|---|\r\n"
|
|
98
|
+
"| SO-001 | Sondenfall | sitzung | offen |\r\n")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _46_steckbrief_dazu(root: str) -> None:
|
|
102
|
+
"""Ein neues Modul auf `entwurf` - Kriterium 3 steigt um eins."""
|
|
103
|
+
schreib(P(root, ".koolie/core/prompts/13-sondenprompt.md".replace("/", os.sep)),
|
|
104
|
+
"# Sondenprompt\r\n\r\n"
|
|
105
|
+
"| Attribut | Wert |\r\n|---|---|\r\n"
|
|
106
|
+
"| ID | `FW-PR-13` |\r\n| Version | `0.1.0` |\r\n"
|
|
107
|
+
"| Status | `entwurf` |\r\n| Owner (Rolle) | `<FRAMEWORK_OWNER>` |\r\n")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# Synthetische Kennung der Gegenprobe 46b. Sie stand bis 0.49.0 auf K-36 - und 0.50.0
|
|
111
|
+
# hat K-36 und K-37 wirklich vergeben (CR-2026-072). Der Kennungswaechter frei() hat
|
|
112
|
+
# die Kollision beim Sondenlauf gemeldet, statt sie als Befund am Repositorium
|
|
113
|
+
# erscheinen zu lassen; das ist die Lehre von G-18 (2026-09-13) zum zweiten Mal, und
|
|
114
|
+
# diesmal hat sie funktioniert. Die 99 folgt der Konvention von G-99 und UEB-99: hoch
|
|
115
|
+
# genug, dass keine echte Vergabe sie erreicht.
|
|
116
|
+
P46_KLAERUNG = "K-99"
|
|
117
|
+
P46_BESTAETIGT = "| entschieden (`CR-2026-071`); "
|
|
118
|
+
P46_VORSCHLAG = "| entschieden (Vorschlag); "
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _46_record_zurueckgefallen(root: str) -> None:
|
|
122
|
+
"""D-10 auf `entschieden (Vorschlag)` zuruecksetzen - Kriterium 4 STEIGT auf eins.
|
|
123
|
+
|
|
124
|
+
Bis 0.48.0 hob diese Sonde D-10 AUS dem Vorschlagsstatus HERAUS und belegte damit
|
|
125
|
+
die Richtung "Fortschritt nicht nachgezogen". Mit 0.49.0 sind alle neun Records
|
|
126
|
+
bestaetigt (CR-2026-071, D-100) - die Hebung hat keinen Gegenstand mehr, und der
|
|
127
|
+
alte Suchtext haette zwar noch getroffen (er steht jetzt im Verlaufszusatz der
|
|
128
|
+
Zelle), aber an einer Stelle, die Pruefung 46 gar nicht liest. Eine Sonde, die
|
|
129
|
+
etwas veraendert, ohne den Gegenstand zu treffen, ist der schlechteste Zustand:
|
|
130
|
+
Der Baumvergleich meldet kein "[nichts praepariert]", und der Fehlschlag sieht aus
|
|
131
|
+
wie ein Befund an der Pruefung.
|
|
132
|
+
|
|
133
|
+
Die Sonde stellt ihren Defekt deshalb seither HER statt ihn zu entfernen - wie 38a
|
|
134
|
+
und 38b seit 0.38.0 - und deckt damit die Richtung, die vorher KEINE Sonde decken
|
|
135
|
+
konnte, weil Kriterium 4 nie null war: den RUECKFALL. Getroffen wird der ANFANG
|
|
136
|
+
der Statuszelle, denn genau das liest der Zaehler (`zellen[4].startswith`).
|
|
137
|
+
"""
|
|
138
|
+
pfad = P(root, ".koolie/core/governance/DECISION_LOG.md".replace("/", os.sep))
|
|
139
|
+
zeilen = lies(pfad).split("\r\n")
|
|
140
|
+
treffer = [i for i, z in enumerate(zeilen) if z.startswith("| D-10 |")]
|
|
141
|
+
if len(treffer) != 1:
|
|
142
|
+
raise Praeparationsfehler(
|
|
143
|
+
"DECISION_LOG.md: Zeile D-10 steht %dx, erwartet genau einmal"
|
|
144
|
+
% len(treffer))
|
|
145
|
+
if P46_BESTAETIGT not in zeilen[treffer[0]]:
|
|
146
|
+
raise Praeparationsfehler(
|
|
147
|
+
"DECISION_LOG.md: die Statuszelle von D-10 beginnt nicht mit %r"
|
|
148
|
+
% P46_BESTAETIGT)
|
|
149
|
+
zeilen[treffer[0]] = zeilen[treffer[0]].replace(
|
|
150
|
+
P46_BESTAETIGT, P46_VORSCHLAG, 1)
|
|
151
|
+
schreib(pfad, "\r\n".join(zeilen))
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _46_klaerungspunkt_dazu(root: str) -> None:
|
|
155
|
+
"""Ein Klaerungspunkt mit demselben Statuswort - er ist KEIN Decision Record.
|
|
156
|
+
|
|
157
|
+
Die alte Zaehlregel war ein roher grep und zaehlte fuenf solcher Zeilen mit. D-11
|
|
158
|
+
sagt "Decision Records"; ein Klaerungspunkt ist keiner.
|
|
159
|
+
"""
|
|
160
|
+
pfad = P(root, ".koolie/core/governance/DECISION_LOG.md".replace("/", os.sep))
|
|
161
|
+
frei(pfad, P46_KLAERUNG)
|
|
162
|
+
zeile_nach(pfad, "| K-35 |",
|
|
163
|
+
"| " + P46_KLAERUNG + " | Sondenklärungspunkt | niedrig | Sondenlauf | "
|
|
164
|
+
"Framework Owner | entschieden (Vorschlag): Sondenauflösung |")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _46_protokollmarker(root: str) -> None:
|
|
168
|
+
"""Ein Marker in einem datierten Protokoll - ausserhalb des Zaehlbereichs.
|
|
169
|
+
|
|
170
|
+
Die Gattungsausnahme aus E2. Ein Bericht von gestern ist nicht bearbeitbar; zaehlte
|
|
171
|
+
er mit, stiege Kriterium 1 mit jedem Protokoll, das den Marker erwaehnt, und koennte
|
|
172
|
+
nie sinken.
|
|
173
|
+
"""
|
|
174
|
+
ordner = P(root, ".koolie/core/tests/protocols".replace("/", os.sep))
|
|
175
|
+
schreib(os.path.join(ordner, "2026-09-15-sondenprotokoll.md"),
|
|
176
|
+
"# Sondenprotokoll\r\n\r\nGemessen: Mustersemantik " + P46_MARKER + ".\r\n")
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
sonde("46a", "Eine Zahl der Standzeile steht zu hoch - der Zaehler meldet den nicht "
|
|
180
|
+
"nachgezogenen Fortschritt", lambda r: _46_zahl_verstellen(r, 3, "99"),
|
|
181
|
+
M46_NICHT_NACHGEZOGEN)
|
|
182
|
+
|
|
183
|
+
sonde("46b", "Ohne Standzeile hat Pruefung 46 ihren Gegenstand verloren und sagt es, "
|
|
184
|
+
"statt leise zu bestehen", _46_standzeile_weg, M46_ANKER)
|
|
185
|
+
|
|
186
|
+
sonde("46c", "Eine neue unverifizierte Aussage im Kern hebt Kriterium 1, ohne dass "
|
|
187
|
+
"jemand die Standzeile anfasst", _46_marker_dazu, M46_K1)
|
|
188
|
+
|
|
189
|
+
sonde("46d", "Ein Testblatt an einer Ablage, die keine Liste kennt, hebt Kriterium 2 - "
|
|
190
|
+
"der Befund dieses Antrags", _46_testblatt_dazu, M46_K2)
|
|
191
|
+
|
|
192
|
+
sonde("46e", "Ein neues Modul auf entwurf hebt Kriterium 3, auch ausserhalb der vier "
|
|
193
|
+
"frueher genannten Ablagen", _46_steckbrief_dazu, M46_K3)
|
|
194
|
+
|
|
195
|
+
sonde("46f", "Ein zurueckgefallener Decision Record hebt Kriterium 4 - die Standzeile "
|
|
196
|
+
"steht dann zu niedrig", _46_record_zurueckgefallen, M46_RUECKFALL)
|
|
197
|
+
|
|
198
|
+
gegenprobe("46a", "Das unveraenderte Repositorium bleibt unbeanstandet - alle vier "
|
|
199
|
+
"Zahlen der Standzeile stimmen", None, "D-11")
|
|
200
|
+
|
|
201
|
+
gegenprobe("46b", "Ein Klaerungspunkt mit demselben Statuswort bleibt ungezaehlt - "
|
|
202
|
+
"die alte Regel zaehlte fuenf davon mit", _46_klaerungspunkt_dazu,
|
|
203
|
+
M46_K4)
|
|
204
|
+
|
|
205
|
+
gegenprobe("46c", "Ein Marker in einem datierten Protokoll bleibt ungezaehlt - ein "
|
|
206
|
+
"Bericht von gestern ist nicht bearbeitbar", _46_protokollmarker,
|
|
207
|
+
M46_K1)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
# --- 46g, 46h, Gegenprobe 46d (K-98, D-483): die Markerform ausserhalb des Zaehlbereichs
|
|
211
|
+
#
|
|
212
|
+
# Kriterium 1 zaehlt den Kern. Die Wurzeldokumente und die Quellen des Hauptdokuments
|
|
213
|
+
# liegen ausserhalb; seit 1.19.1 meldet Pruefung 46 dort jede Fundstelle einzeln, ohne
|
|
214
|
+
# die Zaehlung zu veraendern. Die Gegenprobe haelt die Grenze zur anderen Seite: Eine
|
|
215
|
+
# Wurzeldatei, die kein Einstiegsdokument ist, gehoert nicht zu diesem Gegenstand.
|
|
216
|
+
def _46_marker_in(rel: str):
|
|
217
|
+
def praeparieren(root: str) -> None:
|
|
218
|
+
pfad = P(root, rel.replace("/", os.sep))
|
|
219
|
+
if not os.path.isfile(pfad):
|
|
220
|
+
raise Praeparationsfehler("Sonde 46: %s fehlt" % rel)
|
|
221
|
+
schreib(pfad, lies(pfad) + "\r\nSondenzeile: " + P46_MARKER + "\r\n")
|
|
222
|
+
return praeparieren
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def _46_marker_neben_der_wurzel(root: str) -> None:
|
|
226
|
+
schreib(P(root, "SONDENNOTIZ.txt"), "Sondenzeile: " + P46_MARKER + "\r\n")
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
sonde("46g", "Die Markerform in der README der Wurzel wird gemeldet, obwohl sie ausserhalb "
|
|
230
|
+
"des Zaehlbereichs von Kriterium 1 liegt", _46_marker_in("README.md"),
|
|
231
|
+
M46_AUSSERHALB)
|
|
232
|
+
|
|
233
|
+
sonde("46h", "Die Markerform in einer Quelle des Hauptdokuments unter build/doc wird "
|
|
234
|
+
"gemeldet", _46_marker_in(".koolie/core/build/doc/32-abschluss.md"),
|
|
235
|
+
M46_AUSSERHALB)
|
|
236
|
+
|
|
237
|
+
gegenprobe("46d", "Die Markerform in einer Wurzeldatei, die kein Einstiegsdokument ist, "
|
|
238
|
+
"gehoert nicht zu diesem Gegenstand", _46_marker_neben_der_wurzel,
|
|
239
|
+
M46_AUSSERHALB)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
# --- Selbstprobe C1: der Baumdurchlauf sieht mehr als die Mustersuche ----------------
|
|
243
|
+
#
|
|
244
|
+
# ANLASS: Die erste Fassung des Zaehlers lief ueber glob.glob(..., recursive=True).
|
|
245
|
+
# glob ueberspringt Pfadbestandteile, die mit einem Punkt beginnen - damit fehlten
|
|
246
|
+
# fuenfzehn Dateien des Kerns, darunter genau die zwei Traeger
|
|
247
|
+
# clients/*/root-template/.devin/README.md und .../.claude/README.md, die den Befund zu
|
|
248
|
+
# Kriterium 1 tragen. Der Zaehler haette 27 gemeldet und damit zufaellig die geglaubte
|
|
249
|
+
# Zahl bestaetigt.
|
|
250
|
+
#
|
|
251
|
+
# Eine Zaehlregel, die einen Traeger still ueberspringt, war der ANLASS dieses Antrags.
|
|
252
|
+
# Sie ist beim Bauen der Abhilfe ein zweites Mal entstanden - und eine benannte Falle,
|
|
253
|
+
# in die man zweimal tritt, gehoert in den Code (D-74). Diese Probe zaehlt beide
|
|
254
|
+
# Verfahren auf dem echten Baum gegeneinander ab: Findet glob genauso viel wie os.walk,
|
|
255
|
+
# ist entweder der Bestand ohne versteckte Traeger - dann sagt sie das - oder jemand hat
|
|
256
|
+
# den Zaehler zurueckgebaut.
|
|
257
|
+
#
|
|
258
|
+
# GRENZE: Sie misst den Bestand dieses Repositoriums, nicht den eines beliebigen. In
|
|
259
|
+
# einem Projekt ohne versteckte Kerndateien ist der Unterschied null, und dann belegt
|
|
260
|
+
# sie nichts - das steht dann in ihrer eigenen Meldung.
|
|
261
|
+
def selbstprobe_baumdurchlauf() -> None:
|
|
262
|
+
"""glob gegen os.walk auf dem echten Kern - der Fallstrick aus CR-2026-070 E7."""
|
|
263
|
+
kern = os.path.join(QUELLE, ".koolie/core")
|
|
264
|
+
mit_glob = {p for p in glob.glob(os.path.join(kern, "**", "*"), recursive=True)
|
|
265
|
+
if os.path.isfile(p)}
|
|
266
|
+
mit_walk = set()
|
|
267
|
+
for ordner, _, dateien in os.walk(kern):
|
|
268
|
+
for name in dateien:
|
|
269
|
+
mit_walk.add(os.path.join(ordner, name))
|
|
270
|
+
versteckt = sorted(mit_walk - mit_glob)
|
|
271
|
+
melde("SELBSTPROBE", "C1", bool(versteckt),
|
|
272
|
+
"Der Baumdurchlauf des Zaehlers findet %d Kerndateien, die eine Mustersuche "
|
|
273
|
+
"ueberspringt" % len(versteckt))
|
|
274
|
+
if not versteckt:
|
|
275
|
+
notiz(" glob und os.walk finden dasselbe. Entweder traegt der Kern keine "
|
|
276
|
+
"versteckte Datei mehr - dann belegt diese Probe nichts -, oder der "
|
|
277
|
+
"Zaehler ist auf glob zurueckgebaut worden (CR-2026-070 E7).")
|
|
278
|
+
else:
|
|
279
|
+
for pfad in versteckt[:3]:
|
|
280
|
+
notiz(" " + os.path.relpath(pfad, QUELLE).replace(os.sep, "/"))
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
buendel(selbstprobe_baumdurchlauf,
|
|
284
|
+
"Zaehlt Mustersuche gegen Baumdurchlauf auf dem echten Kern - der Fallstrick, "
|
|
285
|
+
"der beim Bauen von Pruefung 46 zuschnappte")
|
|
286
|
+
|
|
287
|
+
# --- 47: das Statusvokabular jedes Modultraegers ------------------------------------
|
|
288
|
+
#
|
|
289
|
+
# Die vier Gegenstaende der Pruefung, je eine Sonde - und dazu die Sonde auf den
|
|
290
|
+
# verlorenen Anker. Drei der vier Sonden legen eine NEUE Datei an, statt eine
|
|
291
|
+
# bestehende zu verstellen: Der Statuswert des Bestands bewegt sich mit jedem Release,
|
|
292
|
+
# und eine Sonde, die einen Wert woertlich sucht, misst ab dem naechsten Statuswechsel
|
|
293
|
+
# den Suchtext statt die Pruefung (die Lehre von 46f, 0.49.0).
|
|
294
|
+
M47_FEHLT = "der Steckbrief führt keine Zeile"
|
|
295
|
+
M47_VOKABULAR = "gehört nicht zum Vokabular"
|
|
296
|
+
M47_VORLAGE_ECHT = "die Statuszelle einer Vorlage trägt den echten Wert"
|
|
297
|
+
M47_SCHLITZ_FREMD = "trägt den Ausfüllschlitz"
|
|
298
|
+
M47_ANKER = "kein einziger Steckbrief gefunden"
|
|
299
|
+
P47_STECKBRIEFKOPF = "| Attribut | Wert |"
|
|
300
|
+
P47_SKILLVORLAGE = ".koolie/core/templates/SKILL_TEMPLATE.md".replace("/", os.sep)
|
|
301
|
+
P47_SCHLITZ = "<TBD: Status; ein neuer Skill beginnt auf entwurf>"
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _47_datei(root: str, name: str, statuszeile: str) -> None:
|
|
305
|
+
"""Eine neue Prompt-Datei mit Steckbrief und der uebergebenen Statuszeile.
|
|
306
|
+
|
|
307
|
+
Eine leere Statuszeile heisst: kein Status im Steckbrief.
|
|
308
|
+
"""
|
|
309
|
+
schreib(P(root, (".koolie/core/prompts/" + name).replace("/", os.sep)),
|
|
310
|
+
"# Sondenvorlage\r\n\r\n"
|
|
311
|
+
+ P47_STECKBRIEFKOPF + "\r\n|---|---|\r\n"
|
|
312
|
+
"| ID | `FW-PR-013` |\r\n| Version | `0.1.0` |\r\n"
|
|
313
|
+
+ (statuszeile + "\r\n" if statuszeile else "")
|
|
314
|
+
+ "| Owner (Rolle) | `<FRAMEWORK_OWNER>` |\r\n")
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _47_ohne_statuszeile(root: str) -> None:
|
|
318
|
+
"""Ein Steckbrief ohne Statuszeile - genau die zwoelf Traeger aus K-36."""
|
|
319
|
+
_47_datei(root, "13-sonde-ohne-status.md", "")
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def _47_fremdes_wort(root: str) -> None:
|
|
323
|
+
"""Ein Statuswert ausserhalb des Vokabulars - bis 0.50.0 nur in einer SKILL.md gefangen."""
|
|
324
|
+
_47_datei(root, "13-sonde-vokabular.md", "| Status | `banane` |")
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def _47_schlitz_ausserhalb(root: str) -> None:
|
|
328
|
+
"""Ein Ausfuellschlitz in einer Datei, die keine Vorlage ist - der Preis aus D-104."""
|
|
329
|
+
_47_datei(root, "13-sonde-schlitz.md",
|
|
330
|
+
"| Status | `<TBD: Status; ein neuer Prompt beginnt auf entwurf>` |")
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def _47_vorlage_mit_echtem_wert(root: str) -> None:
|
|
334
|
+
"""Der Defekt von 0.50.0, wiederhergestellt: eine Vorlage traegt `entwurf`.
|
|
335
|
+
|
|
336
|
+
Die Statuszelle der Skillvorlage gab diesen Wert an jede Kopie weiter und durfte
|
|
337
|
+
sich deshalb nie aendern; genau daran war Kriterium 3 von D-11 unerreichbar
|
|
338
|
+
(D-104). Die Sonde stellt den Zustand HER statt ihn zu entfernen - wie 38a, 38b
|
|
339
|
+
und 46f.
|
|
340
|
+
"""
|
|
341
|
+
ersetze(P(root, P47_SKILLVORLAGE), (P47_SCHLITZ, "entwurf"))
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def _47_steckbriefkopf_umbenennen(root: str) -> None:
|
|
345
|
+
"""Die Kopfzeile jedes Steckbriefs umbenennen - die Pruefung findet keinen mehr.
|
|
346
|
+
|
|
347
|
+
Anders als bei den Pruefungen 28, 29, 31, 40 und 46 ist der Anker hier keine
|
|
348
|
+
einzelne Zeichenkette in einer Datei, sondern eine KONVENTION ueber den ganzen
|
|
349
|
+
Bestand. Verliert sie sich, faende die Pruefung nichts mehr und bestuende leise -
|
|
350
|
+
deshalb benennt diese Sonde sie ueberall um und belegt, dass der Lauf das meldet.
|
|
351
|
+
"""
|
|
352
|
+
getroffen = 0
|
|
353
|
+
for ordner, _, dateien in os.walk(P(root, ".koolie/core")):
|
|
354
|
+
for name in sorted(dateien):
|
|
355
|
+
if not name.endswith(".md"):
|
|
356
|
+
continue
|
|
357
|
+
pfad = os.path.join(ordner, name)
|
|
358
|
+
text = lies(pfad)
|
|
359
|
+
if P47_STECKBRIEFKOPF not in text:
|
|
360
|
+
continue
|
|
361
|
+
schreib(pfad, text.replace(P47_STECKBRIEFKOPF, "| Merkmal | Wert |"))
|
|
362
|
+
getroffen += 1
|
|
363
|
+
if getroffen < 50:
|
|
364
|
+
raise Praeparationsfehler(
|
|
365
|
+
"nur %d Dateien mit der Steckbriefkopfzeile gefunden, erwartet mindestens "
|
|
366
|
+
"50 - die Konvention hat sich geaendert" % getroffen)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def _47_verlaufszusatz(root: str) -> None:
|
|
370
|
+
"""Einem gehobenen Traeger einen Verlaufszusatz in Klammern anhaengen.
|
|
371
|
+
|
|
372
|
+
`entwurf (Referenzpack der Erstfassung)` steht seit der Erstfassung im Bestand;
|
|
373
|
+
verglichen wird deshalb das ERSTE WORT. Die Gegenprobe belegt, dass ein solcher
|
|
374
|
+
Zusatz zulaessig bleibt - und dass Pruefung 46 ihn weiterhin richtig einordnet.
|
|
375
|
+
"""
|
|
376
|
+
ersetze(P(root, ".koolie/core/checklists/01-preflight.md".replace("/", os.sep)),
|
|
377
|
+
("| Status | `pilot` |", "| Status | `pilot (Abnahme CR-2026-073)` |"))
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def _47_tabelle_hinter_ueberschrift(root: str) -> None:
|
|
381
|
+
"""Eine Steckbriefkopfzeile im KOERPER einer Datei ist kein Steckbrief.
|
|
382
|
+
|
|
383
|
+
Der Fall von templates/PLAN_TEMPLATE.md: Dort steht die Tabelle hinter einer
|
|
384
|
+
Ueberschrift der Ebene 2 und ist das Formular fuer die Kopie, nicht der Steckbrief
|
|
385
|
+
der Datei. Eine Erkennungsregel, die bloss nach der Kopfzeile sucht, verlangte dort
|
|
386
|
+
einen Statuswert - und die Datei fuehrt zu Recht keinen.
|
|
387
|
+
"""
|
|
388
|
+
schreib(P(root, ".koolie/core/examples/example-sondenformular.md"
|
|
389
|
+
.replace("/", os.sep)),
|
|
390
|
+
"# Beispielformular (synthetisch)\r\n\r\n"
|
|
391
|
+
"Ein Formular, das die Kopie ausfuellt - kein Steckbrief.\r\n\r\n"
|
|
392
|
+
"## Formular\r\n\r\n"
|
|
393
|
+
+ P47_STECKBRIEFKOPF + "\r\n|---|---|\r\n"
|
|
394
|
+
"| Erstellt mit | `<Skill>` |\r\n| Bestaetigt durch | `<Rolle>` |\r\n")
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
sonde("47a", "Ein Steckbrief ohne Statuszeile wird gemeldet - das Loch, durch das bis "
|
|
398
|
+
"0.50.0 zwoelf Traeger entkamen", _47_ohne_statuszeile, M47_FEHLT)
|
|
399
|
+
|
|
400
|
+
sonde("47b", "Ein Statuswert ausserhalb des Vokabulars faellt auf, auch weit weg von "
|
|
401
|
+
"einer SKILL.md", _47_fremdes_wort, M47_VOKABULAR)
|
|
402
|
+
|
|
403
|
+
sonde("47c", "Eine Vorlage mit echtem Statuswert wird gemeldet - der Defekt, der "
|
|
404
|
+
"Kriterium 3 unerreichbar machte", _47_vorlage_mit_echtem_wert,
|
|
405
|
+
M47_VORLAGE_ECHT)
|
|
406
|
+
|
|
407
|
+
sonde("47d", "Ein Ausfuellschlitz ausserhalb einer Vorlage wird gemeldet - die "
|
|
408
|
+
"kopierte und nicht gefuellte Vorlage", _47_schlitz_ausserhalb,
|
|
409
|
+
M47_SCHLITZ_FREMD)
|
|
410
|
+
|
|
411
|
+
sonde("47e", "Ohne die Steckbriefkonvention hat Pruefung 47 ihren Gegenstand verloren "
|
|
412
|
+
"und sagt es, statt leise zu bestehen", _47_steckbriefkopf_umbenennen,
|
|
413
|
+
M47_ANKER)
|
|
414
|
+
|
|
415
|
+
gegenprobe("47a", "Das unveraenderte Repositorium bleibt unbeanstandet - jeder "
|
|
416
|
+
"Steckbrief traegt einen gueltigen Statuswert", None, "Vokabular")
|
|
417
|
+
|
|
418
|
+
gegenprobe("47b", "Ein Verlaufszusatz in Klammern bleibt zulaessig - verglichen wird "
|
|
419
|
+
"das erste Wort des Werts", _47_verlaufszusatz, M47_VOKABULAR)
|
|
420
|
+
|
|
421
|
+
gegenprobe("47c", "Eine Steckbriefkopfzeile hinter einer Ueberschrift ist kein "
|
|
422
|
+
"Steckbrief und verlangt keinen Status", _47_tabelle_hinter_ueberschrift,
|
|
423
|
+
M47_FEHLT)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
# --- 48: die Werkzeugneutralitaet des Kerns -----------------------------------------
|
|
427
|
+
#
|
|
428
|
+
# Die drei Gruende, aus denen Pruefung 12 die siebzehn Fundstellen nicht fand, sind hier
|
|
429
|
+
# je eine Sonde: der Pfad des INSTALLIERTEN Packs (Grund 2 - er existiert und war damit
|
|
430
|
+
# unsichtbar), der Pfad OHNE Backticks (Grund 1) und die anweisende Spalte des
|
|
431
|
+
# Testkatalogs, deren letzte Zelle bewusst ausgenommen ist. Dazu die Sonde auf den
|
|
432
|
+
# verlorenen Anker und drei Gegenproben - die Belegspalte, die Chronik und der
|
|
433
|
+
# unberuehrte Bestand.
|
|
434
|
+
#
|
|
435
|
+
# Die Sonden legen NEUE Dateien an, statt bestehende zu verstellen: Ein Suchtext im
|
|
436
|
+
# Bestand misst ab dem naechsten Release den Suchtext statt die Pruefung (die Lehre von
|
|
437
|
+
# 46f). Welchen Pfad sie schreiben, LESEN sie aus den Manifesten - eine Sonde, die einen
|
|
438
|
+
# Pfad raet, misst den geratenen Pfad.
|
|
439
|
+
M48_PFAD = "gehört der Laufzeitschicht des Client Packs"
|
|
440
|
+
M48_ANKER = "kein Client Pack mit runtime_placeholders gefunden"
|
|
441
|
+
P48_KATALOG = ".koolie/core/tests/TEST_CATALOG.md".replace("/", os.sep)
|
|
442
|
+
P48_ROADMAP = ".koolie/core/docs/ROADMAP.md".replace("/", os.sep)
|
|
443
|
+
P48_KATALOGANKER = "| FW-AK-02 (Basis) |"
|
|
444
|
+
P48_ROADMAPANKER = "#### Der Releaseplan bis 1.0.0 und darüber hinaus"
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def _48_marken(root: str) -> tuple:
|
|
448
|
+
"""(Laufzeitschicht des installierten Packs, die des anderen) - aus den Manifesten.
|
|
449
|
+
|
|
450
|
+
Installiert ist das Pack, dessen Laufzeitverzeichnis im Baum wirklich liegt; genau
|
|
451
|
+
darauf beruht der zweite Grund, aus dem Pruefung 12 blind war.
|
|
452
|
+
"""
|
|
453
|
+
base = P(root, ".koolie/core", "clients")
|
|
454
|
+
verzeichnisse = []
|
|
455
|
+
for name in sorted(os.listdir(base)):
|
|
456
|
+
if name.startswith("_"):
|
|
457
|
+
continue
|
|
458
|
+
mp = os.path.join(base, name, "manifest.json")
|
|
459
|
+
if os.path.exists(mp):
|
|
460
|
+
verzeichnisse.append(json.loads(lies(mp))["runtime_dir"])
|
|
461
|
+
if len(verzeichnisse) < 2:
|
|
462
|
+
raise Praeparationsfehler(
|
|
463
|
+
"Weniger als zwei Client Packs mit manifest.json - die Sonden zu 48 "
|
|
464
|
+
"brauchen ein installiertes und ein nicht installiertes Pack")
|
|
465
|
+
installiert = [v for v in verzeichnisse if os.path.isdir(P(root, *v.split("/")))]
|
|
466
|
+
fremd = [v for v in verzeichnisse if v not in installiert]
|
|
467
|
+
if not installiert or not fremd:
|
|
468
|
+
raise Praeparationsfehler(
|
|
469
|
+
"Im Baum liegt keine oder jede Laufzeitschicht (%s) - die Sonden zu 48 "
|
|
470
|
+
"unterscheiden das installierte vom nicht installierten Pack"
|
|
471
|
+
% ", ".join(verzeichnisse))
|
|
472
|
+
return installiert[0], fremd[0]
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
def _48_datei(root: str, name: str, inhalt: str) -> None:
|
|
476
|
+
"""Eine neue Prompt-Datei mit vollstaendigem Steckbrief und der Inhaltszeile."""
|
|
477
|
+
schreib(P(root, (".koolie/core/prompts/" + name).replace("/", os.sep)),
|
|
478
|
+
"# Sondenvorlage\r\n\r\n"
|
|
479
|
+
"| Attribut | Wert |\r\n|---|---|\r\n"
|
|
480
|
+
"| ID | `FW-PR-014` |\r\n| Version | `0.1.0` |\r\n"
|
|
481
|
+
"| Status | `pilot` |\r\n"
|
|
482
|
+
"| Owner (Rolle) | `<FRAMEWORK_OWNER>` |\r\n\r\n"
|
|
483
|
+
+ inhalt + "\r\n")
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def _48_installiertes_pack(root: str) -> None:
|
|
487
|
+
"""Der Pfad des INSTALLIERTEN Packs in einem Kerntraeger - Grund 2 der Blindheit.
|
|
488
|
+
|
|
489
|
+
Pruefung 12 meldet nur Pfade, die es NICHT GIBT. Dieser hier existiert im Baum und
|
|
490
|
+
lief deshalb sechsundfuenfzig Releases lang durch.
|
|
491
|
+
"""
|
|
492
|
+
installiert, _ = _48_marken(root)
|
|
493
|
+
_48_datei(root, "14-sonde-installiert.md",
|
|
494
|
+
"Ausgabeformat: Analyse nach `%s/skills/fw-repo-analyze/SKILL.md`."
|
|
495
|
+
% installiert)
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
def _48_ohne_backticks(root: str) -> None:
|
|
499
|
+
"""Derselbe Befund ohne Backticks - Grund 1 der Blindheit.
|
|
500
|
+
|
|
501
|
+
Zehn der siebzehn Fundstellen standen so: im Codeblock, in Prosa oder im
|
|
502
|
+
HTML-Kommentar. Die Heuristik von Pruefung 12 sieht nur Token in Backticks.
|
|
503
|
+
"""
|
|
504
|
+
_, fremd = _48_marken(root)
|
|
505
|
+
_48_datei(root, "14-sonde-prosa.md",
|
|
506
|
+
"Die Regeln liegen unter %s/rules und werden bei Sitzungsbeginn geladen."
|
|
507
|
+
% fremd)
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def _48_anweisende_spalte(root: str) -> None:
|
|
511
|
+
"""Ein Clientpfad in einer ANWEISENDEN Spalte des Testkatalogs wird gemeldet.
|
|
512
|
+
|
|
513
|
+
Die Ausnahme dieses Traegers gilt der LETZTEN Zelle (Ergebnisstatus, D-117). Wer
|
|
514
|
+
sie auf die Zeile ausdehnt, nimmt genau die Eingabezelle mit heraus, in der bis
|
|
515
|
+
0.56.2 'Passe AGENTS.md an' stand - der Zuschnitt, der den Gegenstand mitentfernt.
|
|
516
|
+
"""
|
|
517
|
+
installiert, _ = _48_marken(root)
|
|
518
|
+
zeile_nach(P(root, P48_KATALOG), P48_KATALOGANKER,
|
|
519
|
+
"| FW-SO-01 | Sondenzeile | Sondenvorbedingung | Anweisung: lies %s/config "
|
|
520
|
+
"| Ablehnung | Zugriff | sitzung | offen |" % installiert)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
def _48_anker_verlieren(root: str) -> None:
|
|
524
|
+
"""Ohne runtime_placeholders in den Manifesten hat die Pruefung keine Marken mehr.
|
|
525
|
+
|
|
526
|
+
Sie leitet sie von dort ab; geht der Schluessel verloren, faende sie nichts und
|
|
527
|
+
bestuende leise. Die Sonde belegt, dass sie das Fehlen selbst meldet (D-23).
|
|
528
|
+
"""
|
|
529
|
+
base = P(root, ".koolie/core", "clients")
|
|
530
|
+
getroffen = 0
|
|
531
|
+
for name in sorted(os.listdir(base)):
|
|
532
|
+
mp = os.path.join(base, name, "manifest.json")
|
|
533
|
+
if not os.path.exists(mp):
|
|
534
|
+
continue
|
|
535
|
+
ersetze(mp, ('"runtime_placeholders"', '"runtime_placeholders_alt"'))
|
|
536
|
+
getroffen += 1
|
|
537
|
+
if not getroffen:
|
|
538
|
+
raise Praeparationsfehler(
|
|
539
|
+
"Kein manifest.json unter clients/ - die Ankersonde zu 48 haette nichts "
|
|
540
|
+
"zu verstellen")
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
def _48_belegspalte(root: str) -> None:
|
|
544
|
+
"""Ein Clientpfad in der LETZTEN Zelle einer Testkatalogzeile bleibt zulaessig.
|
|
545
|
+
|
|
546
|
+
Der Ergebnisstatus nennt, was ein Lauf gelesen hat, und das gemessene Client Pack
|
|
547
|
+
(D-117). Ein Begriff statt des Pfads waere dort kein Beleg mehr.
|
|
548
|
+
"""
|
|
549
|
+
_, fremd = _48_marken(root)
|
|
550
|
+
zeile_nach(P(root, P48_KATALOG), P48_KATALOGANKER,
|
|
551
|
+
"| FW-SO-02 | Sondenzeile | Sondenvorbedingung | Anweisung | Ablehnung "
|
|
552
|
+
"| Zugriff | sitzung | bestanden (`.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md`; Client Pack `claude-code` 2.1.278 - der Lauf benennt `%s/rules/00-framework-core.md`) |"
|
|
553
|
+
% fremd)
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
def _48_chronik(root: str) -> None:
|
|
557
|
+
"""Ein Clientpfad in der Roadmap bleibt zulaessig - sie berichtet Erhebungen.
|
|
558
|
+
|
|
559
|
+
Dieselbe Begruendung wie bei den Protokollen: Wer einen Befundbericht glaettet,
|
|
560
|
+
macht aus einer richtigen Zeile eine unbelegbare.
|
|
561
|
+
"""
|
|
562
|
+
installiert, fremd = _48_marken(root)
|
|
563
|
+
pfad = P(root, P48_ROADMAP)
|
|
564
|
+
schreib(pfad, lies(pfad).rstrip("\r\n") + "\r\n\r\n"
|
|
565
|
+
+ "Sondennachtrag zur Erhebung: Der Lauf las %s/rules und legte seine "
|
|
566
|
+
"Ausgabe unter %s/skills ab.\r\n" % (installiert, fremd))
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
sonde("48a", "Der Pfad des INSTALLIERTEN Packs in einem Kerntraeger wird gemeldet - "
|
|
570
|
+
"genau der Fall, den Pruefung 12 nie sah", _48_installiertes_pack, M48_PFAD)
|
|
571
|
+
|
|
572
|
+
sonde("48b", "Ein Clientpfad ohne Backticks wird gemeldet - zehn der siebzehn "
|
|
573
|
+
"Fundstellen standen so", _48_ohne_backticks, M48_PFAD)
|
|
574
|
+
|
|
575
|
+
sonde("48c", "Ein Clientpfad in einer anweisenden Spalte des Testkatalogs wird "
|
|
576
|
+
"gemeldet, obwohl die letzte Zelle ausgenommen ist", _48_anweisende_spalte,
|
|
577
|
+
M48_PFAD)
|
|
578
|
+
|
|
579
|
+
sonde("48d", "Ohne runtime_placeholders in den Manifesten meldet Pruefung 48 den "
|
|
580
|
+
"verlorenen Gegenstand, statt leise zu bestehen", _48_anker_verlieren,
|
|
581
|
+
M48_ANKER)
|
|
582
|
+
|
|
583
|
+
gegenprobe("48a", "Das unveraenderte Repositorium bleibt unbeanstandet - die siebzehn "
|
|
584
|
+
"Fundstellen sind aufgeloest", None, M48_PFAD)
|
|
585
|
+
|
|
586
|
+
gegenprobe("48b", "Ein Clientpfad in der Ergebnisstatuszelle des Testkatalogs bleibt "
|
|
587
|
+
"zulaessig - dort ist er der Beleg", _48_belegspalte, M48_PFAD)
|
|
588
|
+
|
|
589
|
+
gegenprobe("48c", "Ein Clientpfad in der Roadmap bleibt zulaessig - sie fuehrt die "
|
|
590
|
+
"Erhebungen je Arbeitspaket", _48_chronik, M48_PFAD)
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
# --- Pruefung 49: ausdruecklicher Skill-Aufruf im Testkatalog (D-146) --------------
|
|
594
|
+
#
|
|
595
|
+
# Der Befund, der sie veranlasst hat, ist am 2026-09-18 an FW-SC-01 gemessen worden: Der
|
|
596
|
+
# Hauptlauf rief `fw-change-small` auf, wurde abgewiesen - neun von zwoelf Kernskills
|
|
597
|
+
# fuehren `triggers` ohne `- model`, und das Pack claude-code bildet das auf
|
|
598
|
+
# `disable-model-invocation: true` ab - und arbeitete den Ablauf nicht nach. Damit fiel
|
|
599
|
+
# Schritt 3 des Skills aus, der die Verwender der geaenderten Einheit erhebt; die
|
|
600
|
+
# Scope-Falle konnte nicht zuschnappen. Die Zelle stand danach als `offen`, und die
|
|
601
|
+
# Ursache wurde einer Regelkollision zugeschrieben, die es nicht gibt (CR-2026-085).
|
|
602
|
+
M49_AUFRUF = "ohne den ausdrücklichen Aufruf"
|
|
603
|
+
M49_ANKER = "kein Skill mit 'triggers' ohne '- model' gefunden"
|
|
604
|
+
P49_KATALOG = ".koolie/core/tests/TEST_CATALOG.md".replace("/", os.sep)
|
|
605
|
+
P49_KATALOGANKER = "| FW-AK-02 (Basis) |"
|
|
606
|
+
P49_SKILLS = ".koolie/core/framework/skills".replace("/", os.sep)
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
def _49_skill_ohne_modell(root: str) -> str:
|
|
610
|
+
"""Ein Kernskill, dessen Quelle `triggers` ohne `- model` fuehrt - abgeleitet.
|
|
611
|
+
|
|
612
|
+
Die Sonde raet den Namen nicht: Waere er gepflegt, prueften Sonde und Pruefung
|
|
613
|
+
verschiedene Mengen, und die Sonde bestuende an einem Skill, den es nicht mehr gibt.
|
|
614
|
+
"""
|
|
615
|
+
basis = P(root, *P49_SKILLS.split(os.sep))
|
|
616
|
+
for name in sorted(os.listdir(basis)):
|
|
617
|
+
pfad = os.path.join(basis, name, "SKILL.md")
|
|
618
|
+
if not os.path.isfile(pfad):
|
|
619
|
+
continue
|
|
620
|
+
text = lies(pfad)
|
|
621
|
+
i = text.find("triggers:")
|
|
622
|
+
if i < 0:
|
|
623
|
+
continue
|
|
624
|
+
block = text[i:text.find("---", 3)] if text.startswith("---") else text[i:i + 200]
|
|
625
|
+
# Seit 1.17.0 tragen fw-bugfix-prepare und fw-plan `model` (D-451); der naechste
|
|
626
|
+
# Skill ohne model fuehrt Test- und Lintbefehle aus, und Pruefung 49 verlangt dann
|
|
627
|
+
# zu Recht den Schlitz in der Vorbedingung - gemessen wuerde die falsche Regel.
|
|
628
|
+
if "- model" not in block and "<TEST_COMMAND>" not in text and "<LINT_COMMAND>" not in text:
|
|
629
|
+
return name
|
|
630
|
+
raise Praeparationsfehler(
|
|
631
|
+
"Kein Kernskill mit `triggers` ohne `- model` - die Sonden zu 49 brauchen einen")
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
def _49_skill_mit_modell(root: str) -> str:
|
|
635
|
+
"""Das Gegenstueck: ein Skill, den das Modell von sich aus waehlen darf."""
|
|
636
|
+
basis = P(root, *P49_SKILLS.split(os.sep))
|
|
637
|
+
for name in sorted(os.listdir(basis)):
|
|
638
|
+
pfad = os.path.join(basis, name, "SKILL.md")
|
|
639
|
+
if not os.path.isfile(pfad):
|
|
640
|
+
continue
|
|
641
|
+
text = lies(pfad)
|
|
642
|
+
i = text.find("triggers:")
|
|
643
|
+
if i < 0:
|
|
644
|
+
continue
|
|
645
|
+
block = text[i:text.find("---", 3)] if text.startswith("---") else text[i:i + 200]
|
|
646
|
+
if "- model" in block:
|
|
647
|
+
return name
|
|
648
|
+
raise Praeparationsfehler(
|
|
649
|
+
"Kein Kernskill mit `- model` - die Gegenprobe zu 49 braucht einen")
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
def _49_katalogzeile(root: str, zeile: str) -> None:
|
|
653
|
+
zeile_nach(P(root, P49_KATALOG), P49_KATALOGANKER, zeile)
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
def _49_nackte_nennung(root: str) -> None:
|
|
657
|
+
"""Der Skillname ohne Schraegstrich im Ausloeser eines `sitzung`-Testfalls.
|
|
658
|
+
|
|
659
|
+
Genau die Schreibweise, in der vier Katalogzeilen ihn bis 0.59.1 fuehrten - und in
|
|
660
|
+
der der Prompt zu FW-SC-01 ihn gar nicht fuehrte.
|
|
661
|
+
"""
|
|
662
|
+
_49_katalogzeile(root,
|
|
663
|
+
"| FW-SO-03 | Sondenzeile | Sondenvorbedingung | %s mit Sondenaufgabe "
|
|
664
|
+
"| Ablehnung | Zugriff | sitzung | offen |" % _49_skill_ohne_modell(root))
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
def _49_anker_verlieren(root: str) -> None:
|
|
668
|
+
"""Ohne `triggers` in den Skillquellen hat Pruefung 49 keine Marken mehr.
|
|
669
|
+
|
|
670
|
+
Sie leitet sie von dort ab; geht der Schluessel verloren, faende sie nichts und
|
|
671
|
+
bestuende leise. Die Sonde belegt, dass sie das Fehlen selbst meldet (D-23).
|
|
672
|
+
"""
|
|
673
|
+
basis = P(root, *P49_SKILLS.split(os.sep))
|
|
674
|
+
getroffen = 0
|
|
675
|
+
for name in sorted(os.listdir(basis)):
|
|
676
|
+
pfad = os.path.join(basis, name, "SKILL.md")
|
|
677
|
+
if not os.path.isfile(pfad):
|
|
678
|
+
continue
|
|
679
|
+
if "triggers:" in lies(pfad):
|
|
680
|
+
ersetze(pfad, ("triggers:", "ladeausloeser:"))
|
|
681
|
+
getroffen += 1
|
|
682
|
+
if not getroffen:
|
|
683
|
+
raise Praeparationsfehler(
|
|
684
|
+
"Keine SKILL.md mit `triggers` - die Ankersonde zu 49 haette nichts zu "
|
|
685
|
+
"verstellen")
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
def _49_ausdruecklicher_aufruf(root: str) -> None:
|
|
689
|
+
"""Derselbe Skill als `/name` bleibt zulaessig - das ist der Aufruf selbst."""
|
|
690
|
+
_49_katalogzeile(root,
|
|
691
|
+
"| FW-SO-04 | Sondenzeile | Sondenvorbedingung | `/%s` mit Sondenaufgabe "
|
|
692
|
+
"| Ablehnung | Zugriff | sitzung | bestanden (Sondenbeleg, `.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md`; Client Pack `claude-code` 2.1.278) |"
|
|
693
|
+
% _49_skill_ohne_modell(root))
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
def _49_modellaufrufbar(root: str) -> None:
|
|
697
|
+
"""Ein Skill MIT `- model` bleibt nackt zulaessig - der Zuschnitt ist nicht zu breit.
|
|
698
|
+
|
|
699
|
+
Ohne dieses Paar meldete die Pruefung jeden Skillnamen und waere eine Stilregel.
|
|
700
|
+
"""
|
|
701
|
+
_49_katalogzeile(root,
|
|
702
|
+
"| FW-SO-05 | Sondenzeile | Sondenvorbedingung | %s mit Sondenaufgabe "
|
|
703
|
+
"| Ablehnung | Zugriff | sitzung | bestanden (Sondenbeleg, `.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md`; Client Pack `claude-code` 2.1.278) |"
|
|
704
|
+
% _49_skill_mit_modell(root))
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
def _49_andere_spalte(root: str) -> None:
|
|
708
|
+
"""Derselbe Name in einer ANDEREN Spalte bleibt zulaessig - die Regel gilt dem Ausloeser.
|
|
709
|
+
|
|
710
|
+
Das Gegenstueck zur Spaltenaufloesung: Wer die Zeile statt der Spalte nimmt, meldet
|
|
711
|
+
auch die Zelle, die das erwartete Verhalten beschreibt - und dort ist die Nennung
|
|
712
|
+
eine Aussage ueber den Lauf, keine Anweisung an ihn.
|
|
713
|
+
"""
|
|
714
|
+
_49_katalogzeile(root,
|
|
715
|
+
"| FW-SO-06 | Sondenzeile | Sondenvorbedingung | Sondenaufgabe "
|
|
716
|
+
"| Der Lauf nennt %s als zustaendig | Zugriff | sitzung | bestanden (Sondenbeleg, `.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md`; Client Pack `claude-code` 2.1.278) |"
|
|
717
|
+
% _49_skill_ohne_modell(root))
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
def _49_andere_pruefmethode(root: str) -> None:
|
|
721
|
+
"""Eine nackte Nennung bei Pruefmethode `review` bleibt zulaessig.
|
|
722
|
+
|
|
723
|
+
Die Regel gilt dem Lauf, nicht dem Lesen: Eine Durchsicht ruft keinen Skill auf.
|
|
724
|
+
"""
|
|
725
|
+
_49_katalogzeile(root,
|
|
726
|
+
"| FW-SO-07 | Sondenzeile | Sondenvorbedingung | %s mit Sondenaufgabe "
|
|
727
|
+
"| Ablehnung | Zugriff | review | bestanden (Sondenbeleg, `.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md`; Client Pack `claude-code` 2.1.278) |"
|
|
728
|
+
% _49_skill_ohne_modell(root))
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
sonde("49a", "Ein Kernskill ohne Modellzulassung, im Ausloeser eines sitzung-Testfalls "
|
|
732
|
+
"nackt genannt, wird gemeldet", _49_nackte_nennung, M49_AUFRUF)
|
|
733
|
+
|
|
734
|
+
sonde("49b", "Ohne `triggers` in den Skillquellen meldet Pruefung 49 den verlorenen "
|
|
735
|
+
"Gegenstand, statt leise zu bestehen", _49_anker_verlieren, M49_ANKER)
|
|
736
|
+
|
|
737
|
+
gegenprobe("49a", "Das unveraenderte Repositorium bleibt unbeanstandet - die vier "
|
|
738
|
+
"Fundstellen sind auf `/name` gestellt", None, M49_AUFRUF)
|
|
739
|
+
|
|
740
|
+
gegenprobe("49b", "Derselbe Skill als `/name` bleibt zulaessig - das ist der Aufruf",
|
|
741
|
+
_49_ausdruecklicher_aufruf, M49_AUFRUF)
|
|
742
|
+
|
|
743
|
+
gegenprobe("49c", "Ein Skill MIT Modellzulassung bleibt nackt zulaessig - der Zuschnitt "
|
|
744
|
+
"ist nicht zu breit", _49_modellaufrufbar, M49_AUFRUF)
|
|
745
|
+
|
|
746
|
+
gegenprobe("49d", "Derselbe Name in einer anderen Spalte bleibt zulaessig - die Regel "
|
|
747
|
+
"gilt dem Ausloeser", _49_andere_spalte, M49_AUFRUF)
|
|
748
|
+
|
|
749
|
+
gegenprobe("49e", "Eine nackte Nennung bei Pruefmethode `review` bleibt zulaessig - "
|
|
750
|
+
"eine Durchsicht ruft keinen Skill auf", _49_andere_pruefmethode,
|
|
751
|
+
M49_AUFRUF)
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
# --- Gegenstand 2: der Ausloeser, der eine UEBUNG nennt (D-172) ----------------------
|
|
755
|
+
#
|
|
756
|
+
# FW-PO-02 nennt keinen Skill und erbt doch vier: Sein Ausloeser verweist auf UE3. Der
|
|
757
|
+
# Zuschnitt ist SCHMAL - gefragt wird, ob UEBERHAUPT ein ausdruecklicher Aufruf
|
|
758
|
+
# dasteht. Die beiden Gegenproben belegen genau das: eine fuer den bewussten Zuschnitt
|
|
759
|
+
# (FW-SC-01 nennt UE3 und ruft nur den dritten Schritt auf), eine fuer die Uebung ohne
|
|
760
|
+
# gesperrten Skill.
|
|
761
|
+
M49_UEBUNG = "und damit deren Ablauf"
|
|
762
|
+
M49_UEBUNGSANKER = "führt keinen Abschnitt der Form"
|
|
763
|
+
P49_UEBUNGSDATEI = ".koolie/core/onboarding/exercises/EXERCISES.md".replace("/", os.sep)
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
def _49_uebung_ohne_aufruf(root: str) -> None:
|
|
767
|
+
"""Ein Ausloeser, der eine Uebung mit gesperrten Skills nennt und keinen Aufruf."""
|
|
768
|
+
_49_katalogzeile(root,
|
|
769
|
+
"| FW-SO-08 | Sondenzeile | Sondenvorbedingung | Ü3 aus "
|
|
770
|
+
"`.koolie/core/onboarding/exercises/EXERCISES.md` | Ablehnung | Zugriff "
|
|
771
|
+
"| sitzung | offen |")
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
def _49_uebung_mit_einem_aufruf(root: str) -> None:
|
|
775
|
+
"""Dieselbe Uebung, aber ein Schritt ausdruecklich aufgerufen - der Fall FW-SC-01."""
|
|
776
|
+
_49_katalogzeile(root,
|
|
777
|
+
"| FW-SO-09 | Sondenzeile | Sondenvorbedingung | Ü3-Änderung, ausgelöst über "
|
|
778
|
+
"`/%s` | Ablehnung | Zugriff | sitzung | bestanden (Sondenbeleg, `.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md`; Client Pack `claude-code` 2.1.278) |"
|
|
779
|
+
% _49_skill_ohne_modell(root))
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
def _49_uebung_ohne_gesperrten_skill(root: str) -> None:
|
|
783
|
+
"""Eine Uebung, deren Abschnitt nur modellaufrufbare Skills fuehrt - UE1/UE2."""
|
|
784
|
+
_49_katalogzeile(root,
|
|
785
|
+
"| FW-SO-10 | Sondenzeile | Sondenvorbedingung | Ü1 aus "
|
|
786
|
+
"`.koolie/core/onboarding/exercises/EXERCISES.md` | Ablehnung | Zugriff "
|
|
787
|
+
"| sitzung | bestanden (Sondenbeleg, `.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md`; Client Pack `claude-code` 2.1.278) |")
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
def _49_uebungsanker_verlieren(root: str) -> None:
|
|
791
|
+
"""Ohne die Abschnittsueberschriften hat Gegenstand 2 keine Uebungen mehr."""
|
|
792
|
+
pfad = P(root, P49_UEBUNGSDATEI)
|
|
793
|
+
text = lies(pfad)
|
|
794
|
+
if "\n## Ü" not in text:
|
|
795
|
+
raise Praeparationsfehler(
|
|
796
|
+
"EXERCISES.md fuehrt keinen Abschnitt '## Ü<n>' - die Ankersonde zu 49 "
|
|
797
|
+
"haette nichts zu entfernen")
|
|
798
|
+
schreib(pfad, text.replace("\n## Ü", "\n## Uebung "))
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
sonde("49c", "Ein Ausloeser nennt eine Uebung mit vier gesperrten Skills und keinen "
|
|
802
|
+
"einzigen ausdruecklichen Aufruf - der Fall FW-PO-02",
|
|
803
|
+
_49_uebung_ohne_aufruf, M49_UEBUNG)
|
|
804
|
+
|
|
805
|
+
sonde("49d", "Ohne die Abschnittsueberschriften der Uebungsdatei meldet Gegenstand 2 "
|
|
806
|
+
"den verlorenen Anker, statt leise zu bestehen", _49_uebungsanker_verlieren,
|
|
807
|
+
M49_UEBUNGSANKER)
|
|
808
|
+
|
|
809
|
+
gegenprobe("49f", "Dieselbe Uebung mit EINEM ausdruecklichen Aufruf bleibt zulaessig - "
|
|
810
|
+
"der bewusste Zuschnitt von FW-SC-01", _49_uebung_mit_einem_aufruf,
|
|
811
|
+
M49_UEBUNG)
|
|
812
|
+
|
|
813
|
+
gegenprobe("49g", "Eine Uebung, deren Abschnitt keinen gesperrten Skill fuehrt, bleibt "
|
|
814
|
+
"ohne Aufruf zulaessig", _49_uebung_ohne_gesperrten_skill, M49_UEBUNG)
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
# --- Pruefung 50: Vollstaendigkeit des Klaerungspunktregisters (D-147) -------------
|
|
818
|
+
M50_FEHLT = "steht in keiner Registerzeile"
|
|
819
|
+
M50_ANKER = "hat ihren Anker verloren"
|
|
820
|
+
P50_LOG = ".koolie/core/governance/DECISION_LOG.md".replace("/", os.sep)
|
|
821
|
+
P50_ROADMAP = ".koolie/core/docs/ROADMAP.md".replace("/", os.sep)
|
|
822
|
+
# Eine Kennung, die es im Register nicht gibt und nie geben wird - die Sonde vergibt
|
|
823
|
+
# keine echte. 'Eine synthetische Kennung nimmt nie die naechste freie' (0.59.0).
|
|
824
|
+
#
|
|
825
|
+
# ZUSAMMENGESETZT, und das ist kein Trick, sondern der Gegenstand: Dieses Skript liegt
|
|
826
|
+
# im Kern, und Pruefung 50 meldet jede dort GENANNTE Kennung ohne Registerzeile. Stuende
|
|
827
|
+
# sie woertlich hier, muesste sie in die Ausnahmemenge - und dann meldete die Sonde
|
|
828
|
+
# nichts mehr. Eine Sonde, deren Gegenstand die eigene Nennung ist, darf sich nicht
|
|
829
|
+
# selbst nennen - auch nicht in dem Kommentar, der das erklaert. Der erste Entwurf
|
|
830
|
+
# dieses Absatzes tat es, und Pruefung 50 hat ihn gemeldet.
|
|
831
|
+
K50_SYNTH = "K-" + "95"
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
def _50_freie_kennung(root: str) -> str:
|
|
835
|
+
"""Belegt, dass die Sondenkennung im Register wirklich fehlt - sonst misst sie nichts."""
|
|
836
|
+
if ("| " + K50_SYNTH + " |") in lies(P(root, P50_LOG)):
|
|
837
|
+
raise Praeparationsfehler(
|
|
838
|
+
"%s steht bereits im Register - die Sonde zu 50 braucht eine freie Kennung"
|
|
839
|
+
% K50_SYNTH)
|
|
840
|
+
return K50_SYNTH
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
def _50_nennung_ohne_register(root: str) -> None:
|
|
844
|
+
"""Eine Kennung wird in einem Kerntraeger genannt und steht in keiner Registerzeile.
|
|
845
|
+
|
|
846
|
+
Genau der Fall von K-34 (sieben Traeger, seit 0.32.0) und K-55 (drei Traeger, als
|
|
847
|
+
'neu' angekuendigt und nie eingetragen).
|
|
848
|
+
"""
|
|
849
|
+
kennung = _50_freie_kennung(root)
|
|
850
|
+
pfad = P(root, P50_ROADMAP)
|
|
851
|
+
schreib(pfad, lies(pfad).rstrip("\r\n") + "\r\n\r\n"
|
|
852
|
+
+ "Sondennachtrag: Offen bleibt die Frage nach dem Sondengegenstand (%s).\r\n"
|
|
853
|
+
% kennung)
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
def _50_anker_verlieren(root: str) -> None:
|
|
857
|
+
"""Ohne den Absatz mit den synthetischen Kennungen hat Pruefung 50 keine Ausnahme mehr.
|
|
858
|
+
|
|
859
|
+
Sie leitet sie von dort ab; geht der Absatz verloren, meldete sie jede Sondenkennung
|
|
860
|
+
des Pruefapparats als Befund - oder, schlimmer, man naehme die Liste in den Code.
|
|
861
|
+
"""
|
|
862
|
+
ersetze(P(root, P50_LOG),
|
|
863
|
+
("**Belegte synthetische Kennungen", "**Frueher belegte Kennungen"))
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
def _50_nennung_mit_register(root: str) -> None:
|
|
867
|
+
"""Dieselbe Nennung MIT Registerzeile bleibt zulaessig - das ist der erlaubte Fall."""
|
|
868
|
+
kennung = _50_freie_kennung(root)
|
|
869
|
+
_50_nennung_ohne_register(root)
|
|
870
|
+
zeile_nach(P(root, P50_LOG), "| K-56 | Ein dezentrales Testblatt",
|
|
871
|
+
"| %s | Sondenfrage? | niedrig | Sondenbegruendung | Sondenweg | offen |"
|
|
872
|
+
% kennung)
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
def _50_synthetische_kennung(root: str) -> None:
|
|
876
|
+
"""Eine synthetische Kennung des Pruefapparats bleibt ohne Registerzeile zulaessig.
|
|
877
|
+
|
|
878
|
+
Ohne dieses Paar meldete die Pruefung ihre eigenen Sonden - der Zuschnitt waere zu
|
|
879
|
+
breit, und die Ausnahme haette keinen belegten Gegenstand.
|
|
880
|
+
"""
|
|
881
|
+
pfad = P(root, P50_ROADMAP)
|
|
882
|
+
schreib(pfad, lies(pfad).rstrip("\r\n") + "\r\n\r\n"
|
|
883
|
+
+ "Sondennachtrag: Die Gegenprobe benutzt die synthetische Kennung K-99.\r\n")
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
sonde("50a", "Eine Kennung, die ein Kerntraeger nennt und das Register nicht fuehrt, "
|
|
887
|
+
"wird gemeldet - der Fall von K-34 und K-55", _50_nennung_ohne_register,
|
|
888
|
+
M50_FEHLT)
|
|
889
|
+
|
|
890
|
+
sonde("50b", "Ohne den Absatz mit den synthetischen Kennungen meldet Pruefung 50 den "
|
|
891
|
+
"verlorenen Anker, statt leise zu bestehen", _50_anker_verlieren, M50_ANKER)
|
|
892
|
+
|
|
893
|
+
gegenprobe("50a", "Das unveraenderte Repositorium bleibt unbeanstandet - K-34 und K-55 "
|
|
894
|
+
"sind nachgetragen", None, M50_FEHLT)
|
|
895
|
+
|
|
896
|
+
gegenprobe("50b", "Dieselbe Nennung MIT Registerzeile bleibt zulaessig",
|
|
897
|
+
_50_nennung_mit_register, M50_FEHLT)
|
|
898
|
+
|
|
899
|
+
gegenprobe("50c", "Eine synthetische Kennung des Pruefapparats bleibt ohne Registerzeile "
|
|
900
|
+
"zulaessig - der Zuschnitt ist nicht zu breit", _50_synthetische_kennung,
|
|
901
|
+
M50_FEHLT)
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
# --- Pruefung 51: Ausfuellschlitz fuer einen festgelegten Overlay-Wert (D-150) -----
|
|
905
|
+
M51_SCHLITZ = "trägt einen Ausfüllschlitz, obwohl"
|
|
906
|
+
M51_ANKER = "Kontextquellentabelle mit dem Kopf"
|
|
907
|
+
P51_QUELLE = ".koolie/core/templates/project-overlay/OVERLAY.md".replace("/", os.sep)
|
|
908
|
+
P51_LAUFZEIT = (".koolie/core/framework/runtime/rules/20-project-overlay.md"
|
|
909
|
+
.replace("/", os.sep))
|
|
910
|
+
# Der Stand VOR 0.61.0, woertlich. Die Sonde stellt ihn wieder her: Sie misst genau den
|
|
911
|
+
# Befund, den dieses Release behoben hat, und nicht einen nachgebauten.
|
|
912
|
+
P51_ALTZEILE = '- Freigegebene externe Domains: `<TBD: Liste oder „keine">`'
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
def _zeile_ersetzen(pfad: str, praefix: str, neu: str) -> None:
|
|
916
|
+
"""Die eine Zeile, die mit `praefix` beginnt, ganz ersetzen.
|
|
917
|
+
|
|
918
|
+
Fuer eine Praeparation, deren Gegenstand eine ganze Zeile ist, taugt kein Suchtext
|
|
919
|
+
ueber den Zeileninhalt: Er waere die Zeile selbst und muesste bei jeder Umformulierung
|
|
920
|
+
nachgezogen werden. Der Praefix ist der Feldname, und der ist der Gegenstand.
|
|
921
|
+
"""
|
|
922
|
+
zeilen = lies(pfad).split("\r\n")
|
|
923
|
+
treffer = [i for i, z in enumerate(zeilen) if z.startswith(praefix)]
|
|
924
|
+
if len(treffer) != 1:
|
|
925
|
+
raise Praeparationsfehler(
|
|
926
|
+
"%s: Praefix %r steht %dx am Zeilenanfang, erwartet genau einmal"
|
|
927
|
+
% (os.path.basename(pfad), praefix, len(treffer)))
|
|
928
|
+
zeilen[treffer[0]] = neu
|
|
929
|
+
schreib(pfad, "\r\n".join(zeilen))
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
def _51_schlitz_zurueck(root: str) -> None:
|
|
933
|
+
"""Der Stand vor 0.61.0: die Laufzeitfassung bietet an, was die Quelle ausschliesst."""
|
|
934
|
+
_zeile_ersetzen(P(root, P51_LAUFZEIT), "- Freigegebene externe Domains:", P51_ALTZEILE)
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
def _51_anker_verlieren(root: str) -> None:
|
|
938
|
+
"""Ohne die Kontextquellentabelle hat Pruefung 51 keine Feldmenge mehr.
|
|
939
|
+
|
|
940
|
+
Sie leitet sie von dort ab; geht der Kopf verloren, pruefte sie nichts und bestuende
|
|
941
|
+
leise - genau die Bauform, die D-23 ausschliesst.
|
|
942
|
+
"""
|
|
943
|
+
ersetze(P(root, P51_QUELLE),
|
|
944
|
+
("| Kontextquelle | Kontextklasse | Freigabe | Bedingungen |",
|
|
945
|
+
"| Quelle | Klasse | Freigabe | Bedingungen |"))
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
def _51_quelle_oeffnet(root: str) -> None:
|
|
949
|
+
"""Legt die QUELLE den Wert nicht fest, ist der Schlitz zulaessig - beides zusammen.
|
|
950
|
+
|
|
951
|
+
Das Paar belegt, dass die Pruefung die Quelle liest und nicht ein verdrahtetes Feld:
|
|
952
|
+
Derselbe Schlitz, der eben gemeldet wurde, bleibt unbeanstandet, sobald die Vorlage
|
|
953
|
+
ihn selbst offen laesst.
|
|
954
|
+
"""
|
|
955
|
+
_51_schlitz_zurueck(root)
|
|
956
|
+
ersetze(P(root, P51_QUELLE),
|
|
957
|
+
("| Freigegebene externe Domains (Fetch) | K0 | **„keine\"** |",
|
|
958
|
+
"| Freigegebene externe Domains (Fetch) | K0 | `<TBD: Liste oder "
|
|
959
|
+
"„keine\">` |"))
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
def _51_fremdes_feld(root: str) -> None:
|
|
963
|
+
"""Ein Schlitz fuer ein Feld, das die Quellentabelle nicht fuehrt, bleibt zulaessig."""
|
|
964
|
+
zeile_nach(P(root, P51_LAUFZEIT), "- Freigegebene externe Domains:",
|
|
965
|
+
"- Freigegebene Sondenquellen: `<TBD: Liste oder „keine\">`")
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
sonde("51a", "Ein Ausfuellschlitz in der Laufzeitfassung fuer einen Wert, den die "
|
|
969
|
+
"Overlay-Vorlage festlegt, wird gemeldet", _51_schlitz_zurueck, M51_SCHLITZ)
|
|
970
|
+
|
|
971
|
+
sonde("51b", "Ohne den Kopf der Kontextquellentabelle meldet Pruefung 51 die verlorene "
|
|
972
|
+
"Feldmenge, statt leise zu bestehen", _51_anker_verlieren, M51_ANKER)
|
|
973
|
+
|
|
974
|
+
gegenprobe("51a", "Das unveraenderte Repositorium bleibt unbeanstandet - die Domainzeile "
|
|
975
|
+
"traegt seit 0.61.0 den festen Wert", None, M51_SCHLITZ)
|
|
976
|
+
|
|
977
|
+
gegenprobe("51b", "Laesst die Quelle den Wert selbst offen, bleibt derselbe Schlitz "
|
|
978
|
+
"zulaessig - die Pruefung liest die Vorlage", _51_quelle_oeffnet,
|
|
979
|
+
M51_SCHLITZ)
|
|
980
|
+
|
|
981
|
+
gegenprobe("51c", "Ein Schlitz fuer ein Feld ausserhalb der Quellentabelle bleibt "
|
|
982
|
+
"zulaessig - der Zuschnitt ist nicht zu breit", _51_fremdes_feld,
|
|
983
|
+
M51_SCHLITZ)
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
# --- Pruefung 52: V6-Gegenstand mit Freigabefolge (D-151) --------------------------
|
|
987
|
+
M52_FOLGE = "deren Rechtsfolge eine Freigabe ist"
|
|
988
|
+
M52_ANKER = "Delegationsverbotsliste ist nicht mehr auffindbar"
|
|
989
|
+
P52_LAUFZEIT = (".koolie/core/framework/runtime/rules/10-privacy-security.md"
|
|
990
|
+
.replace("/", os.sep))
|
|
991
|
+
P52_RISIKO = ".koolie/core/framework/core/09-risk-model.md".replace("/", os.sep)
|
|
992
|
+
P52_CL06 = ".koolie/core/checklists/06-security.md".replace("/", os.sep)
|
|
993
|
+
# Woertlich der Stand vor 0.61.0 - sechzig Releases lang stand er so.
|
|
994
|
+
P52_ALTSATZ = (
|
|
995
|
+
"Authentifizierung, Autorisierung, Sitzungsverwaltung, Kryptografie, "
|
|
996
|
+
"Security-Konfiguration, Eingabevalidierung an Systemgrenzen, Verarbeitung "
|
|
997
|
+
"personenbezogener Daten: Kontrollstufe hoch. Nur analysieren und planen; Umsetzung "
|
|
998
|
+
"ausschließlich nach dokumentierter Freigabe durch `<APPROVAL_ROLE>` und "
|
|
999
|
+
"`<SECURITY_CONTACT>`."
|
|
1000
|
+
)
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
def _52_altsatz_zurueck(root: str) -> None:
|
|
1004
|
+
"""Der Stand vor 0.61.0: ein Delegationsverbot in der Aufzaehlung mit Freigabefolge."""
|
|
1005
|
+
_zeile_ersetzen(P(root, P52_LAUFZEIT),
|
|
1006
|
+
"Stufe hoch: Authentifizierung, Autorisierung, Sitzungsverwaltung,",
|
|
1007
|
+
P52_ALTSATZ)
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
def _52_anker_verlieren(root: str) -> None:
|
|
1011
|
+
"""Ohne die V6-Zeile hat Pruefung 52 keine Begriffe mehr - sie leitet sie von dort ab."""
|
|
1012
|
+
ersetze(P(root, P52_RISIKO),
|
|
1013
|
+
("| V6 | Änderungen an Produktionssystemen",
|
|
1014
|
+
"| V6-alt | Änderungen an Produktionssystemen"))
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
def _52_nur_anwendungslogik(root: str) -> None:
|
|
1018
|
+
"""Dieselbe Freigabefolge OHNE V6-Gegenstand bleibt zulaessig - das ist G-04."""
|
|
1019
|
+
zeile_nach(P(root, P52_CL06),
|
|
1020
|
+
"## Abbruch- und Eskalationskriterien",
|
|
1021
|
+
"\r\nSondennachtrag: Eine Änderung an Kryptografie oder "
|
|
1022
|
+
"Sitzungsverwaltung ist Kontrollstufe hoch; die Umsetzung erfolgt nach "
|
|
1023
|
+
"dokumentierter Freigabe durch `<APPROVAL_ROLE>`.")
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
def _52_ohne_freigabefolge(root: str) -> None:
|
|
1027
|
+
"""Ein V6-Gegenstand OHNE Freigabefolge bleibt zulaessig - die Regel gilt dem Paar."""
|
|
1028
|
+
zeile_nach(P(root, P52_CL06),
|
|
1029
|
+
"## Abbruch- und Eskalationskriterien",
|
|
1030
|
+
"\r\nSondennachtrag: Eine Sicherheitskonfiguration mit Schutzwirkung ist "
|
|
1031
|
+
"Kontrollstufe hoch und nicht delegierbar; zulässig sind Analyse und "
|
|
1032
|
+
"Planvorschlag.")
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
def _52_langform_ausgenommen(root: str) -> None:
|
|
1036
|
+
"""Die Langform, aus der die Begriffe stammen, darf beide Seiten in einem Absatz nennen.
|
|
1037
|
+
|
|
1038
|
+
Ohne diese Ausnahme meldete die Pruefung ausgerechnet den Text, der die Abgrenzung
|
|
1039
|
+
ZIEHT - und die Ausnahme ist abgeleitet: es ist die Datei, aus der gelesen wurde.
|
|
1040
|
+
"""
|
|
1041
|
+
zeile_nach(P(root, P52_RISIKO),
|
|
1042
|
+
"## 5. Anwendungshinweise (Erläuterung)",
|
|
1043
|
+
"\r\nSondennachtrag zur Abgrenzung: Eine Sicherheitskonfiguration bleibt "
|
|
1044
|
+
"V6; eine Berechtigungsprüfung in der Anwendungslogik ist Kontrollstufe "
|
|
1045
|
+
"hoch, und ihre Umsetzung erfolgt nach dokumentierter Freigabe.")
|
|
1046
|
+
|
|
1047
|
+
|
|
1048
|
+
sonde("52a", "Ein Gegenstand von V6 in einer Aufzaehlung mit Freigabefolge wird gemeldet "
|
|
1049
|
+
"- der Stand vor 0.61.0", _52_altsatz_zurueck, M52_FOLGE)
|
|
1050
|
+
|
|
1051
|
+
sonde("52b", "Ohne die V6-Zeile der Delegationsverbotsliste meldet Pruefung 52 den "
|
|
1052
|
+
"verlorenen Gegenstand, statt leise zu bestehen", _52_anker_verlieren,
|
|
1053
|
+
M52_ANKER)
|
|
1054
|
+
|
|
1055
|
+
gegenprobe("52a", "Das unveraenderte Repositorium bleibt unbeanstandet - beide Fassungen "
|
|
1056
|
+
"trennen seit 0.61.0 Anwendungslogik vom Betrieb", None, M52_FOLGE)
|
|
1057
|
+
|
|
1058
|
+
gegenprobe("52b", "Dieselbe Freigabefolge ohne einen Gegenstand von V6 bleibt zulaessig - "
|
|
1059
|
+
"das ist der erlaubte Fall", _52_nur_anwendungslogik, M52_FOLGE)
|
|
1060
|
+
|
|
1061
|
+
gegenprobe("52c", "Ein Gegenstand von V6 ohne Freigabefolge bleibt zulaessig - die Regel "
|
|
1062
|
+
"gilt dem Paar, nicht dem Wort", _52_ohne_freigabefolge, M52_FOLGE)
|
|
1063
|
+
|
|
1064
|
+
gegenprobe("52d", "Die Langform, aus der die Begriffe stammen, bleibt ausgenommen - sie "
|
|
1065
|
+
"zieht die Abgrenzung und nennt beide Seiten", _52_langform_ausgenommen,
|
|
1066
|
+
M52_FOLGE)
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
# --- Pruefung 53: Die Kriterium-2-Kette des Releaseplans (D-153) -------------------
|
|
1070
|
+
M53_KETTE = "Kette des Releaseplans reißt zwischen"
|
|
1071
|
+
M53_NULL = "Kette des Releaseplans endet bei"
|
|
1072
|
+
M53_ANKER = "liest den Releaseplan darunter"
|
|
1073
|
+
P53_ROADMAP = ".koolie/core/docs/ROADMAP.md".replace("/", os.sep)
|
|
1074
|
+
P53_UEBERSCHRIFT = "#### Der Releaseplan bis 1.0.0 und darüber hinaus"
|
|
1075
|
+
# Genau der Fehler, den 0.60.0 gemergt hat: Die Zelle wurde aus dem Posten genommen, seine
|
|
1076
|
+
# Zahl nachgezogen - und die des Folgepostens blieb stehen.
|
|
1077
|
+
P53_KETTE_SUCH = "Kriterium 2: **"
|
|
1078
|
+
P53_GLIED_RE = re.compile(r"Kriterium 2: \*\*(\d+) → (\d+)\*\*")
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
# 🔴 DER ANKER IST ABGELEITET, NICHT GEPFLEGT - UND DAS ZUM DRITTEN MAL IN DREI
|
|
1082
|
+
# RELEASES. Bis 0.67.0 stand er hier als feste Zeichenkette ("**85 → 0**"), also auf
|
|
1083
|
+
# dem Inhalt EINES Postens. 0.63.0 hat dieselbe Bauform schon einmal an Gegenprobe 53b
|
|
1084
|
+
# behoben und den Fall im Kopfkommentar dort beschrieben - die beiden SONDEN blieben
|
|
1085
|
+
# gepflegt. Der Umbau des Releaseplans in 0.67.0 (ein Posten wird zu sieben) hat 53a
|
|
1086
|
+
# prompt fallen lassen: "Praeparation gebrochen".
|
|
1087
|
+
# Eine Abhilfe gilt fuer die Stelle, an der sie eingetragen wird, nicht fuer die
|
|
1088
|
+
# Bauform. Wer eine findet, sucht ihre Geschwister im selben Block.
|
|
1089
|
+
def _53_letztes_glied(root: str) -> str:
|
|
1090
|
+
"""Die LETZTE Kettenzeile des Plans - sie schliesst die Kette und endet bei null."""
|
|
1091
|
+
text = lies(P(root, P53_ROADMAP))
|
|
1092
|
+
kette = [z for z in text.replace("\r\n", "\n").split("\n")
|
|
1093
|
+
if P53_KETTE_SUCH in z and P53_GLIED_RE.search(z)]
|
|
1094
|
+
if not kette:
|
|
1095
|
+
raise Praeparationsfehler(
|
|
1096
|
+
"ROADMAP.md: keine Zeile mit einer Kriterium-2-Kette gefunden - die Sonde "
|
|
1097
|
+
"zu 53 haette keinen Anker")
|
|
1098
|
+
return kette[-1]
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
def _53_kette_reissen(root: str) -> None:
|
|
1102
|
+
"""Der Stand vor 0.61.0: Der Folgeposten beginnt um eins unter dem Vorgaengerende."""
|
|
1103
|
+
glied = _53_letztes_glied(root)
|
|
1104
|
+
m = P53_GLIED_RE.search(glied)
|
|
1105
|
+
kaputt = P53_GLIED_RE.sub(
|
|
1106
|
+
"Kriterium 2: **%d → %s**" % (int(m.group(1)) - 1, m.group(2)), glied)
|
|
1107
|
+
ersetze(P(root, P53_ROADMAP), (glied, kaputt))
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
def _53_null_verfehlen(root: str) -> None:
|
|
1111
|
+
"""Ein Plan, der nicht bei null ankommt, fuehrt nicht bis 1.0.0."""
|
|
1112
|
+
glied = _53_letztes_glied(root)
|
|
1113
|
+
m = P53_GLIED_RE.search(glied)
|
|
1114
|
+
kaputt = P53_GLIED_RE.sub(
|
|
1115
|
+
"Kriterium 2: **%s → %d**" % (m.group(1), int(m.group(2)) + 1), glied)
|
|
1116
|
+
ersetze(P(root, P53_ROADMAP), (glied, kaputt))
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
def _53_anker_verlieren(root: str) -> None:
|
|
1120
|
+
"""Ohne die Ueberschrift liest Pruefung 53 keinen Plan - und sagt es."""
|
|
1121
|
+
ersetze(P(root, P53_ROADMAP),
|
|
1122
|
+
(P53_UEBERSCHRIFT, "#### Der Plan bis 1.0.0"))
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
def _53_glied_anfuegen(root: str) -> None:
|
|
1126
|
+
"""Ein weiterer Posten, der die Kette fortsetzt, bleibt zulaessig.
|
|
1127
|
+
|
|
1128
|
+
Die Pruefung rechnet eine Kette nach und zaehlt keine Posten; ohne dieses Paar waere
|
|
1129
|
+
nicht belegt, dass sie dem Plan folgt statt einer festen Laenge.
|
|
1130
|
+
"""
|
|
1131
|
+
# DER ANKER IST ABGELEITET, NICHT GEPFLEGT - und das ist mit 0.63.0 noetig
|
|
1132
|
+
# geworden: Er stand zweimal in zwei Releases auf einer Postennummer, und beide
|
|
1133
|
+
# Male hat die Verschiebung des Releaseplans die Gegenprobe fallen lassen
|
|
1134
|
+
# ("Praeparation gebrochen"). Gesucht wird die LETZTE Zeile der Kette; dahinter
|
|
1135
|
+
# gehoert der Sondenposten, damit die Kette geschlossen bleibt.
|
|
1136
|
+
text = lies(P(root, P53_ROADMAP))
|
|
1137
|
+
kette = [z for z in text.replace("\r\n", "\n").split("\n")
|
|
1138
|
+
if P53_KETTE_SUCH in z]
|
|
1139
|
+
if not kette:
|
|
1140
|
+
raise Praeparationsfehler(
|
|
1141
|
+
"ROADMAP.md: keine Zeile mit einer Kriterium-2-Kette gefunden - die "
|
|
1142
|
+
"Gegenprobe haette keinen Anker")
|
|
1143
|
+
zeile_nach(P(root, P53_ROADMAP), kette[-1].strip(),
|
|
1144
|
+
"| **~0.99.0** | Sondenposten | Kriterium 2: **0 → 0** | nein |")
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
def _53_nennung_vor_dem_plan(root: str) -> None:
|
|
1148
|
+
"""Eine Kriterium-2-Angabe VOR der Ueberschrift bleibt zulaessig - der Zuschnitt beginnt dort."""
|
|
1149
|
+
ersetze(P(root, P53_ROADMAP),
|
|
1150
|
+
(P53_UEBERSCHRIFT,
|
|
1151
|
+
"Sondennachtrag: Eine Vorhersage ausserhalb des Plans, Kriterium 2: "
|
|
1152
|
+
"**99 → 1**.\r\n\r\n" + P53_UEBERSCHRIFT))
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
sonde("53a", "Ein Folgeposten, der unter dem Ende seines Vorgaengers beginnt, wird "
|
|
1156
|
+
"gemeldet - genau der Fehler, den 0.60.0 gemergt hat", _53_kette_reissen,
|
|
1157
|
+
M53_KETTE)
|
|
1158
|
+
|
|
1159
|
+
sonde("53b", "Ein Plan, dessen Kette nicht bei null ankommt, wird gemeldet - Kriterium 2 "
|
|
1160
|
+
"muss dort ankommen", _53_null_verfehlen, M53_NULL)
|
|
1161
|
+
|
|
1162
|
+
sonde("53c", "Ohne die Ueberschrift des Releaseplans meldet Pruefung 53 den verlorenen "
|
|
1163
|
+
"Gegenstand, statt leise zu bestehen", _53_anker_verlieren, M53_ANKER)
|
|
1164
|
+
|
|
1165
|
+
gegenprobe("53a", "Das unveraenderte Repositorium bleibt unbeanstandet - die Kette "
|
|
1166
|
+
"schliesst und endet bei null", None, M53_KETTE)
|
|
1167
|
+
|
|
1168
|
+
gegenprobe("53b", "Ein weiterer Posten, der die Kette fortsetzt, bleibt zulaessig - "
|
|
1169
|
+
"gerechnet wird die Kette, nicht die Laenge", _53_glied_anfuegen,
|
|
1170
|
+
M53_KETTE)
|
|
1171
|
+
|
|
1172
|
+
gegenprobe("53c", "Eine Kriterium-2-Angabe vor der Ueberschrift bleibt zulaessig - der "
|
|
1173
|
+
"Zuschnitt beginnt am Plan", _53_nennung_vor_dem_plan, M53_KETTE)
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
# --- Pruefung 54: Zusatzschluessel auf der deklarierten Ebene (D-155) --------------
|
|
1177
|
+
#
|
|
1178
|
+
# ZWEI ZUSCHNITTE, UND DER ZWEITE IST DER WICHTIGERE. Das Repositorium traegt eine
|
|
1179
|
+
# devin-desktop-Testinstallation, und dieses Pack fuehrt settings_extra ABSICHTLICH leer.
|
|
1180
|
+
# Eine Sonde auf der Kopie des Repositoriums belegt deshalb nur die Deklarationspflicht.
|
|
1181
|
+
# Was der Befund von 0.62.0 verlangt - dass ein Schluessel mit WERT auf der richtigen
|
|
1182
|
+
# EBENE ankommt -, ist nur an einer claude-code-Installation zu messen. Das ist B02: nicht,
|
|
1183
|
+
# dass eine Pruefung falsch prueft, sondern dass sie einen Client nicht sieht.
|
|
1184
|
+
M54_FEHLT_FELD = "Feld settings_extra fehlt"
|
|
1185
|
+
M54_FEHLT_KEY = "aus settings_extra fehlt in der obersten Ebene"
|
|
1186
|
+
M54_EBENE = "steht in dem Objekt permissions statt in der obersten Ebene"
|
|
1187
|
+
M54_WERT = "das Manifest deklariert in settings_extra aber"
|
|
1188
|
+
MAN_DD_54 = ".koolie/core/clients/devin-desktop/manifest.json".replace("/", os.sep)
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
def _54_deklaration_fehlt(root: str) -> None:
|
|
1192
|
+
"""Das Pack fuehrt das Feld gar nicht - der Stand jedes Packs bis 0.61.0."""
|
|
1193
|
+
ersetze(P(root, MAN_DD_54), (' "settings_extra": {},\r\n', ""))
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
def _54_leeres_feld_bleibt(root: str) -> None:
|
|
1197
|
+
"""Gegenprobe: Ein leeres settings_extra ist eine Deklaration und bleibt zulaessig.
|
|
1198
|
+
|
|
1199
|
+
Ohne dieses Paar stuende nur fest, dass die Pruefung ein fehlendes Feld meldet - nicht,
|
|
1200
|
+
dass sie die ausdrueckliche Abwesenheit von der Luecke unterscheidet. Genau diese
|
|
1201
|
+
Unterscheidung ist ihr Zweck.
|
|
1202
|
+
"""
|
|
1203
|
+
ersetze(P(root, MAN_DD_54),
|
|
1204
|
+
(' "settings_extra": {},\r\n',
|
|
1205
|
+
' "settings_extra": {},\r\n "_sonde_54": "leer ist eine Deklaration",\r\n'))
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
def _cc_manifest_54(root: str) -> str:
|
|
1209
|
+
return os.path.join(root, ".koolie/core", "clients", "claude-code", "manifest.json")
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
def sonden_zusatzschluessel() -> None:
|
|
1213
|
+
"""Wirkungsnachweis an einer claude-code-Installation (D-155).
|
|
1214
|
+
|
|
1215
|
+
Gemessen wird an der ERZEUGTEN Datei, nicht am Manifest: Die Pruefung fragt, ob die
|
|
1216
|
+
Verschaerfung ankommt, und das entscheidet die Abbildung, nicht die Deklaration.
|
|
1217
|
+
"""
|
|
1218
|
+
root = installation("claude-code")
|
|
1219
|
+
try:
|
|
1220
|
+
rechte = os.path.join(root, ".claude", "settings.json")
|
|
1221
|
+
ausgang = lies(rechte)
|
|
1222
|
+
|
|
1223
|
+
# --- Gegenprobe: die frische Installation traegt den Schluessel --------------
|
|
1224
|
+
# Sie ist hier die wichtigere Haelfte: Sie belegt, dass die Abbildung aus
|
|
1225
|
+
# 0.62.0 ueberhaupt etwas ausliefert. Ohne sie bewiese jede Sonde nur, dass die
|
|
1226
|
+
# Pruefung irgendetwas meldet.
|
|
1227
|
+
aus = validator_ausgabe(root)
|
|
1228
|
+
melde("GEGENPROBE", "54c", "autoMemoryEnabled" not in aus,
|
|
1229
|
+
"Die frische claude-code-Installation traegt autoMemoryEnabled auf der "
|
|
1230
|
+
"obersten Ebene und bleibt unbeanstandet")
|
|
1231
|
+
if "autoMemoryEnabled" in aus:
|
|
1232
|
+
notiz(" Ausgabe:", " | ".join(
|
|
1233
|
+
z for z in aus.splitlines() if "autoMemoryEnabled" in z)[:400])
|
|
1234
|
+
|
|
1235
|
+
# --- 54a: der Schluessel fehlt ganz - der Stand bis 0.61.0 ------------------
|
|
1236
|
+
# Die erzeugte Datei ist LF: install.py schreibt LF, git normalisiert. Ein
|
|
1237
|
+
# Suchtext mit \r\n traefe hier NICHT - anders als in den Manifest-Sonden, die
|
|
1238
|
+
# gegen das CRLF des Repositoriums laufen.
|
|
1239
|
+
schreib(rechte, ersetzt(
|
|
1240
|
+
ausgang,
|
|
1241
|
+
(' "autoMemoryEnabled": false,\n', ""),
|
|
1242
|
+
quelle=".claude/settings.json"))
|
|
1243
|
+
melde("SONDE", "54b", M54_FEHLT_KEY in validator_ausgabe(root),
|
|
1244
|
+
"Ein deklarierter Zusatzschluessel fehlt in der erzeugten Datei - die "
|
|
1245
|
+
"Verschaerfung kommt nicht an")
|
|
1246
|
+
|
|
1247
|
+
# --- 54b: der Schluessel steht auf der FALSCHEN Ebene -----------------------
|
|
1248
|
+
# Der eigentliche Gegenstand: Die Datei bleibt gueltiges JSON, der Schluessel ist
|
|
1249
|
+
# da, er wird nur nicht gelesen. Bis 0.61.0 haette nichts es gemeldet.
|
|
1250
|
+
schreib(rechte, ersetzt(
|
|
1251
|
+
ausgang,
|
|
1252
|
+
(' "autoMemoryEnabled": false,\n', ""),
|
|
1253
|
+
('"permissions": {\n "defaultMode": "default",',
|
|
1254
|
+
'"permissions": {\n "autoMemoryEnabled": false,\n '
|
|
1255
|
+
'"defaultMode": "default",'),
|
|
1256
|
+
quelle=".claude/settings.json"))
|
|
1257
|
+
melde("SONDE", "54c", M54_EBENE in validator_ausgabe(root),
|
|
1258
|
+
"Derselbe Schluessel INNERHALB von permissions - gueltiges JSON, vom "
|
|
1259
|
+
"Client nicht gelesen, und die Pruefung nennt die Ebene")
|
|
1260
|
+
|
|
1261
|
+
# --- 54c: der Wert ist ein anderer als der deklarierte ----------------------
|
|
1262
|
+
schreib(rechte, ersetzt(
|
|
1263
|
+
ausgang,
|
|
1264
|
+
(' "autoMemoryEnabled": false,\n', ' "autoMemoryEnabled": true,\n'),
|
|
1265
|
+
quelle=".claude/settings.json"))
|
|
1266
|
+
melde("SONDE", "54d", M54_WERT in validator_ausgabe(root),
|
|
1267
|
+
"Der Schluessel steht auf der richtigen Ebene und traegt den "
|
|
1268
|
+
"entgegengesetzten Wert - eine Verschaerfung, die keine ist")
|
|
1269
|
+
|
|
1270
|
+
schreib(rechte, ausgang)
|
|
1271
|
+
finally:
|
|
1272
|
+
aufraeumen(os.path.dirname(root))
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
sonde("54a", "Ein Pack fuehrt settings_extra gar nicht - der Stand jedes Packs bis "
|
|
1276
|
+
"0.61.0, und die Abwesenheit war nicht von der Luecke zu unterscheiden",
|
|
1277
|
+
_54_deklaration_fehlt, M54_FEHLT_FELD)
|
|
1278
|
+
|
|
1279
|
+
gegenprobe("54a", "Das unveraenderte Repositorium bleibt unbeanstandet - beide Packs "
|
|
1280
|
+
"fuehren beide Felder", None, M54_FEHLT_FELD)
|
|
1281
|
+
|
|
1282
|
+
gegenprobe("54b", "Ein LEERES settings_extra ist eine Deklaration und bleibt zulaessig - "
|
|
1283
|
+
"die Pruefung trennt die ausdrueckliche Abwesenheit von der Luecke",
|
|
1284
|
+
_54_leeres_feld_bleibt, M54_FEHLT_FELD)
|
|
1285
|
+
|
|
1286
|
+
buendel(sonden_zusatzschluessel,
|
|
1287
|
+
"Pruefung 54 an einer claude-code-Installation: fehlend, falsche Ebene und "
|
|
1288
|
+
"falscher Wert je eigens gemessen, dazu die unveraenderte Installation")
|
|
1289
|
+
|
|
1290
|
+
|
|
1291
|
+
# --- Pruefung 55 und 56: Pflichtplatzhalter und gesperrte Traeger (D-160, D-161) ---
|
|
1292
|
+
#
|
|
1293
|
+
# ZWEI ZUSCHNITTE, AUS EINEM GRUND: Teil (a) von Pruefung 55 liest die VORLAGE und laeuft
|
|
1294
|
+
# im gewoehnlichen Lauf. Teil (b) und Pruefung 56 lesen ein GEFUELLTES Overlay - und das
|
|
1295
|
+
# Repositorium traegt nur die unausgefuellte Vorlage, in der jeder Wert <TBD> ist.
|
|
1296
|
+
# Deshalb baut das Buendel eine frische Installation und schreibt genau die zwei
|
|
1297
|
+
# Bindungszeilen hinein, um die es geht. Alles andere an --strict-overlay meldet dort
|
|
1298
|
+
# ohnehin, und die Sonden pruefen je auf IHRE Meldung, nicht auf die Fehlerzahl.
|
|
1299
|
+
M55_VORLAGE = "kommt in der Vorlage aber nicht vor"
|
|
1300
|
+
M55_ANKER = "keine Zeile trägt 'Pflicht vor Aktivierung' = ja"
|
|
1301
|
+
M55_BINDUNG = "<ISSUE_TRACKER> wird von"
|
|
1302
|
+
M56_GESPERRT = "das dasselbe Overlay unter <EXCLUDED_PATHS> führt"
|
|
1303
|
+
P55_REG = ".koolie/core/docs/PLACEHOLDER_REGISTRY.md".replace("/", os.sep)
|
|
1304
|
+
P55_VOR = ".koolie/core/templates/project-overlay/OVERLAY.md".replace("/", os.sep)
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
def _55_vorlage_luecke(root: str) -> None:
|
|
1308
|
+
"""Ein Pflichtplatzhalter verschwindet aus der Vorlage - der Fall vom 2026-09-18."""
|
|
1309
|
+
ersetze(P(root, P55_VOR),
|
|
1310
|
+
("| Änderungsschwelle (`CHANGE_SIZE_THRESHOLD`) |",
|
|
1311
|
+
"| Änderungsschwelle |"))
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
def _55_anker_weg(root: str) -> None:
|
|
1315
|
+
"""Ohne die Pflichtspalte hat Pruefung 55 keinen Gegenstand - und sagt es."""
|
|
1316
|
+
p = P(root, P55_REG)
|
|
1317
|
+
text = lies(p)
|
|
1318
|
+
# NICHT "| ja |": Eine der 29 Zeilen traegt 'ja (oder „keine")', bliebe stehen,
|
|
1319
|
+
# und die Pflichtmenge waere nicht leer - die Sonde maesse dann nichts.
|
|
1320
|
+
schreib(p, text.replace("| ja", "| spaeter"))
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
def _55_ohne_overlayort(root: str) -> None:
|
|
1324
|
+
"""Gegenprobe: Ein Pflichtplatzhalter, den das Register NICHT im Overlay verortet,
|
|
1325
|
+
muss in der Vorlage nicht vorkommen. `<FRAMEWORK_OWNER>` wird in OWNERS.md gesetzt -
|
|
1326
|
+
ohne diesen Zuschnitt meldete die Pruefung ihn bei jedem Lauf."""
|
|
1327
|
+
p = P(root, P55_VOR)
|
|
1328
|
+
text = lies(p)
|
|
1329
|
+
schreib(p, text.replace("<FRAMEWORK_OWNER>", "<FRAMEWORK-EIGNER>"))
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
# 🔴 DIE SPITZEN KLAMMERN GEHOEREN HINEIN (K-88, D-257). Bis 0.83.0 schrieb dieser
|
|
1333
|
+
# Block `ISSUE_TRACKER` OHNE sie und nannte das eine Bindung - er kam damit durch, weil
|
|
1334
|
+
# Pruefung 55b `if name in text` fragte. **Die Gegenprobe deckte die Luecke der Pruefung,
|
|
1335
|
+
# und die Pruefung die der Gegenprobe.** Mit der geschaerften Pruefung faellt die alte
|
|
1336
|
+
# Form, und genau das ist ihr Wirkungsnachweis.
|
|
1337
|
+
BINDUNGEN = (
|
|
1338
|
+
"\n## Sondenabschnitt (nur fuer den Wirkungsnachweis)\n\n"
|
|
1339
|
+
"| Element | Platzhalter | Wert |\n|---|---|---|\n"
|
|
1340
|
+
"| Ticketsystem | `<ISSUE_TRACKER>` | Beispiel-Ticketsystem |\n"
|
|
1341
|
+
"| Merge-Request-Vorlage | `<MR_TEMPLATE_PATH>` | `%s` |\n"
|
|
1342
|
+
)
|
|
1343
|
+
|
|
1344
|
+
# Dieselbe Tabelle in der Form von 0.83.0: der Name OHNE Klammern. Sie ist der
|
|
1345
|
+
# Gegenstand der Sonde 55d - ein Overlay, das den Platzhalter nennt und nicht bindet.
|
|
1346
|
+
BINDUNGEN_NUR_GENANNT = BINDUNGEN.replace("`<ISSUE_TRACKER>`", "`ISSUE_TRACKER`")
|
|
1347
|
+
|
|
1348
|
+
|
|
1349
|
+
def _ov(root: str) -> str:
|
|
1350
|
+
return os.path.join(root, ".koolie/project-overlay", "OVERLAY.md")
|
|
1351
|
+
|
|
1352
|
+
|
|
1353
|
+
def sonden_platzhalterbindung() -> None:
|
|
1354
|
+
"""Wirkungsnachweis fuer Pruefung 55b und 56 an einer gefuellten Installation."""
|
|
1355
|
+
root = installation("claude-code")
|
|
1356
|
+
try:
|
|
1357
|
+
pfad = _ov(root)
|
|
1358
|
+
ausgang = lies(pfad)
|
|
1359
|
+
# Eine ausgeschlossene Pfadmenge, die nicht <TBD> ist - sonst hat 56 keinen Anker.
|
|
1360
|
+
gefuellt = ersetzt(
|
|
1361
|
+
ausgang,
|
|
1362
|
+
("`<TBD: z. B. deploy/**, infra/**, config/prod/**, **/fixtures/real/**>`",
|
|
1363
|
+
"`deploy/**`, `infra/**`"),
|
|
1364
|
+
quelle=".koolie/project-overlay/OVERLAY.md")
|
|
1365
|
+
|
|
1366
|
+
# --- Gegenprobe 55: der gebundene Platzhalter wird nicht beanstandet ---------
|
|
1367
|
+
schreib(pfad, gefuellt + BINDUNGEN % ".mr/pull_request_template.md")
|
|
1368
|
+
aus = strict_ausgabe(root)
|
|
1369
|
+
melde("GEGENPROBE", "55c", M55_BINDUNG not in aus,
|
|
1370
|
+
"Ein Overlay, das <ISSUE_TRACKER> BINDET, bleibt unbeanstandet - die "
|
|
1371
|
+
"Pruefung misst die Bindung, nicht das Vorhandensein eines Werts")
|
|
1372
|
+
|
|
1373
|
+
# --- Gegenprobe 56: derselbe Baum, Vorlage ausserhalb der Sperre -------------
|
|
1374
|
+
melde("GEGENPROBE", "56a", M56_GESPERRT not in aus,
|
|
1375
|
+
"Liegt der Wert von <MR_TEMPLATE_PATH> ausserhalb von <EXCLUDED_PATHS>, "
|
|
1376
|
+
"bleibt die Vorbedingung zulaessig")
|
|
1377
|
+
|
|
1378
|
+
# --- 55b: die Bindung fehlt, der Kerntext nennt den Platzhalter weiter -------
|
|
1379
|
+
# Der gemessene Fall ist die ERSETZUNG: Das Overlay nennt den Wert und den
|
|
1380
|
+
# Platzhalter nirgends mehr. In einer frischen Installation steht er noch in
|
|
1381
|
+
# der Prosa der Vorlage - die muss die Sonde mit entfernen, sonst gilt er als
|
|
1382
|
+
# gebunden und sie maesse nichts.
|
|
1383
|
+
ohne = gefuellt.replace("`<ISSUE_TRACKER>`", "Beispiel-Ticketsystem")
|
|
1384
|
+
schreib(pfad, ohne + (BINDUNGEN % ".mr/pull_request_template.md").replace(
|
|
1385
|
+
"| Ticketsystem | `<ISSUE_TRACKER>` | Beispiel-Ticketsystem |\n", ""))
|
|
1386
|
+
melde("SONDE", "55c", M55_BINDUNG in strict_ausgabe(root),
|
|
1387
|
+
"Das Overlay nennt den Wert, bindet den Platzhalter aber nicht - genau der "
|
|
1388
|
+
"Fall, der am 2026-09-18 fuenf Platzhalter in 65 Fundstellen unaufloesbar "
|
|
1389
|
+
"liess")
|
|
1390
|
+
|
|
1391
|
+
# --- 56: die Vorbedingung verlangt einen gesperrten Traeger ------------------
|
|
1392
|
+
schreib(pfad, gefuellt + BINDUNGEN % "deploy/pull_request_template.md")
|
|
1393
|
+
melde("SONDE", "56a", M56_GESPERRT in strict_ausgabe(root),
|
|
1394
|
+
"Eine Vorbedingung verlangt <MR_TEMPLATE_PATH>, und dessen Wert liegt "
|
|
1395
|
+
"unter einem ausgeschlossenen Pfad - die Zelle ist nicht fahrbar")
|
|
1396
|
+
|
|
1397
|
+
# --- Gegenprobe 56b: die NACHBARDATEI im selben Verzeichnis ---------------
|
|
1398
|
+
# Der erste Entwurf von Pruefung 56 verglich nur das erste Pfadsegment und
|
|
1399
|
+
# meldete `.github/pull_request_template.md` gegen `.github/workflows/**`.
|
|
1400
|
+
# Ohne dieses Paar stuende nur fest, dass die Pruefung einen gesperrten Pfad
|
|
1401
|
+
# findet - nicht, dass sie den ungesperrten Nachbarn in Ruhe laesst.
|
|
1402
|
+
nachbar = ersetzt(gefuellt, ("`deploy/**`, `infra/**`",
|
|
1403
|
+
"`deploy/gen/**`, `infra/**`"),
|
|
1404
|
+
quelle=".koolie/project-overlay/OVERLAY.md")
|
|
1405
|
+
schreib(pfad, nachbar + BINDUNGEN % "deploy/pull_request_template.md")
|
|
1406
|
+
melde("GEGENPROBE", "56b", M56_GESPERRT not in strict_ausgabe(root),
|
|
1407
|
+
"Derselbe Pfadanfang, ein anderer Pfad: `deploy/pull_request_template.md` gegen `deploy/gen/**` bleibt zulaessig - die Pruefung vergleicht Pfade, nicht Anfaenge")
|
|
1408
|
+
|
|
1409
|
+
# --- 55d: GENANNT ist nicht GEBUNDEN (K-88, D-257) --------------------------
|
|
1410
|
+
# 🔴 DER GEGENBEWEIS GEGEN DEN VORSTAND. Bis 0.83.0 fragte Pruefung 55b
|
|
1411
|
+
# `if name in text`; gegen diesen Baum haette sie GESCHWIEGEN, weil die
|
|
1412
|
+
# Buchstaben `ISSUE_TRACKER` im Overlay stehen - nur eben ohne die spitzen
|
|
1413
|
+
# Klammern, die den Kerntext aufloesen. Am Uebungsrepositorium waren es 14
|
|
1414
|
+
# von 26 Pflichtplatzhaltern, und die Pruefung meldete null.
|
|
1415
|
+
ohne_klammern = gefuellt.replace("`<ISSUE_TRACKER>`", "Beispiel-Ticketsystem")
|
|
1416
|
+
schreib(pfad, ohne_klammern
|
|
1417
|
+
+ BINDUNGEN_NUR_GENANNT % ".mr/pull_request_template.md")
|
|
1418
|
+
melde("SONDE", "55d", M55_BINDUNG in strict_ausgabe(root),
|
|
1419
|
+
"Das Overlay NENNT <ISSUE_TRACKER> (ohne spitze Klammern) und bindet ihn "
|
|
1420
|
+
"nicht - bis 0.83.0 blieb genau das unbeanstandet (K-88, D-257)")
|
|
1421
|
+
|
|
1422
|
+
# --- Gegenprobe 55d: dieselbe Tabelle MIT Klammern --------------------------
|
|
1423
|
+
schreib(pfad, ohne_klammern + BINDUNGEN % ".mr/pull_request_template.md")
|
|
1424
|
+
melde("GEGENPROBE", "55d", M55_BINDUNG not in strict_ausgabe(root),
|
|
1425
|
+
"Dieselbe Tabelle mit spitzen Klammern bleibt unbeanstandet - die "
|
|
1426
|
+
"Pruefung misst die SCHREIBWEISE der Bindung und nicht den Wert daneben")
|
|
1427
|
+
|
|
1428
|
+
schreib(pfad, ausgang)
|
|
1429
|
+
finally:
|
|
1430
|
+
aufraeumen(os.path.dirname(root))
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
sonde("55a", "Ein Pflichtplatzhalter fehlt in der Overlay-Vorlage - ein Projekt, das sie "
|
|
1434
|
+
"ausfuellt, begegnet ihm nie", _55_vorlage_luecke, M55_VORLAGE)
|
|
1435
|
+
|
|
1436
|
+
sonde("55b", "Ohne die Spalte 'Pflicht vor Aktivierung' meldet Pruefung 55 den "
|
|
1437
|
+
"verlorenen Gegenstand, statt leise zu bestehen", _55_anker_weg, M55_ANKER)
|
|
1438
|
+
|
|
1439
|
+
gegenprobe("55a", "Das unveraenderte Repositorium bleibt unbeanstandet - die Vorlage "
|
|
1440
|
+
"bietet jeden Pflichtplatzhalter an", None, M55_VORLAGE)
|
|
1441
|
+
|
|
1442
|
+
gegenprobe("55b", "Ein Pflichtplatzhalter, den das Register NICHT im Overlay verortet, "
|
|
1443
|
+
"muss in der Vorlage nicht stehen", _55_ohne_overlayort, M55_VORLAGE)
|
|
1444
|
+
|
|
1445
|
+
buendel(sonden_platzhalterbindung,
|
|
1446
|
+
"Pruefung 55b und 56 an einer gefuellten claude-code-Installation: fehlende "
|
|
1447
|
+
"Bindung und gesperrter Traeger je eigens gemessen, dazu beide Gegenproben")
|