@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.
Files changed (693) hide show
  1. package/.gitattributes +16 -0
  2. package/.gitignore +51 -0
  3. package/.koolie/QUELLREPOSITORIUM.md +18 -0
  4. package/.koolie/core/CHANGELOG.md +11832 -0
  5. package/.koolie/core/LICENSE +674 -0
  6. package/.koolie/core/LICENSE-HINWEIS.md +98 -0
  7. package/.koolie/core/OWNERS.md +36 -0
  8. package/.koolie/core/VERSION +1 -0
  9. package/.koolie/core/banner.py +397 -0
  10. package/.koolie/core/build/README.md +34 -0
  11. package/.koolie/core/build/assemble.py +354 -0
  12. package/.koolie/core/build/build-docx.py +194 -0
  13. package/.koolie/core/build/doc/00-kopf.md +18 -0
  14. package/.koolie/core/build/doc/01-executive-summary.md +24 -0
  15. package/.koolie/core/build/doc/02-zielbild.md +13 -0
  16. package/.koolie/core/build/doc/03-ziele-nichtziele.md +28 -0
  17. package/.koolie/core/build/doc/04-geltungsbereich.md +25 -0
  18. package/.koolie/core/build/doc/05-glossar.md +47 -0
  19. package/.koolie/core/build/doc/06-leitprinzipien.md +5 -0
  20. package/.koolie/core/build/doc/07-architektur.md +60 -0
  21. package/.koolie/core/build/doc/07a-abbildungsschicht.md +66 -0
  22. package/.koolie/core/build/doc/08-trennung.md +24 -0
  23. package/.koolie/core/build/doc/09-betriebsmodi.md +18 -0
  24. package/.koolie/core/build/doc/10-arbeitsablauf.md +5 -0
  25. package/.koolie/core/build/doc/11-datenschutz.md +5 -0
  26. package/.koolie/core/build/doc/12-sicherheit.md +5 -0
  27. package/.koolie/core/build/doc/13-risiko.md +5 -0
  28. package/.koolie/core/build/doc/14-rollen.md +9 -0
  29. package/.koolie/core/build/doc/15-referenzstruktur.md +124 -0
  30. package/.koolie/core/build/doc/16-agentenanweisung.md +8 -0
  31. package/.koolie/core/build/doc/17-overlay.md +29 -0
  32. package/.koolie/core/build/doc/18-skill-standard.md +5 -0
  33. package/.koolie/core/build/doc/19-skill-template.md +5 -0
  34. package/.koolie/core/build/doc/20-referenz-skills.md +70 -0
  35. package/.koolie/core/build/doc/21-prompts.md +53 -0
  36. package/.koolie/core/build/doc/22-checklisten.md +49 -0
  37. package/.koolie/core/build/doc/23-entscheidungsbaeume.md +29 -0
  38. package/.koolie/core/build/doc/24-onboarding.md +33 -0
  39. package/.koolie/core/build/doc/25-governance.md +35 -0
  40. package/.koolie/core/build/doc/26-qs-test.md +9 -0
  41. package/.koolie/core/build/doc/27-pilot.md +13 -0
  42. package/.koolie/core/build/doc/28-uebernahme.md +5 -0
  43. package/.koolie/core/build/doc/29-grenzen.md +87 -0
  44. package/.koolie/core/build/doc/30-roadmap.md +5 -0
  45. package/.koolie/core/build/doc/31-anhaenge.md +151 -0
  46. package/.koolie/core/build/doc/32-abschluss.md +92 -0
  47. package/.koolie/core/build/ref-a4.docx +0 -0
  48. package/.koolie/core/checklists/01-preflight.md +54 -0
  49. package/.koolie/core/checklists/02-privacy-context.md +51 -0
  50. package/.koolie/core/checklists/03-before-code-change.md +51 -0
  51. package/.koolie/core/checklists/04-review-ai-code.md +58 -0
  52. package/.koolie/core/checklists/05-testing.md +48 -0
  53. package/.koolie/core/checklists/06-security.md +50 -0
  54. package/.koolie/core/checklists/07-new-dependency.md +57 -0
  55. package/.koolie/core/checklists/08-merge-request.md +47 -0
  56. package/.koolie/core/checklists/09-onboarding.md +52 -0
  57. package/.koolie/core/checklists/10-project-adoption.md +74 -0
  58. package/.koolie/core/checklists/11-framework-release.md +71 -0
  59. package/.koolie/core/checklists/README.md +28 -0
  60. package/.koolie/core/clientmap.py +1358 -0
  61. package/.koolie/core/clients/README.md +113 -0
  62. package/.koolie/core/clients/_template/CLIENT_PACK.md +197 -0
  63. package/.koolie/core/clients/claude-code/CLIENT_PACK.md +383 -0
  64. package/.koolie/core/clients/claude-code/manifest.json +232 -0
  65. package/.koolie/core/clients/claude-code/root-template/.claude/README.md +127 -0
  66. package/.koolie/core/clients/cursor/CLIENT_PACK.md +229 -0
  67. package/.koolie/core/clients/cursor/manifest.json +330 -0
  68. package/.koolie/core/clients/cursor/root-template/.cursor/README.md +36 -0
  69. package/.koolie/core/clients/devin-desktop/CLIENT_PACK.md +251 -0
  70. package/.koolie/core/clients/devin-desktop/manifest.json +163 -0
  71. package/.koolie/core/clients/devin-desktop/root-template/.devin/README.md +79 -0
  72. package/.koolie/core/clients/kiro/CLIENT_PACK.md +223 -0
  73. package/.koolie/core/clients/kiro/manifest.json +300 -0
  74. package/.koolie/core/clients/kiro/root-template/.kiro/README.md +37 -0
  75. package/.koolie/core/clients/openai-codex/CLIENT_PACK.md +257 -0
  76. package/.koolie/core/clients/openai-codex/manifest.json +208 -0
  77. package/.koolie/core/clients/openai-codex/root-template/.codex/README.md +35 -0
  78. package/.koolie/core/decision-trees/01-context-allowed.md +46 -0
  79. package/.koolie/core/decision-trees/02-may-ai-do-task.md +47 -0
  80. package/.koolie/core/decision-trees/03-analyze-or-modify.md +50 -0
  81. package/.koolie/core/decision-trees/04-required-review.md +49 -0
  82. package/.koolie/core/decision-trees/05-stop-or-escalate.md +47 -0
  83. package/.koolie/core/decision-trees/06-rule-placement.md +58 -0
  84. package/.koolie/core/decision-trees/README.md +14 -0
  85. package/.koolie/core/docs/ADOPTION_GUIDE.md +582 -0
  86. package/.koolie/core/docs/DOCUMENTATION_STANDARD.md +91 -0
  87. package/.koolie/core/docs/PLACEHOLDER_REGISTRY.md +79 -0
  88. package/.koolie/core/docs/ROADMAP.md +848 -0
  89. package/.koolie/core/docs/RUNTIME_GLOSSARY.md +113 -0
  90. package/.koolie/core/examples/README.md +11 -0
  91. package/.koolie/core/examples/example-ergebnisbericht.md +31 -0
  92. package/.koolie/core/examples/example-mr-description.md +31 -0
  93. package/.koolie/core/examples/example-overlay-runtime.md +48 -0
  94. package/.koolie/core/framework/core/00-principles.md +93 -0
  95. package/.koolie/core/framework/core/01-governance.md +58 -0
  96. package/.koolie/core/framework/core/02-privacy.md +141 -0
  97. package/.koolie/core/framework/core/03-security.md +86 -0
  98. package/.koolie/core/framework/core/04-quality.md +48 -0
  99. package/.koolie/core/framework/core/05-working-model.md +199 -0
  100. package/.koolie/core/framework/core/06-prompting-rules.md +51 -0
  101. package/.koolie/core/framework/core/07-review-rules.md +52 -0
  102. package/.koolie/core/framework/core/08-skill-conventions.md +115 -0
  103. package/.koolie/core/framework/core/09-risk-model.md +87 -0
  104. package/.koolie/core/framework/core/10-error-escalation.md +53 -0
  105. package/.koolie/core/framework/org-policies/MAPPING_CLASSIFICATION.md +16 -0
  106. package/.koolie/core/framework/org-policies/README.md +29 -0
  107. package/.koolie/core/framework/overlay-patterns/general/documents/branching-strategy/muster-general.md +43 -0
  108. package/.koolie/core/framework/overlay-patterns/general/documents/coding-guidelines/muster-general.md +82 -0
  109. package/.koolie/core/framework/overlay-patterns/general/documents/definition-of-done/muster-general.md +52 -0
  110. package/.koolie/core/framework/overlay-patterns/general/documents/definition-of-ready/muster-general.md +54 -0
  111. package/.koolie/core/framework/overlay-patterns/general/documents/quality/muster-general.md +59 -0
  112. package/.koolie/core/framework/overlay-patterns/general/documents/security/muster-general.md +52 -0
  113. package/.koolie/core/framework/overlay-patterns/general.md +150 -0
  114. package/.koolie/core/framework/role-packs/README.md +63 -0
  115. package/.koolie/core/framework/role-packs/_template/ROLE_PACK.md +58 -0
  116. package/.koolie/core/framework/role-packs/requirements-engineering/ROLE_PACK.md +158 -0
  117. package/.koolie/core/framework/role-packs/requirements-engineering/runtime/30-role-requirements-engineering.md +88 -0
  118. package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/CHANGELOG.md +10 -0
  119. package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/EXAMPLES.md +148 -0
  120. package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/SKILL.md +195 -0
  121. package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/TESTS.md +22 -0
  122. package/.koolie/core/framework/role-packs/software-development/ROLE_PACK.md +95 -0
  123. package/.koolie/core/framework/role-packs/software-development/runtime/30-role-software-development.md +26 -0
  124. package/.koolie/core/framework/runtime/agents/fw-reviewer.md +34 -0
  125. package/.koolie/core/framework/runtime/client-settings.json +3 -0
  126. package/.koolie/core/framework/runtime/hooks.json +20 -0
  127. package/.koolie/core/framework/runtime/mcp-config.example.json +4 -0
  128. package/.koolie/core/framework/runtime/permissions.json +106 -0
  129. package/.koolie/core/framework/runtime/root-instruction-local.example.md +19 -0
  130. package/.koolie/core/framework/runtime/root-instruction.md +116 -0
  131. package/.koolie/core/framework/runtime/rules/00-framework-core.md +49 -0
  132. package/.koolie/core/framework/runtime/rules/10-privacy-security.md +49 -0
  133. package/.koolie/core/framework/runtime/rules/15-development-rules.md +41 -0
  134. package/.koolie/core/framework/runtime/rules/16-plan-spezifikation.md +32 -0
  135. package/.koolie/core/framework/runtime/rules/20-project-overlay.md +60 -0
  136. package/.koolie/core/framework/skills/fw-bugfix-prepare/CHANGELOG.md +14 -0
  137. package/.koolie/core/framework/skills/fw-bugfix-prepare/EXAMPLES.md +57 -0
  138. package/.koolie/core/framework/skills/fw-bugfix-prepare/SKILL.md +177 -0
  139. package/.koolie/core/framework/skills/fw-bugfix-prepare/TESTS.md +15 -0
  140. package/.koolie/core/framework/skills/fw-change-analyze/CHANGELOG.md +12 -0
  141. package/.koolie/core/framework/skills/fw-change-analyze/EXAMPLES.md +66 -0
  142. package/.koolie/core/framework/skills/fw-change-analyze/SKILL.md +167 -0
  143. package/.koolie/core/framework/skills/fw-change-analyze/TESTS.md +16 -0
  144. package/.koolie/core/framework/skills/fw-change-small/CHANGELOG.md +13 -0
  145. package/.koolie/core/framework/skills/fw-change-small/EXAMPLES.md +68 -0
  146. package/.koolie/core/framework/skills/fw-change-small/SKILL.md +175 -0
  147. package/.koolie/core/framework/skills/fw-change-small/TESTS.md +13 -0
  148. package/.koolie/core/framework/skills/fw-code-explain/CHANGELOG.md +11 -0
  149. package/.koolie/core/framework/skills/fw-code-explain/EXAMPLES.md +61 -0
  150. package/.koolie/core/framework/skills/fw-code-explain/SKILL.md +163 -0
  151. package/.koolie/core/framework/skills/fw-code-explain/TESTS.md +11 -0
  152. package/.koolie/core/framework/skills/fw-docs-update/CHANGELOG.md +10 -0
  153. package/.koolie/core/framework/skills/fw-docs-update/EXAMPLES.md +59 -0
  154. package/.koolie/core/framework/skills/fw-docs-update/SKILL.md +160 -0
  155. package/.koolie/core/framework/skills/fw-docs-update/TESTS.md +12 -0
  156. package/.koolie/core/framework/skills/fw-error-analyze/CHANGELOG.md +10 -0
  157. package/.koolie/core/framework/skills/fw-error-analyze/EXAMPLES.md +67 -0
  158. package/.koolie/core/framework/skills/fw-error-analyze/SKILL.md +160 -0
  159. package/.koolie/core/framework/skills/fw-error-analyze/TESTS.md +12 -0
  160. package/.koolie/core/framework/skills/fw-mr-description/CHANGELOG.md +12 -0
  161. package/.koolie/core/framework/skills/fw-mr-description/EXAMPLES.md +69 -0
  162. package/.koolie/core/framework/skills/fw-mr-description/SKILL.md +170 -0
  163. package/.koolie/core/framework/skills/fw-mr-description/TESTS.md +12 -0
  164. package/.koolie/core/framework/skills/fw-overlay-pflege/CHANGELOG.md +7 -0
  165. package/.koolie/core/framework/skills/fw-overlay-pflege/EXAMPLES.md +48 -0
  166. package/.koolie/core/framework/skills/fw-overlay-pflege/SKILL.md +147 -0
  167. package/.koolie/core/framework/skills/fw-overlay-pflege/TESTS.md +13 -0
  168. package/.koolie/core/framework/skills/fw-plan/CHANGELOG.md +14 -0
  169. package/.koolie/core/framework/skills/fw-plan/EXAMPLES.md +69 -0
  170. package/.koolie/core/framework/skills/fw-plan/SKILL.md +168 -0
  171. package/.koolie/core/framework/skills/fw-plan/TESTS.md +14 -0
  172. package/.koolie/core/framework/skills/fw-refactor/CHANGELOG.md +10 -0
  173. package/.koolie/core/framework/skills/fw-refactor/EXAMPLES.md +70 -0
  174. package/.koolie/core/framework/skills/fw-refactor/SKILL.md +173 -0
  175. package/.koolie/core/framework/skills/fw-refactor/TESTS.md +14 -0
  176. package/.koolie/core/framework/skills/fw-repo-analyze/CHANGELOG.md +10 -0
  177. package/.koolie/core/framework/skills/fw-repo-analyze/EXAMPLES.md +52 -0
  178. package/.koolie/core/framework/skills/fw-repo-analyze/SKILL.md +149 -0
  179. package/.koolie/core/framework/skills/fw-repo-analyze/TESTS.md +11 -0
  180. package/.koolie/core/framework/skills/fw-review-support/CHANGELOG.md +12 -0
  181. package/.koolie/core/framework/skills/fw-review-support/EXAMPLES.md +69 -0
  182. package/.koolie/core/framework/skills/fw-review-support/SKILL.md +179 -0
  183. package/.koolie/core/framework/skills/fw-review-support/TESTS.md +13 -0
  184. package/.koolie/core/framework/skills/fw-tests/CHANGELOG.md +9 -0
  185. package/.koolie/core/framework/skills/fw-tests/EXAMPLES.md +65 -0
  186. package/.koolie/core/framework/skills/fw-tests/SKILL.md +169 -0
  187. package/.koolie/core/framework/skills/fw-tests/TESTS.md +12 -0
  188. package/.koolie/core/framework/tech-packs/README.md +15 -0
  189. package/.koolie/core/framework/tech-packs/_template/TECH_PACK.md +61 -0
  190. package/.koolie/core/governance/ADOPTION_REGISTRY.md +89 -0
  191. package/.koolie/core/governance/CHANGE_REQUEST_TEMPLATE.md +60 -0
  192. package/.koolie/core/governance/DECISION_LOG.md +779 -0
  193. package/.koolie/core/governance/EXCEPTION_PROCESS.md +31 -0
  194. package/.koolie/core/governance/FEEDBACK_PROCESS.md +34 -0
  195. package/.koolie/core/governance/FRAMEWORK_DEV_PROFILE.md +135 -0
  196. package/.koolie/core/governance/INCIDENT_HANDLING.md +47 -0
  197. package/.koolie/core/governance/PRIORITY_HIERARCHY.md +61 -0
  198. package/.koolie/core/governance/RACI.md +37 -0
  199. package/.koolie/core/governance/RELEASE_PROCESS.md +183 -0
  200. package/.koolie/core/governance/change-requests/CR-2026-001-definition-release-1-0-0.md +67 -0
  201. package/.koolie/core/governance/change-requests/CR-2026-002-client-packs.md +63 -0
  202. package/.koolie/core/governance/change-requests/CR-2026-003-install-client-schalter.md +70 -0
  203. package/.koolie/core/governance/change-requests/CR-2026-004-client-pack-claude-code.md +82 -0
  204. package/.koolie/core/governance/change-requests/CR-2026-005-kern-neutralisierung.md +75 -0
  205. package/.koolie/core/governance/change-requests/CR-2026-006-gemeinsame-skill-quelle.md +77 -0
  206. package/.koolie/core/governance/change-requests/CR-2026-007-geteilte-kernbestandteile.md +80 -0
  207. package/.koolie/core/governance/change-requests/CR-2026-008-berechtigungen-und-hooks.md +85 -0
  208. package/.koolie/core/governance/change-requests/CR-2026-009-umbenennung-leitwerk.md +77 -0
  209. package/.koolie/core/governance/change-requests/CR-2026-010-restduplikation.md +73 -0
  210. package/.koolie/core/governance/change-requests/CR-2026-011-hauptdokument.md +72 -0
  211. package/.koolie/core/governance/change-requests/CR-2026-012-schreibschutz-kernverzeichnis.md +106 -0
  212. package/.koolie/core/governance/change-requests/CR-2026-013-validator-blindstellen.md +128 -0
  213. package/.koolie/core/governance/change-requests/CR-2026-014-kurzform-langform.md +125 -0
  214. package/.koolie/core/governance/change-requests/CR-2026-015-versionskette.md +150 -0
  215. package/.koolie/core/governance/change-requests/CR-2026-016-ap2-claude-code.md +127 -0
  216. package/.koolie/core/governance/change-requests/CR-2026-017-ladebedingungen-claude-code.md +173 -0
  217. package/.koolie/core/governance/change-requests/CR-2026-018-quellenliste-claude-code.md +121 -0
  218. package/.koolie/core/governance/change-requests/CR-2026-019-strukturentscheidungen-fortschreiben.md +143 -0
  219. package/.koolie/core/governance/change-requests/CR-2026-020-akteursbezeichnung.md +118 -0
  220. package/.koolie/core/governance/change-requests/CR-2026-021-hook-interpreter.md +113 -0
  221. package/.koolie/core/governance/change-requests/CR-2026-022-artefaktversionen.md +73 -0
  222. package/.koolie/core/governance/change-requests/CR-2026-023-shell-lesesperre.md +128 -0
  223. package/.koolie/core/governance/change-requests/CR-2026-024-clientbindungen.md +78 -0
  224. package/.koolie/core/governance/change-requests/CR-2026-025-betriebsmodi.md +110 -0
  225. package/.koolie/core/governance/change-requests/CR-2026-026-fail-closed.md +134 -0
  226. package/.koolie/core/governance/change-requests/CR-2026-027-zeichenlimit-einstufung.md +105 -0
  227. package/.koolie/core/governance/change-requests/CR-2026-028-berechtigungsmodi.md +130 -0
  228. package/.koolie/core/governance/change-requests/CR-2026-029-hook-ablageort.md +115 -0
  229. package/.koolie/core/governance/change-requests/CR-2026-030-lesende-werkzeuge.md +143 -0
  230. package/.koolie/core/governance/change-requests/CR-2026-031-regelquellen-ausserhalb.md +182 -0
  231. package/.koolie/core/governance/change-requests/CR-2026-032-fremde-skill-ablage.md +151 -0
  232. package/.koolie/core/governance/change-requests/CR-2026-033-modusabhaengige-durchsetzung.md +131 -0
  233. package/.koolie/core/governance/change-requests/CR-2026-034-nachweisbedingungen.md +116 -0
  234. package/.koolie/core/governance/change-requests/CR-2026-035-readme-in-der-regelablage.md +115 -0
  235. package/.koolie/core/governance/change-requests/CR-2026-036-ortsangaben-hook-konfiguration.md +108 -0
  236. package/.koolie/core/governance/change-requests/CR-2026-037-meldender-hook-clientgebunden.md +133 -0
  237. package/.koolie/core/governance/change-requests/CR-2026-038-importsteuerung.md +159 -0
  238. package/.koolie/core/governance/change-requests/CR-2026-039-normative-saetze-in-kommentaren.md +124 -0
  239. package/.koolie/core/governance/change-requests/CR-2026-040-erh01-ist-clientgebunden.md +115 -0
  240. package/.koolie/core/governance/change-requests/CR-2026-041-s5-nicht-abbildbar.md +128 -0
  241. package/.koolie/core/governance/change-requests/CR-2026-042-abwesenheitsnachweis-suchwerkzeug.md +102 -0
  242. package/.koolie/core/governance/change-requests/CR-2026-043-validator-gibt-trefferwerte-aus.md +135 -0
  243. package/.koolie/core/governance/change-requests/CR-2026-044-aktivierungspruefung-clientgebunden.md +112 -0
  244. package/.koolie/core/governance/change-requests/CR-2026-045-update-verliert-die-clientwahl.md +116 -0
  245. package/.koolie/core/governance/change-requests/CR-2026-046-erstinstallation-ueberschreibt-projektdatei.md +125 -0
  246. package/.koolie/core/governance/change-requests/CR-2026-047-zusagen-je-zugriffskanal.md +133 -0
  247. package/.koolie/core/governance/change-requests/CR-2026-048-modusgrenze-ohne-durchsetzung.md +137 -0
  248. package/.koolie/core/governance/change-requests/CR-2026-049-sondenlauf-kodierungsabhaengig.md +126 -0
  249. package/.koolie/core/governance/change-requests/CR-2026-050-allowed-tools-und-verworfene-permissions.md +110 -0
  250. package/.koolie/core/governance/change-requests/CR-2026-051-quellenkarte-und-ueberholter-stand.md +110 -0
  251. package/.koolie/core/governance/change-requests/CR-2026-052-drei-regelkonflikte.md +166 -0
  252. package/.koolie/core/governance/change-requests/CR-2026-053-lesesperre-und-entwicklungsprofil.md +144 -0
  253. package/.koolie/core/governance/change-requests/CR-2026-054-aktivierung-verlangt-aktivitaet.md +124 -0
  254. package/.koolie/core/governance/change-requests/CR-2026-055-domain-ausnahme-ohne-mechanismus.md +173 -0
  255. package/.koolie/core/governance/change-requests/CR-2026-056-eingabeschema-und-pfadidentitaet.md +245 -0
  256. package/.koolie/core/governance/change-requests/CR-2026-057-disallowed-tools-und-s3.md +148 -0
  257. package/.koolie/core/governance/change-requests/CR-2026-058-unteragent-reichweite.md +203 -0
  258. package/.koolie/core/governance/change-requests/CR-2026-059-unteragent-tiefe-und-widerspruch.md +125 -0
  259. package/.koolie/core/governance/change-requests/CR-2026-060-stumme-brueche.md +170 -0
  260. package/.koolie/core/governance/change-requests/CR-2026-061-berechtigungsdatei-ohne-pruefung.md +169 -0
  261. package/.koolie/core/governance/change-requests/CR-2026-062-werkzeugabbildung-des-frontmatters.md +178 -0
  262. package/.koolie/core/governance/change-requests/CR-2026-063-skillaufruf-ohne-freigabe.md +207 -0
  263. package/.koolie/core/governance/change-requests/CR-2026-064-pruefregister-nicht-nachgezaehlt.md +141 -0
  264. package/.koolie/core/governance/change-requests/CR-2026-065-devin-suchwerkzeuge-erhoben.md +170 -0
  265. package/.koolie/core/governance/change-requests/CR-2026-066-schlitzdeckung-ohne-abgleich.md +153 -0
  266. package/.koolie/core/governance/change-requests/CR-2026-067-hookblock-und-praeparationsregister.md +140 -0
  267. package/.koolie/core/governance/change-requests/CR-2026-068-sondenlauf-nebenlaeufig.md +106 -0
  268. package/.koolie/core/governance/change-requests/CR-2026-069-bytecode-des-kerns.md +108 -0
  269. package/.koolie/core/governance/change-requests/CR-2026-070-d11-zaehler.md +114 -0
  270. package/.koolie/core/governance/change-requests/CR-2026-071-strukturentscheidungen-bestaetigen.md +322 -0
  271. package/.koolie/core/governance/change-requests/CR-2026-072-modulstatus-heben.md +315 -0
  272. package/.koolie/core/governance/change-requests/CR-2026-073-nicht-skill-traeger-heben.md +246 -0
  273. package/.koolie/core/governance/change-requests/CR-2026-074-restliche-nicht-skill-traeger-heben.md +271 -0
  274. package/.koolie/core/governance/change-requests/CR-2026-075-ap2-zielversion-devin-desktop.md +335 -0
  275. package/.koolie/core/governance/change-requests/CR-2026-076-erster-sitzungstest.md +455 -0
  276. package/.koolie/core/governance/change-requests/CR-2026-077-sitzungstest-schranken.md +425 -0
  277. package/.koolie/core/governance/change-requests/CR-2026-078-planung-nach-1-0-0.md +294 -0
  278. package/.koolie/core/governance/change-requests/CR-2026-079-umbenennung-vorziehen.md +233 -0
  279. package/.koolie/core/governance/change-requests/CR-2026-080-clientbindung-des-kerns.md +321 -0
  280. package/.koolie/core/governance/change-requests/CR-2026-081-produktnamen-im-kern.md +297 -0
  281. package/.koolie/core/governance/change-requests/CR-2026-082-sitzungstest-pi-ds-2.md +145 -0
  282. package/.koolie/core/governance/change-requests/CR-2026-083-sitzungstest-ne-sc.md +300 -0
  283. package/.koolie/core/governance/change-requests/CR-2026-084-trockenlauf-gegen-den-committeten-stand.md +117 -0
  284. package/.koolie/core/governance/change-requests/CR-2026-085-vorbedingungen-sitzungstest-5.md +182 -0
  285. package/.koolie/core/governance/change-requests/CR-2026-086-grenzfaelle-gegen-die-fassungen.md +164 -0
  286. package/.koolie/core/governance/change-requests/CR-2026-087-produktbeobachtung-quellenliste.md +206 -0
  287. package/.koolie/core/governance/change-requests/CR-2026-088-vorbedingungen-testblaetter.md +127 -0
  288. package/.koolie/core/governance/change-requests/CR-2026-089-herrichtung-uebungsrepositorium.md +226 -0
  289. package/.koolie/core/governance/change-requests/CR-2026-090-vorbedingungen-sitzungstest-5-zweiter-durchgang.md +255 -0
  290. package/.koolie/core/governance/change-requests/CR-2026-091-sitzungstest-5.md +163 -0
  291. package/.koolie/core/governance/change-requests/CR-2026-092-pruefmittelwort-und-buendelschnitt.md +226 -0
  292. package/.koolie/core/governance/change-requests/CR-2026-093-sechzehnte-praeparation.md +151 -0
  293. package/.koolie/core/governance/change-requests/CR-2026-094-testblaetter-buendel-1.md +113 -0
  294. package/.koolie/core/governance/change-requests/CR-2026-095-pruefapparat-filter.md +65 -0
  295. package/.koolie/core/governance/change-requests/CR-2026-096-vorbedingungen-buendel-2.md +225 -0
  296. package/.koolie/core/governance/change-requests/CR-2026-097-testblaetter-buendel-2.md +162 -0
  297. package/.koolie/core/governance/change-requests/CR-2026-098-anforderungen-auslieferung.md +93 -0
  298. package/.koolie/core/governance/change-requests/CR-2026-099-k74-und-vorbedingungen-buendel-3.md +119 -0
  299. package/.koolie/core/governance/change-requests/CR-2026-100-testblaetter-buendel-3.md +120 -0
  300. package/.koolie/core/governance/change-requests/CR-2026-101-k77-eigener-posten.md +165 -0
  301. package/.koolie/core/governance/change-requests/CR-2026-102-k77-entschieden.md +118 -0
  302. package/.koolie/core/governance/change-requests/CR-2026-103-vorbedingungen-buendel-4.md +76 -0
  303. package/.koolie/core/governance/change-requests/CR-2026-104-herrichtung-buendel-4.md +82 -0
  304. package/.koolie/core/governance/change-requests/CR-2026-105-messapparat-buendel-4.md +227 -0
  305. package/.koolie/core/governance/change-requests/CR-2026-106-uebergabe-einchecken.md +91 -0
  306. package/.koolie/core/governance/change-requests/CR-2026-107-uebergabe-im-release-commit.md +111 -0
  307. package/.koolie/core/governance/change-requests/CR-2026-108-testblaetter-buendel-4.md +118 -0
  308. package/.koolie/core/governance/change-requests/CR-2026-109-berichtsweg-des-aufraeumers.md +108 -0
  309. package/.koolie/core/governance/change-requests/CR-2026-110-vorbedingungen-des-nachlaufs.md +184 -0
  310. package/.koolie/core/governance/change-requests/CR-2026-111-der-apparat-auf-dem-weg-der-wiederaufnahme.md +127 -0
  311. package/.koolie/core/governance/change-requests/CR-2026-112-der-arbeitsplatz-im-kern.md +103 -0
  312. package/.koolie/core/governance/change-requests/CR-2026-113-nachlauf-buendel-4.md +103 -0
  313. package/.koolie/core/governance/change-requests/CR-2026-114-vorbedingungen-buendel-5.md +317 -0
  314. package/.koolie/core/governance/change-requests/CR-2026-115-herrichtung-buendel-5.md +244 -0
  315. package/.koolie/core/governance/change-requests/CR-2026-116-messtag-buendel-5.md +178 -0
  316. package/.koolie/core/governance/change-requests/CR-2026-117-sammelzellen-zentraler-katalog.md +251 -0
  317. package/.koolie/core/governance/change-requests/CR-2026-118-quellenzuordnung-matrixzeilen.md +115 -0
  318. package/.koolie/core/governance/change-requests/CR-2026-119-umbenennung-koolie.md +204 -0
  319. package/.koolie/core/governance/change-requests/CR-2026-120-ap2-rest-devin-desktop.md +96 -0
  320. package/.koolie/core/governance/change-requests/CR-2026-121-verify-marker-abschaffen.md +185 -0
  321. package/.koolie/core/governance/change-requests/CR-2026-122-umbenennung-koolie-lauf.md +131 -0
  322. package/.koolie/core/governance/change-requests/CR-2026-123-vortrag-und-namensabsatz.md +170 -0
  323. package/.koolie/core/governance/change-requests/CR-2026-124-hauptdokument-ap11.md +237 -0
  324. package/.koolie/core/governance/change-requests/CR-2026-125-word-fassung-und-blinder-fleck.md +204 -0
  325. package/.koolie/core/governance/change-requests/CR-2026-126-lizenz-gpl3.md +112 -0
  326. package/.koolie/core/governance/change-requests/CR-2026-127-gegenzeichnung-rollenfrage.md +96 -0
  327. package/.koolie/core/governance/change-requests/CR-2026-128-freigabelauf-1.0.0.md +278 -0
  328. package/.koolie/core/governance/change-requests/CR-2026-129-archiv-zeilenenden.md +90 -0
  329. package/.koolie/core/governance/change-requests/CR-2026-130-reihenfolge-des-hebens.md +204 -0
  330. package/.koolie/core/governance/change-requests/CR-2026-131-chronik-und-vorlage.md +194 -0
  331. package/.koolie/core/governance/change-requests/CR-2026-132-erhebung-openai-codex.md +185 -0
  332. package/.koolie/core/governance/change-requests/CR-2026-133-bau-openai-codex.md +97 -0
  333. package/.koolie/core/governance/change-requests/CR-2026-134-uebergabe-lokal.md +117 -0
  334. package/.koolie/core/governance/change-requests/CR-2026-135-pfadlisten-nul-getrennt.md +139 -0
  335. package/.koolie/core/governance/change-requests/CR-2026-136-overlay-werte-einordnung.md +156 -0
  336. package/.koolie/core/governance/change-requests/CR-2026-137-kopierweg-kern.md +144 -0
  337. package/.koolie/core/governance/change-requests/CR-2026-138-overlay-muster-general.md +118 -0
  338. package/.koolie/core/governance/change-requests/CR-2026-139-overlay-muster-dokumente.md +105 -0
  339. package/.koolie/core/governance/change-requests/CR-2026-140-installer-je-zielsystem.md +120 -0
  340. package/.koolie/core/governance/change-requests/CR-2026-141-lieferumfang.md +123 -0
  341. package/.koolie/core/governance/change-requests/CR-2026-142-dokumentationsstandard.md +90 -0
  342. package/.koolie/core/governance/change-requests/CR-2026-143-klasse-b-core-laufzeit.md +89 -0
  343. package/.koolie/core/governance/change-requests/CR-2026-144-klasse-b-governance.md +90 -0
  344. package/.koolie/core/governance/change-requests/CR-2026-145-klasse-b-skills.md +81 -0
  345. package/.koolie/core/governance/change-requests/CR-2026-146-code-pack-posten.md +84 -0
  346. package/.koolie/core/governance/change-requests/CR-2026-147-regel-register-posten.md +78 -0
  347. package/.koolie/core/governance/change-requests/CR-2026-148-mehrprojekt-tokenlast.md +70 -0
  348. package/.koolie/core/governance/change-requests/CR-2026-149-regelablage-pfadtoken.md +71 -0
  349. package/.koolie/core/governance/change-requests/CR-2026-150-client-pack-kiro.md +76 -0
  350. package/.koolie/core/governance/change-requests/CR-2026-151-skill-anweisungen.md +71 -0
  351. package/.koolie/core/governance/change-requests/CR-2026-152-testblaetter-modellwechsel.md +78 -0
  352. package/.koolie/core/governance/change-requests/CR-2026-153-attributionszeile.md +88 -0
  353. package/.koolie/core/governance/change-requests/CR-2026-154-auffindbarkeit.md +102 -0
  354. package/.koolie/core/governance/change-requests/CR-2026-155-client-pack-cursor.md +80 -0
  355. package/.koolie/core/governance/change-requests/CR-2026-156-mandat-und-reibung.md +100 -0
  356. package/.koolie/core/governance/change-requests/CR-2026-157-mcp-anbindung.md +93 -0
  357. package/.koolie/core/governance/change-requests/CR-2026-158-registerpflege.md +69 -0
  358. package/.koolie/core/governance/change-requests/CR-2026-159-powershell.md +49 -0
  359. package/.koolie/core/governance/change-requests/CR-2026-160-messapparat.md +59 -0
  360. package/.koolie/core/governance/change-requests/CR-2026-161-pruefwerkzeuge.md +52 -0
  361. package/.koolie/core/governance/change-requests/CR-2026-162-schutzschicht.md +65 -0
  362. package/.koolie/core/governance/change-requests/CR-2026-163-pfadsemantik.md +61 -0
  363. package/.koolie/core/governance/change-requests/CR-2026-164-modi-ausnahmen.md +65 -0
  364. package/.koolie/core/governance/change-requests/CR-2026-165-installer-banner.md +406 -0
  365. package/.koolie/core/governance/change-requests/CR-2026-166-nachlauf-aufzeichnungen.md +59 -0
  366. package/.koolie/core/governance/change-requests/CR-2026-167-einsatzarchitektur.md +60 -0
  367. package/.koolie/core/governance/change-requests/CR-2026-168-paketquellen.md +64 -0
  368. package/.koolie/core/governance/change-requests/CR-2026-169-modusbindung-messfragen.md +58 -0
  369. package/.koolie/core/governance/change-requests/CR-2026-170-erste-veroeffentlichung.md +62 -0
  370. package/.koolie/core/governance/change-requests/CR-2026-171-befehl-im-projektverzeichnis.md +57 -0
  371. package/.koolie/core/governance/change-requests/CR-2026-172-auftritt-npm-suche.md +58 -0
  372. package/.koolie/core/install.py +2402 -0
  373. package/.koolie/core/install_dialog.py +227 -0
  374. package/.koolie/core/koexistenz.py +112 -0
  375. package/.koolie/core/mandat.py +605 -0
  376. package/.koolie/core/onboarding/COMPLETION_CRITERIA.md +37 -0
  377. package/.koolie/core/onboarding/GUIDE.md +103 -0
  378. package/.koolie/core/onboarding/KNOWLEDGE_CHECK.md +48 -0
  379. package/.koolie/core/onboarding/MENTOR_CHECKLIST.md +40 -0
  380. package/.koolie/core/onboarding/QUICKSTART.md +50 -0
  381. package/.koolie/core/onboarding/REFERENCE.md +69 -0
  382. package/.koolie/core/onboarding/exercises/EXERCISES.md +78 -0
  383. package/.koolie/core/onboarding/exercises/README.md +120 -0
  384. package/.koolie/core/pilot/METRICS.md +59 -0
  385. package/.koolie/core/pilot/PILOT_CONCEPT.md +42 -0
  386. package/.koolie/core/prompts/01-understand-codebase.md +99 -0
  387. package/.koolie/core/prompts/02-impact-analysis.md +104 -0
  388. package/.koolie/core/prompts/03-implementation-planning.md +102 -0
  389. package/.koolie/core/prompts/04-code-generation.md +100 -0
  390. package/.koolie/core/prompts/05-test-generation.md +103 -0
  391. package/.koolie/core/prompts/06-refactoring.md +102 -0
  392. package/.koolie/core/prompts/07-debugging.md +97 -0
  393. package/.koolie/core/prompts/08-security-review.md +92 -0
  394. package/.koolie/core/prompts/09-performance-analysis.md +89 -0
  395. package/.koolie/core/prompts/10-documentation.md +91 -0
  396. package/.koolie/core/prompts/11-merge-request-review.md +94 -0
  397. package/.koolie/core/prompts/12-developer-training.md +90 -0
  398. package/.koolie/core/prompts/README.md +88 -0
  399. package/.koolie/core/templates/MR_AI_DISCLOSURE.md +37 -0
  400. package/.koolie/core/templates/PLAN_TEMPLATE.md +57 -0
  401. package/.koolie/core/templates/SKILL_TEMPLATE.md +159 -0
  402. package/.koolie/core/templates/project-overlay/OVERLAY.md +315 -0
  403. package/.koolie/core/templates/project-overlay/documents/README.md +43 -0
  404. package/.koolie/core/templates/project-overlay/documents/ai-governance/.gitkeep.md +3 -0
  405. package/.koolie/core/templates/project-overlay/documents/ai-process-model/.gitkeep.md +3 -0
  406. package/.koolie/core/templates/project-overlay/documents/architecture/.gitkeep.md +3 -0
  407. package/.koolie/core/templates/project-overlay/documents/architecture/decisions/README.md +3 -0
  408. package/.koolie/core/templates/project-overlay/documents/branching-strategy/.gitkeep.md +3 -0
  409. package/.koolie/core/templates/project-overlay/documents/coding-guidelines/.gitkeep.md +3 -0
  410. package/.koolie/core/templates/project-overlay/documents/definition-of-done/.gitkeep.md +3 -0
  411. package/.koolie/core/templates/project-overlay/documents/definition-of-ready/.gitkeep.md +3 -0
  412. package/.koolie/core/templates/project-overlay/documents/deployment/.gitkeep.md +3 -0
  413. package/.koolie/core/templates/project-overlay/documents/glossary/.gitkeep.md +3 -0
  414. package/.koolie/core/templates/project-overlay/documents/quality/.gitkeep.md +3 -0
  415. package/.koolie/core/templates/project-overlay/documents/roadmap/.gitkeep.md +3 -0
  416. package/.koolie/core/templates/project-overlay/documents/roles/.gitkeep.md +3 -0
  417. package/.koolie/core/templates/project-overlay/documents/security/.gitkeep.md +3 -0
  418. package/.koolie/core/templates/project-overlay/exceptions/EXCEPTIONS.md +9 -0
  419. package/.koolie/core/templates/project-overlay/forbidden-terms.txt +8 -0
  420. package/.koolie/core/templates/project-overlay/overlay-manifest.yaml +73 -0
  421. package/.koolie/core/templates/rules/21-overlay-TEMPLATE.md.template +28 -0
  422. package/.koolie/core/templates/rules/40-tech-TEMPLATE.md.template +33 -0
  423. package/.koolie/core/tests/EDGE_CASES.md +67 -0
  424. package/.koolie/core/tests/TEST_CATALOG.md +170 -0
  425. package/.koolie/core/tests/erhebungen/README.md +326 -0
  426. package/.koolie/core/tests/erhebungen/ablage.py +357 -0
  427. package/.koolie/core/tests/erhebungen/apparat/__init__.py +22 -0
  428. package/.koolie/core/tests/erhebungen/apparat/baum.py +214 -0
  429. package/.koolie/core/tests/erhebungen/apparat/belege.py +91 -0
  430. package/.koolie/core/tests/erhebungen/apparat/clients.py +321 -0
  431. package/.koolie/core/tests/erhebungen/apparat/freigabe.py +74 -0
  432. package/.koolie/core/tests/erhebungen/apparat/kontingent.py +64 -0
  433. package/.koolie/core/tests/erhebungen/apparat/laeufer.py +155 -0
  434. package/.koolie/core/tests/erhebungen/apparat/reihe.py +202 -0
  435. package/.koolie/core/tests/erhebungen/apparat/selbsttest.py +280 -0
  436. package/.koolie/core/tests/erhebungen/apparat/stand.py +30 -0
  437. package/.koolie/core/tests/erhebungen/apparat/vorpruefung.py +70 -0
  438. package/.koolie/core/tests/erhebungen/auswerten-b4.py +468 -0
  439. package/.koolie/core/tests/erhebungen/auswerten-b5.py +517 -0
  440. package/.koolie/core/tests/erhebungen/auswerten-dd.py +172 -0
  441. package/.koolie/core/tests/erhebungen/baeume-b4.py +334 -0
  442. package/.koolie/core/tests/erhebungen/baeume-b5.py +339 -0
  443. package/.koolie/core/tests/erhebungen/baeume_loeschen.py +138 -0
  444. package/.koolie/core/tests/erhebungen/cc-overlay-fuellen.py +277 -0
  445. package/.koolie/core/tests/erhebungen/dossier-b4.py +178 -0
  446. package/.koolie/core/tests/erhebungen/dossier-b5.py +202 -0
  447. package/.koolie/core/tests/erhebungen/historie-bauen-b4.py +642 -0
  448. package/.koolie/core/tests/erhebungen/k-bauen-b3.py +841 -0
  449. package/.koolie/core/tests/erhebungen/lauf-dd.py +146 -0
  450. package/.koolie/core/tests/erhebungen/lauf.py +114 -0
  451. package/.koolie/core/tests/erhebungen/mcp-waechter.py +278 -0
  452. package/.koolie/core/tests/erhebungen/messbaum-schnitt.py +256 -0
  453. package/.koolie/core/tests/erhebungen/messen.py +72 -0
  454. package/.koolie/core/tests/erhebungen/node-waechter.py +74 -0
  455. package/.koolie/core/tests/erhebungen/packaktivierung.py +403 -0
  456. package/.koolie/core/tests/erhebungen/prompts-schreiben-b4.py +210 -0
  457. package/.koolie/core/tests/erhebungen/prompts-schreiben-b5.py +251 -0
  458. package/.koolie/core/tests/erhebungen/reihe-b4.py +171 -0
  459. package/.koolie/core/tests/erhebungen/reihe-b5.py +172 -0
  460. package/.koolie/core/tests/erhebungen/stand-b4.py +135 -0
  461. package/.koolie/core/tests/erhebungen/stand-b5.py +137 -0
  462. package/.koolie/core/tests/erhebungen/trust-b4.py +56 -0
  463. package/.koolie/core/tests/erhebungen/trust-b5.py +56 -0
  464. package/.koolie/core/tests/erhebungen/turn2-schreiben-b4.py +105 -0
  465. package/.koolie/core/tests/erhebungen/umgebungen-bauen-b4.py +377 -0
  466. package/.koolie/core/tests/erhebungen/umgebungen-bauen-b5.py +363 -0
  467. package/.koolie/core/tests/erhebungen/zaehlen46.py +74 -0
  468. package/.koolie/core/tests/erhebungen/zustand-b4.py +82 -0
  469. package/.koolie/core/tests/erhebungen/zustand-b5.py +82 -0
  470. package/.koolie/core/tests/protocols/2026-09-10-AP2-claude-code-wirkungsnachweise.md +194 -0
  471. package/.koolie/core/tests/protocols/2026-09-10-AP2-claude-code.md +468 -0
  472. package/.koolie/core/tests/protocols/2026-09-10-CR-2026-020-akteursbezeichnung.md +99 -0
  473. package/.koolie/core/tests/protocols/2026-09-10-CR-2026-021-hook-interpreter.md +138 -0
  474. package/.koolie/core/tests/protocols/2026-09-10-CR-2026-022-artefaktversionen.md +87 -0
  475. package/.koolie/core/tests/protocols/2026-09-10-CR-2026-023-shell-lesesperre.md +135 -0
  476. package/.koolie/core/tests/protocols/2026-09-10-CR-2026-024-clientbindungen.md +98 -0
  477. package/.koolie/core/tests/protocols/2026-09-10-FW-DS-03.md +90 -0
  478. package/.koolie/core/tests/protocols/2026-09-10-FW-KO-01.md +105 -0
  479. package/.koolie/core/tests/protocols/2026-09-10-FW-KO-02.md +123 -0
  480. package/.koolie/core/tests/protocols/2026-09-10-FW-KO-04.md +73 -0
  481. package/.koolie/core/tests/protocols/2026-09-10-FW-RE-02.md +99 -0
  482. package/.koolie/core/tests/protocols/2026-09-10-FW-VN-01-wiederholung.md +108 -0
  483. package/.koolie/core/tests/protocols/2026-09-10-FW-VN-01.md +249 -0
  484. package/.koolie/core/tests/protocols/2026-09-10-FW-ZA-05.md +99 -0
  485. package/.koolie/core/tests/protocols/2026-09-11-AP2-devin-desktop.md +257 -0
  486. package/.koolie/core/tests/protocols/2026-09-11-CR-2026-026-fail-closed.md +113 -0
  487. package/.koolie/core/tests/protocols/2026-09-11-erhebungen-K21-K26.md +243 -0
  488. package/.koolie/core/tests/protocols/2026-09-11-wirkungsnachweise-0.26.0.md +101 -0
  489. package/.koolie/core/tests/protocols/2026-09-12-B01-allowed-tools.md +152 -0
  490. package/.koolie/core/tests/protocols/2026-09-12-B04-B05-gegenpruefung.md +204 -0
  491. package/.koolie/core/tests/protocols/2026-09-12-erhebungen-K28-S5-B9-bypass.md +268 -0
  492. package/.koolie/core/tests/protocols/2026-09-12-mehrprojekt-arbeitsbereich.md +154 -0
  493. package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.26.1.md +126 -0
  494. package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.27.0.md +114 -0
  495. package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.28.0.md +129 -0
  496. package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.29.0.md +121 -0
  497. package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.30.0.md +112 -0
  498. package/.koolie/core/tests/protocols/2026-09-12-wirkungsnachweise-0.31.0.md +107 -0
  499. package/.koolie/core/tests/protocols/2026-09-13-B06-gegenpruefung.md +370 -0
  500. package/.koolie/core/tests/protocols/2026-09-13-B07-B09-gegenpruefung.md +211 -0
  501. package/.koolie/core/tests/protocols/2026-09-13-B08-B11-gegenpruefung.md +179 -0
  502. package/.koolie/core/tests/protocols/2026-09-13-erhebung-disallowed-tools.md +147 -0
  503. package/.koolie/core/tests/protocols/2026-09-13-erhebung-unteragent-tiefe.md +139 -0
  504. package/.koolie/core/tests/protocols/2026-09-13-erhebung-unteragent.md +214 -0
  505. package/.koolie/core/tests/protocols/2026-09-13-gegenpruefung-berechtigungsdatei.md +253 -0
  506. package/.koolie/core/tests/protocols/2026-09-13-gegenpruefung-stumme-brueche.md +202 -0
  507. package/.koolie/core/tests/protocols/2026-09-13-gegenpruefung-werkzeugabbildung.md +219 -0
  508. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.32.0.md +133 -0
  509. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.33.0.md +169 -0
  510. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.34.0.md +187 -0
  511. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.35.0.md +187 -0
  512. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.36.0.md +137 -0
  513. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.37.0.md +112 -0
  514. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.38.0.md +154 -0
  515. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.39.0.md +188 -0
  516. package/.koolie/core/tests/protocols/2026-09-13-wirkungsnachweise-0.40.0.md +214 -0
  517. package/.koolie/core/tests/protocols/2026-09-14-erhebung-devin-werkzeuge.md +267 -0
  518. package/.koolie/core/tests/protocols/2026-09-14-erhebung-skillaufruf.md +238 -0
  519. package/.koolie/core/tests/protocols/2026-09-14-gegenpruefung-pruefregister.md +156 -0
  520. package/.koolie/core/tests/protocols/2026-09-14-gegenpruefung-schlitzdeckung.md +206 -0
  521. package/.koolie/core/tests/protocols/2026-09-14-gegenpruefung-skillwahl.md +127 -0
  522. package/.koolie/core/tests/protocols/2026-09-14-migrationslauf-pilot.md +134 -0
  523. package/.koolie/core/tests/protocols/2026-09-14-wirkungsnachweise-0.41.0.md +175 -0
  524. package/.koolie/core/tests/protocols/2026-09-14-wirkungsnachweise-0.42.0.md +180 -0
  525. package/.koolie/core/tests/protocols/2026-09-14-wirkungsnachweise-0.43.0.md +165 -0
  526. package/.koolie/core/tests/protocols/2026-09-14-wirkungsnachweise-0.44.0.md +130 -0
  527. package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-d11-zaehlregeln.md +311 -0
  528. package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-modulstatus.md +524 -0
  529. package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-nicht-skill-traeger.md +225 -0
  530. package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-restliche-nicht-skill-traeger.md +345 -0
  531. package/.koolie/core/tests/protocols/2026-09-15-gegenpruefung-strukturentscheidungen.md +392 -0
  532. package/.koolie/core/tests/protocols/2026-09-15-herrichtung-uebungsrepositorium.md +213 -0
  533. package/.koolie/core/tests/protocols/2026-09-15-migrationslauf-pilot-0.46.0.md +143 -0
  534. package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.45.0.md +127 -0
  535. package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.46.0.md +193 -0
  536. package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.47.0.md +149 -0
  537. package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.49.0.md +202 -0
  538. package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.50.0.md +183 -0
  539. package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.51.0.md +202 -0
  540. package/.koolie/core/tests/protocols/2026-09-15-wirkungsnachweise-0.52.0.md +168 -0
  541. package/.koolie/core/tests/protocols/2026-09-16-AP2-zielversion-devin-desktop.md +231 -0
  542. package/.koolie/core/tests/protocols/2026-09-16-wirkungsnachweise-0.53.0.md +350 -0
  543. package/.koolie/core/tests/protocols/2026-09-17-nachtrag-migrationshinweis-0.54.1.md +121 -0
  544. package/.koolie/core/tests/protocols/2026-09-17-sitzungstest-pi-ds.md +523 -0
  545. package/.koolie/core/tests/protocols/2026-09-17-sitzungstest-schranken.md +433 -0
  546. package/.koolie/core/tests/protocols/2026-09-17-wirkungsnachweise-0.54.0.md +159 -0
  547. package/.koolie/core/tests/protocols/2026-09-18-FW-AK-01.md +442 -0
  548. package/.koolie/core/tests/protocols/2026-09-18-FW-KO-05.md +231 -0
  549. package/.koolie/core/tests/protocols/2026-09-18-herrichtung-uebungsrepositorium.md +273 -0
  550. package/.koolie/core/tests/protocols/2026-09-18-nachtrag-preis-umbenennung-0.56.1.md +102 -0
  551. package/.koolie/core/tests/protocols/2026-09-18-sitzungstest-5.md +349 -0
  552. package/.koolie/core/tests/protocols/2026-09-18-sitzungstest-ne-sc.md +430 -0
  553. package/.koolie/core/tests/protocols/2026-09-18-sitzungstest-pi-ds-2.md +499 -0
  554. package/.koolie/core/tests/protocols/2026-09-18-vorbedingungen-sitzungstest-5-zweiter-durchgang.md +170 -0
  555. package/.koolie/core/tests/protocols/2026-09-18-vorbedingungen-testblaetter.md +184 -0
  556. package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.55.0.md +202 -0
  557. package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.56.0.md +135 -0
  558. package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.56.2.md +154 -0
  559. package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.57.0.md +228 -0
  560. package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.57.1.md +262 -0
  561. package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.58.0.md +135 -0
  562. package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.59.0.md +150 -0
  563. package/.koolie/core/tests/protocols/2026-09-18-wirkungsnachweise-0.60.0.md +340 -0
  564. package/.koolie/core/tests/protocols/2026-09-19-herrichtung-buendel-4.md +235 -0
  565. package/.koolie/core/tests/protocols/2026-09-19-k77-zurechenbarkeit.md +236 -0
  566. package/.koolie/core/tests/protocols/2026-09-19-pruefapparat-filter.md +50 -0
  567. package/.koolie/core/tests/protocols/2026-09-19-pruefmittelwort-und-buendelschnitt.md +239 -0
  568. package/.koolie/core/tests/protocols/2026-09-19-sechzehnte-praeparation.md +135 -0
  569. package/.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-1.md +250 -0
  570. package/.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-2.md +229 -0
  571. package/.koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-3.md +293 -0
  572. package/.koolie/core/tests/protocols/2026-09-19-vorbedingungen-buendel-2.md +236 -0
  573. package/.koolie/core/tests/protocols/2026-09-19-vorbedingungen-buendel-3.md +253 -0
  574. package/.koolie/core/tests/protocols/2026-09-19-vorbedingungen-buendel-4.md +138 -0
  575. package/.koolie/core/tests/protocols/2026-09-20-messapparat-buendel-4.md +433 -0
  576. package/.koolie/core/tests/protocols/2026-09-20-testblaetter-buendel-4.md +321 -0
  577. package/.koolie/core/tests/protocols/2026-09-20-uebergabe-im-release-commit.md +146 -0
  578. package/.koolie/core/tests/protocols/2026-09-20-vorbedingungen-nachlauf-b4.md +259 -0
  579. package/.koolie/core/tests/protocols/2026-09-21-arbeitsplatz-im-kern.md +127 -0
  580. package/.koolie/core/tests/protocols/2026-09-21-nachlauf-buendel-4.md +157 -0
  581. package/.koolie/core/tests/protocols/2026-09-21-vorbedingungen-buendel-5.md +247 -0
  582. package/.koolie/core/tests/protocols/2026-09-21-wiederaufnahme-nachlauf-b4.md +190 -0
  583. package/.koolie/core/tests/protocols/2026-09-22-ap2-rest-devin-desktop.md +614 -0
  584. package/.koolie/core/tests/protocols/2026-09-22-hauptdokument-ap11.md +443 -0
  585. package/.koolie/core/tests/protocols/2026-09-22-herrichtung-buendel-5.md +224 -0
  586. package/.koolie/core/tests/protocols/2026-09-22-messtag-buendel-5.md +327 -0
  587. package/.koolie/core/tests/protocols/2026-09-22-quellenzuordnung-matrixzeilen.md +230 -0
  588. package/.koolie/core/tests/protocols/2026-09-22-sammelzellen-zentraler-katalog.md +354 -0
  589. package/.koolie/core/tests/protocols/2026-09-22-umbenennung-koolie.md +296 -0
  590. package/.koolie/core/tests/protocols/2026-09-22-verify-marker-abschaffen.md +283 -0
  591. package/.koolie/core/tests/protocols/2026-09-22-vortrag-und-name.md +261 -0
  592. package/.koolie/core/tests/protocols/2026-09-22-wirkungsnachweise-0.86.0.md +158 -0
  593. package/.koolie/core/tests/protocols/2026-09-23-archiv-zeilenenden.md +113 -0
  594. package/.koolie/core/tests/protocols/2026-09-23-bau-openai-codex.md +168 -0
  595. package/.koolie/core/tests/protocols/2026-09-23-chronik-und-vorlage.md +224 -0
  596. package/.koolie/core/tests/protocols/2026-09-23-erhebung-openai-codex.md +309 -0
  597. package/.koolie/core/tests/protocols/2026-09-23-freigabelauf-1.0.0-vorbereitung.md +119 -0
  598. package/.koolie/core/tests/protocols/2026-09-23-freigabelauf-1.0.0.md +150 -0
  599. package/.koolie/core/tests/protocols/2026-09-23-gegenzeichnung-rollenfrage.md +198 -0
  600. package/.koolie/core/tests/protocols/2026-09-23-reihenfolge-des-hebens.md +220 -0
  601. package/.koolie/core/tests/protocols/2026-09-23-word-fassung-und-blinder-fleck.md +307 -0
  602. package/.koolie/core/tests/protocols/2026-09-24-kopierweg-kern.md +98 -0
  603. package/.koolie/core/tests/protocols/2026-09-24-overlay-werte-einordnung.md +111 -0
  604. package/.koolie/core/tests/protocols/2026-09-24-pfadlisten-nul-getrennt.md +128 -0
  605. package/.koolie/core/tests/protocols/2026-09-24-uebergabe-lokal.md +85 -0
  606. package/.koolie/core/tests/protocols/2026-09-25-code-pack-posten.md +86 -0
  607. package/.koolie/core/tests/protocols/2026-09-25-dokumentationsstandard.md +101 -0
  608. package/.koolie/core/tests/protocols/2026-09-25-installer-je-zielsystem.md +134 -0
  609. package/.koolie/core/tests/protocols/2026-09-25-klasse-b-core-laufzeit.md +126 -0
  610. package/.koolie/core/tests/protocols/2026-09-25-klasse-b-governance.md +133 -0
  611. package/.koolie/core/tests/protocols/2026-09-25-klasse-b-skills.md +91 -0
  612. package/.koolie/core/tests/protocols/2026-09-25-lieferumfang.md +76 -0
  613. package/.koolie/core/tests/protocols/2026-09-25-overlay-muster-dokumente.md +107 -0
  614. package/.koolie/core/tests/protocols/2026-09-25-overlay-muster-general.md +100 -0
  615. package/.koolie/core/tests/protocols/2026-09-25-regel-register-posten.md +87 -0
  616. package/.koolie/core/tests/protocols/2026-09-26-attributionszeile.md +83 -0
  617. package/.koolie/core/tests/protocols/2026-09-26-auffindbarkeit.md +85 -0
  618. package/.koolie/core/tests/protocols/2026-09-26-bau-cursor.md +68 -0
  619. package/.koolie/core/tests/protocols/2026-09-26-bau-kiro.md +75 -0
  620. package/.koolie/core/tests/protocols/2026-09-26-mehrprojekt-tokenlast.md +174 -0
  621. package/.koolie/core/tests/protocols/2026-09-26-regelablage-pfadtoken.md +133 -0
  622. package/.koolie/core/tests/protocols/2026-09-26-skill-anweisungen.md +111 -0
  623. package/.koolie/core/tests/protocols/2026-09-26-testblaetter-modellwechsel.md +106 -0
  624. package/.koolie/core/tests/protocols/2026-09-27-mandat-und-reibung.md +58 -0
  625. package/.koolie/core/tests/protocols/2026-09-28-mcp-anbindung.md +72 -0
  626. package/.koolie/core/tests/protocols/2026-09-29-messapparat.md +75 -0
  627. package/.koolie/core/tests/protocols/2026-09-29-powershell.md +58 -0
  628. package/.koolie/core/tests/protocols/2026-09-29-pruefwerkzeuge.md +64 -0
  629. package/.koolie/core/tests/protocols/2026-09-29-registerpflege.md +228 -0
  630. package/.koolie/core/tests/protocols/2026-09-29-schutzschicht.md +95 -0
  631. package/.koolie/core/tests/protocols/2026-09-30-einsatzarchitektur.md +104 -0
  632. package/.koolie/core/tests/protocols/2026-09-30-modi-ausnahmen.md +77 -0
  633. package/.koolie/core/tests/protocols/2026-09-30-nachlauf-banner.md +85 -0
  634. package/.koolie/core/tests/protocols/2026-09-30-paketquellen.md +65 -0
  635. package/.koolie/core/tests/protocols/2026-09-30-pfadsemantik.md +79 -0
  636. package/.koolie/core/tests/protocols/2026-10-01-auftritt-und-suche.md +58 -0
  637. package/.koolie/core/tests/protocols/2026-10-01-befehl-im-projektverzeichnis.md +47 -0
  638. package/.koolie/core/tests/protocols/2026-10-01-erste-veroeffentlichung.md +60 -0
  639. package/.koolie/core/tests/protocols/2026-10-01-modusbindung-messfragen.md +107 -0
  640. package/.koolie/core/tests/protocols/README.md +14 -0
  641. package/.koolie/core/tests/scripts/hook-check-secrets.py +1307 -0
  642. package/.koolie/core/tests/scripts/hook-overlay-status.py +120 -0
  643. package/.koolie/core/tests/scripts/mermaid_renderer.py +67 -0
  644. package/.koolie/core/tests/scripts/overlay_status.py +130 -0
  645. package/.koolie/core/tests/scripts/probe-pruefungen.py +110 -0
  646. package/.koolie/core/tests/scripts/pruefungen/__init__.py +4 -0
  647. package/.koolie/core/tests/scripts/pruefungen/berechtigungen.py +1559 -0
  648. package/.koolie/core/tests/scripts/pruefungen/bestand.py +1433 -0
  649. package/.koolie/core/tests/scripts/pruefungen/dokumente.py +1262 -0
  650. package/.koolie/core/tests/scripts/pruefungen/gemeinsam.py +784 -0
  651. package/.koolie/core/tests/scripts/pruefungen/hooks.py +1188 -0
  652. package/.koolie/core/tests/scripts/pruefungen/overlay.py +1251 -0
  653. package/.koolie/core/tests/scripts/pruefungen/packs.py +1314 -0
  654. package/.koolie/core/tests/scripts/pruefungen/register.py +950 -0
  655. package/.koolie/core/tests/scripts/pruefungen/testkatalog.py +1202 -0
  656. package/.koolie/core/tests/scripts/pruefungen/werkzeuge.py +957 -0
  657. package/.koolie/core/tests/scripts/sonden/__init__.py +4 -0
  658. package/.koolie/core/tests/scripts/sonden/apparat.py +653 -0
  659. package/.koolie/core/tests/scripts/sonden/teil01_grundbestand_und_installation.py +999 -0
  660. package/.koolie/core/tests/scripts/sonden/teil02_packs_mandat_mcp.py +942 -0
  661. package/.koolie/core/tests/scripts/sonden/teil03_pruefungen_26_bis_36.py +1184 -0
  662. package/.koolie/core/tests/scripts/sonden/teil04_pruefungen_37_bis_45.py +1491 -0
  663. package/.koolie/core/tests/scripts/sonden/teil05_pruefungen_46_bis_55.py +1447 -0
  664. package/.koolie/core/tests/scripts/sonden/teil06_pruefungen_57_bis_65.py +739 -0
  665. package/.koolie/core/tests/scripts/sonden/teil07_overlay_und_lieferung.py +1014 -0
  666. package/.koolie/core/tests/scripts/sonden/teil08_pruefungen_66_bis_80.py +1325 -0
  667. package/.koolie/core/tests/scripts/sonden/teil09_pruefmittel_81_und_82.py +505 -0
  668. package/.koolie/core/tests/scripts/sonden/teil10_pruefungen_83_bis_95.py +1218 -0
  669. package/.koolie/core/tests/scripts/sonden/teil11_pruefungen_104_und_105.py +149 -0
  670. package/.koolie/core/tests/scripts/sonden/teil12_pruefungen_106_und_107.py +136 -0
  671. package/.koolie/core/tests/scripts/sonden/teil13_pfad_und_mustersemantik.py +150 -0
  672. package/.koolie/core/tests/scripts/sonden/teil14_modi_ausnahmen_skills.py +204 -0
  673. package/.koolie/core/tests/scripts/sonden/teil15_banner_und_nachlauf.py +193 -0
  674. package/.koolie/core/tests/scripts/sonden/teil16_koexistenz.py +114 -0
  675. package/.koolie/core/tests/scripts/sonden/teil17_paketquellen.py +115 -0
  676. package/.koolie/core/tests/scripts/sonden/teil18_modusbindung_m3_m5.py +113 -0
  677. package/.koolie/core/tests/scripts/validate-framework.py +1104 -0
  678. package/.koolie/core/tests/scripts/validate-output.py +296 -0
  679. package/.koolie/core/wirksamkeit.py +430 -0
  680. package/CONTRIBUTING.md +119 -0
  681. package/LICENSE +674 -0
  682. package/QUICKSTART.en.md +135 -0
  683. package/QUICKSTART.md +129 -0
  684. package/README.en.md +108 -0
  685. package/README.md +107 -0
  686. package/install.cmd +44 -0
  687. package/install.command +46 -0
  688. package/package.json +21 -0
  689. package/paketquellen/README.md +41 -0
  690. package/paketquellen/bauen.py +411 -0
  691. package/paketquellen/koolie.cmd +23 -0
  692. package/paketquellen/koolie_befehl.py +82 -0
  693. package/paketquellen/npm/koolie.js +26 -0
@@ -0,0 +1,1218 @@
1
+ """Sonden zu den Pruefungen 83 bis 95 und 4 (Zeichengrenze der Wurzel-Anweisung) und zu den
2
+ Einstiegsdokumenten der Wurzel.
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 json
11
+ import os
12
+ import re
13
+ import shutil
14
+
15
+ from .apparat import (
16
+ aufraeumen, baumhash, buendel, installation, kopie, lies, melde, notiz, P,
17
+ Praeparationsfehler, QUELLE, schreib, validator_ausgabe)
18
+
19
+
20
+ # --- Pruefung 83: die Chronik zaehlt ihr eigenes Release zu Ende (CR-2026-131) -----
21
+ #
22
+ # FUENF EINHEITEN, UND DIE ZWEITE GEGENPROBE IST DIE, DIE MAN WEGLASSEN WUERDE.
23
+ # 83a (Gegenprobe) - die berichtigte Chronik laeuft durch, und die Pruefung ist
24
+ # dabei nachweislich gelaufen (keine Ankermeldung).
25
+ # 83b (Gegenprobe) - 🔴 DIE, DIE DEN ZUSCHNITT TRAEGT. Die Releasetabelle ist NICHT
26
+ # sortiert: gemessen am 2026-09-23 stand `1.0.1` VOR `1.0.0`
27
+ # (D-337). Eine Spanne, die NICHT die hoechste ist, wird hinter
28
+ # die hoechste gestellt - die Pruefung muss GRUEN bleiben, weil
29
+ # sie die hoechste Obergrenze nimmt und nicht die zuletzt
30
+ # geschriebene. Ohne diese Gegenprobe waere die Reihenfolgefestig-
31
+ # keit eine Behauptung im Kopfkommentar statt eine gemessene
32
+ # Eigenschaft - genau die Bauform, die 0.90.0 zweimal gekostet
33
+ # hat (D-326, D-299).
34
+ # 83a (Sonde) - eine Entscheidung wird ins Register gehaengt, ohne die Spanne
35
+ # zu heben: der gemessene Fall aus 1.1.0 wird gemeldet, und die
36
+ # Meldung nennt die fehlende Kennung.
37
+ # 83b (Sonde) - die Spannenschreibweise entfernt: der verlorene Anker wird als
38
+ # Fehler gemeldet, statt leise zu bestehen (D-23).
39
+ # 83c (Sonde) - eine Spanne ueber die hoechste Kennung hinaus: die Chronik
40
+ # nennt eine Entscheidung, die es nicht gibt.
41
+ #
42
+ # KEINE EINHEIT HAELT EINE KENNUNG WOERTLICH. Sie lesen die hoechste aus dem Register
43
+ # und rechnen daran - dieselbe Lehre wie bei Pruefung 78, 81 und 82: Eine Sonde, die
44
+ # einen Wert mitpflegen muss, faellt beim naechsten Release aus, und zwar als
45
+ # scheinbarer Befund.
46
+ M83_FEHLEND = "In der Chronik fehlen"
47
+ M83_UEBER = "das Register fuehrt hoechstens"
48
+ M83_ANKER = "keine Release-Spanne der Form"
49
+ M83_REGISTER = "keine Registerzeile '| D-NNN |' gefunden - Pruefung 83"
50
+
51
+ P83_ROADMAP = ".koolie/core/docs/ROADMAP.md"
52
+ P83_REGISTER = ".koolie/core/governance/DECISION_LOG.md"
53
+
54
+
55
+ def _83_hoechste(root: str) -> int:
56
+ """Die hoechste vergebene D-Kennung - ausgerechnet, nicht gewusst."""
57
+ text = lies(P(root, *P83_REGISTER.split("/")))
58
+ return max(int(n) for n in re.findall(r"^\|\s*(?:\*\*)?D-(\d+)", text, re.M))
59
+
60
+
61
+ def _83_spanne(root: str) -> tuple:
62
+ """(Volltext, Untergrenze, Obergrenze) der hoechsten Spanne in der ROADMAP."""
63
+ text = lies(P(root, *P83_ROADMAP.split("/")))
64
+ treffer = re.findall(r"\*\*D-(\d+)\*\*\s*bis\s*\*\*D-(\d+)\*\*", text)
65
+ a, b = max(treffer, key=lambda t: int(t[1]))
66
+ return text, int(a), int(b)
67
+
68
+
69
+ def sonden_chronikspanne() -> None:
70
+ """Wirkungsnachweis zu Pruefung 83."""
71
+ root = kopie()
72
+ try:
73
+ rpfad = P(root, *P83_ROADMAP.split("/"))
74
+ dpfad = P(root, *P83_REGISTER.split("/"))
75
+ rtext, unten, oben = _83_spanne(root)
76
+ dtext = lies(dpfad)
77
+ hoechste = _83_hoechste(root)
78
+ woertlich = "**D-%d** bis **D-%d**" % (unten, oben)
79
+
80
+ # --- Gegenprobe 83a: die berichtigte Chronik laeuft durch -------------------
81
+ aus = validator_ausgabe(root)
82
+ ok = (M83_FEHLEND not in aus and M83_UEBER not in aus
83
+ and M83_ANKER not in aus and M83_REGISTER not in aus)
84
+ melde("GEGENPROBE", "83a", ok,
85
+ "Die berichtigte Chronik laeuft durch - die hoechste Release-Spanne "
86
+ "endet bei der hoechsten vergebenen Kennung, und die Pruefung ist dabei "
87
+ "nachweislich gelaufen")
88
+ if not ok:
89
+ notiz(" Ausgabe:", " | ".join(
90
+ z for z in aus.splitlines() if "83" in z or "Spanne" in z)[:400])
91
+
92
+ # --- Gegenprobe 83b: DIE REIHENFOLGEPROBE (D-337) ---------------------------
93
+ # Eine NIEDRIGERE Spanne wird HINTER die hoechste gestellt. Die Pruefung nimmt
94
+ # die hoechste Obergrenze, nicht die zuletzt geschriebene - genau deshalb ist
95
+ # sie gegen eine unsortierte Releasetabelle fest.
96
+ nachzuegler = "\n| **PROBE** | **D-%d** bis **D-%d** | Probe 83b |\n" % (
97
+ unten, max(unten, oben - 1))
98
+ schreib(rpfad, rtext + nachzuegler)
99
+ aus = validator_ausgabe(root)
100
+ melde("GEGENPROBE", "83b", M83_FEHLEND not in aus and M83_UEBER not in aus,
101
+ "Eine niedrigere Spanne HINTER der hoechsten laeuft durch - die Pruefung "
102
+ "nimmt die hoechste Obergrenze, nicht die zuletzt geschriebene. Gemessen "
103
+ "stand `1.0.1` vor `1.0.0` (D-337)")
104
+ if M83_FEHLEND in aus or M83_UEBER in aus:
105
+ notiz(" Ausgabe:", " | ".join(
106
+ z for z in aus.splitlines() if "ROADMAP" in z)[:400])
107
+ schreib(rpfad, rtext)
108
+
109
+ # --- Sonde 83a: eine Entscheidung ohne Hebung der Spanne --------------------
110
+ vorher = baumhash(root)
111
+ neue = hoechste + 1
112
+ zeile = ("| D-%d | **Probe 83a.** | Probe | Probe | Probe | 2026-01-01 |"
113
+ % neue)
114
+ anker = "| D-%d |" % hoechste
115
+ if anker not in dtext:
116
+ raise Praeparationsfehler(
117
+ "Sonde 83a: keine Registerzeile `%s` - die Sonde hat ihren "
118
+ "Gegenstand verloren" % anker)
119
+ stelle = dtext.index("\n", dtext.index(anker))
120
+ schreib(dpfad, dtext[:stelle] + "\n" + zeile + dtext[stelle:])
121
+ if baumhash(root) == vorher:
122
+ raise Praeparationsfehler("Sonde 83a hat nichts geschrieben")
123
+ aus = validator_ausgabe(root)
124
+ ok = M83_FEHLEND in aus and ("D-%d" % neue) in aus
125
+ melde("SONDE", "83a", ok,
126
+ "Eine Entscheidung, die ins Register faellt, ohne dass die Spanne "
127
+ "nachgezogen wird, wird gemeldet - und die Meldung nennt die fehlende "
128
+ "Kennung. Der gemessene Fall aus 1.1.0")
129
+ if not ok:
130
+ notiz(" Ausgabe:", " | ".join(
131
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
132
+ schreib(dpfad, dtext)
133
+
134
+ # --- Sonde 83b: der verlorene Anker -----------------------------------------
135
+ if woertlich not in rtext:
136
+ raise Praeparationsfehler(
137
+ "Sonde 83b: die Spanne `%s` steht nicht woertlich in %s - die Sonde "
138
+ "hat ihren Gegenstand verloren" % (woertlich, P83_ROADMAP))
139
+ ohne = rtext.replace("** bis **D-", "** und **D-")
140
+ schreib(rpfad, ohne)
141
+ aus = validator_ausgabe(root)
142
+ melde("SONDE", "83b", M83_ANKER in aus,
143
+ "Geht die Spannenschreibweise verloren, meldet die Pruefung es - eine "
144
+ "Konsistenzpruefung ohne Anker bestuende sonst leise (D-23)")
145
+ if M83_ANKER not in aus:
146
+ notiz(" Ausgabe:", " | ".join(
147
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
148
+ schreib(rpfad, rtext)
149
+
150
+ # --- Gegenprobe 83c: DIE SYNTHETISCHE KENNUNG GEHOERT HERAUS ---------------
151
+ # 🔴 DIESE EINHEIT IST EIN GEMESSENER BEFUND, NICHT EINE VORSICHTSMASSNAHME.
152
+ # Die Gegenprobe 58b legt eine Registerzeile mit die Sondenkennung von Prüfung 58 an - der Kennung, die
153
+ # den Sonden gehoert. Beim ersten Abnahmelauf von 1.2.0 las diese Pruefung sie
154
+ # als hoechste vergebene und meldete 654 fehlende Entscheidungen. Der Befund
155
+ # dahinter war groesser: die Sondenkennung von Prüfung 58 stand in KEINER Liste der belegten
156
+ # synthetischen Kennungen, obwohl der Apparat sie seit 0.70.0 benutzt - und
157
+ # Pruefung 50 wie 58 konnten es nie sehen, weil sie eine GENANNTE Kennung ohne
158
+ # Registerzeile melden und diese hier ihre Zeile selbst anlegt.
159
+ # ➡️ Erst eine Pruefung, die die OBERGRENZE misst statt der Zugehoerigkeit,
160
+ # trifft sie. Diese Einheit haelt fest, dass sie herausgenommen bleibt.
161
+ synth = "D-" + "993"
162
+ zeile_s = ("| %s | Sondenentscheidung | Sondenbegruendung | Sondenalternative "
163
+ "| entschieden | 2026-01-01 |" % synth)
164
+ stelle = dtext.index("\n", dtext.index(anker))
165
+ schreib(dpfad, dtext[:stelle] + "\n" + zeile_s + dtext[stelle:])
166
+ aus = validator_ausgabe(root)
167
+ melde("GEGENPROBE", "83c", M83_FEHLEND not in aus and M83_UEBER not in aus,
168
+ "Die synthetische Kennung des Pruefapparats hebt die Obergrenze NICHT - "
169
+ "sie gehoert den Sonden und wird nie echt vergeben. Gemessen als Befund "
170
+ "am ersten Abnahmelauf von 1.2.0 (D-335)")
171
+ if M83_FEHLEND in aus or M83_UEBER in aus:
172
+ notiz(" Ausgabe:", " | ".join(
173
+ z for z in aus.splitlines() if "ROADMAP" in z)[:400])
174
+ schreib(dpfad, dtext)
175
+
176
+ # --- Sonde 83c: eine Spanne ueber die hoechste Kennung hinaus ---------------
177
+ zuweit = rtext.replace(woertlich,
178
+ "**D-%d** bis **D-%d**" % (unten, hoechste + 5), 1)
179
+ if zuweit == rtext:
180
+ raise Praeparationsfehler("Sonde 83c hat nichts geaendert")
181
+ schreib(rpfad, zuweit)
182
+ aus = validator_ausgabe(root)
183
+ melde("SONDE", "83c", M83_UEBER in aus,
184
+ "Eine Spanne ueber die hoechste vergebene Kennung hinaus wird gemeldet - "
185
+ "die Chronik nennt sonst eine Entscheidung, die es nicht gibt")
186
+ if M83_UEBER not in aus:
187
+ notiz(" Ausgabe:", " | ".join(
188
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
189
+ finally:
190
+ aufraeumen(os.path.dirname(root))
191
+
192
+
193
+ buendel(sonden_chronikspanne,
194
+ "Pruefung 83 haelt die Chronik gegen das Register und ist gegen eine "
195
+ "unsortierte Releasetabelle fest, ohne eine Kennung woertlich zu kennen")
196
+
197
+
198
+ # --- Pruefung 84: die Vorlage ist kein Client Pack (CR-2026-131) -------------------
199
+ #
200
+ # VIER EINHEITEN, UND DIE GEGENPROBE IST HIER DIE HAELFTE DES BEFUNDES.
201
+ # 84a (Gegenprobe) - 🔴 DIE MESSUNG, DIE D-336 AUSGELOEST HAT, ALS DAUERHAFTE
202
+ # EINHEIT. Die Vorlage mit einem Probemanifest laeuft NICHT mehr
203
+ # als drittes Pack mit: `_client_packs()` nimmt sie seit D-336
204
+ # nicht auf. Gemessen am 2026-09-23 war genau das der Befund -
205
+ # drei Packs mit Manifest und 0 Fehler. Diese Einheit haelt fest,
206
+ # dass die Ausnahme greift, und nicht nur, dass Pruefung 84
207
+ # meldet.
208
+ # 84b (Gegenprobe) - die unveraenderte Vorlage laeuft durch, und die Pruefung ist
209
+ # dabei nachweislich gelaufen.
210
+ # 84a (Sonde) - ein manifest.json in der Vorlage wird gemeldet.
211
+ # 84b (Sonde) - ein root-template/ in der Vorlage wird gemeldet.
212
+ # 84c (Sonde) - die fehlende CLIENT_PACK.md wird gemeldet, statt leise zu
213
+ # bestehen (D-23).
214
+ M84_BESTANDTEIL = "die Vorlage traegt einen Bestandteil"
215
+ M84_FEHLT = "Sie ist der einzige Bestandteil, den die Vorlage traegt"
216
+ M84_VERZEICHNIS = "nimmt sie seit D-336 ausdruecklich NICHT auf"
217
+
218
+ P84_VORLAGE = ".koolie/core/clients/_template"
219
+ P84_VORBILD = ".koolie/core/clients/claude-code"
220
+
221
+
222
+ def sonden_vorlage_kein_pack() -> None:
223
+ """Wirkungsnachweis zu Pruefung 84."""
224
+ root = kopie()
225
+ try:
226
+ vdir = P(root, *P84_VORLAGE.split("/"))
227
+ vorbild = P(root, *P84_VORBILD.split("/"))
228
+ mpfad = os.path.join(vdir, "manifest.json")
229
+ cpfad = os.path.join(vdir, "CLIENT_PACK.md")
230
+ ctext = lies(cpfad)
231
+
232
+ # --- Gegenprobe 84b: die unveraenderte Vorlage laeuft durch -----------------
233
+ aus = validator_ausgabe(root)
234
+ ok = (M84_BESTANDTEIL not in aus and M84_FEHLT not in aus
235
+ and M84_VERZEICHNIS not in aus)
236
+ melde("GEGENPROBE", "84b", ok,
237
+ "Die unveraenderte Vorlage laeuft durch - sie traegt genau eine "
238
+ "CLIENT_PACK.md, und die Pruefung ist dabei nachweislich gelaufen")
239
+ if not ok:
240
+ notiz(" Ausgabe:", " | ".join(
241
+ z for z in aus.splitlines() if "_template" in z)[:400])
242
+
243
+ # --- Gegenprobe 84a: DIE MESSUNG, DIE D-336 AUSGELOEST HAT ------------------
244
+ # Ein Probemanifest in der Vorlage - eine Kopie des Manifests eines ECHTEN
245
+ # Clients. Vor D-336 lief die Vorlage damit als drittes Pack durch alle
246
+ # Pruefungen, und der Validator meldete NULL. Danach meldet Pruefung 84 den
247
+ # Bestandteil, und KEINE andere Pruefung nimmt die Vorlage als Pack auf.
248
+ schreib(mpfad, lies(os.path.join(vorbild, "manifest.json")))
249
+ aus = validator_ausgabe(root)
250
+ fremd = [z for z in aus.splitlines()
251
+ if "_template" in z and M84_BESTANDTEIL not in z]
252
+ melde("GEGENPROBE", "84a", not fremd,
253
+ "Die Vorlage mit Probemanifest loest KEINE Packpruefung aus - "
254
+ "`_client_packs()` nimmt sie seit D-336 nicht auf. Vor D-336 lief sie "
255
+ "als drittes Pack durch, und der Validator meldete null")
256
+ if fremd:
257
+ notiz(" Ausgabe:", " | ".join(fremd)[:400])
258
+
259
+ # --- Sonde 84a: ein manifest.json in der Vorlage ----------------------------
260
+ melde("SONDE", "84a", M84_BESTANDTEIL in aus,
261
+ "Ein manifest.json in der Vorlage wird gemeldet - eine Vorlage, die nur "
262
+ "durch ihre Unvollstaendigkeit ungeprueft bleibt, ist nicht ausgenommen")
263
+ if M84_BESTANDTEIL not in aus:
264
+ notiz(" Ausgabe:", " | ".join(
265
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
266
+ os.remove(mpfad)
267
+
268
+ # --- Sonde 84b: ein root-template/ in der Vorlage ---------------------------
269
+ rt = os.path.join(vdir, "root-template")
270
+ os.makedirs(rt, exist_ok=True)
271
+ schreib(os.path.join(rt, "README.md"), "# Probe 84b\n")
272
+ aus = validator_ausgabe(root)
273
+ melde("SONDE", "84b", M84_BESTANDTEIL in aus,
274
+ "Ein root-template/ in der Vorlage wird gemeldet - derselbe Zuschnitt "
275
+ "wie beim Manifest, und beide stehen in clients/README.md Abschnitt 3")
276
+ if M84_BESTANDTEIL not in aus:
277
+ notiz(" Ausgabe:", " | ".join(
278
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
279
+ shutil.rmtree(rt)
280
+
281
+ # --- Sonde 84c: die fehlende CLIENT_PACK.md ---------------------------------
282
+ os.remove(cpfad)
283
+ aus = validator_ausgabe(root)
284
+ melde("SONDE", "84c", M84_FEHLT in aus,
285
+ "Geht die CLIENT_PACK.md der Vorlage verloren, meldet die Pruefung es - "
286
+ "ohne ihren Gegenstand bestuende sie leise (D-23)")
287
+ if M84_FEHLT not in aus:
288
+ notiz(" Ausgabe:", " | ".join(
289
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
290
+ schreib(cpfad, ctext)
291
+ finally:
292
+ aufraeumen(os.path.dirname(root))
293
+
294
+
295
+ buendel(sonden_vorlage_kein_pack,
296
+ "Pruefung 84 haelt die Vorlage aus der Packmenge heraus, und die Gegenprobe "
297
+ "misst die Ausnahme selbst und nicht nur die Meldung")
298
+
299
+
300
+ # --- Pruefung 85: eine Zielangabe ueberlebt ihr Release nicht (CR-2026-132) --------
301
+ #
302
+ # VIER EINHEITEN, UND DIE ZWEITE GEGENPROBE IST DIE, DIE MAN WEGLASSEN WUERDE.
303
+ # 85a (Gegenprobe) - die berichtigte ROADMAP laeuft durch, und die Pruefung ist dabei
304
+ # nachweislich gelaufen.
305
+ # 85b (Gegenprobe) - 🔴 EINE ZIELANGABE IN DER ZUKUNFT MUSS DURCHLAUFEN. Ohne diese
306
+ # Einheit koennte die Pruefung jede Ueberschrift melden und saehe
307
+ # dabei genauso gruen aus wie eine, die die Sache misst. Sie
308
+ # traegt zugleich die benannte Grenze: Ein Abschnitt, dessen Ziel
309
+ # in der Zukunft liegt, kann laengst erledigt sein und kommt durch
310
+ # (K-116).
311
+ # 85a (Sonde) - eine Zielangabe, die VERSION erreicht hat, wird gemeldet - der
312
+ # gemessene Fall aus dem Vorbedingungsdurchgang von 1.3.0.
313
+ # 85b (Sonde) - der verlorene Anker: verschwindet die Zielangabe aus der
314
+ # Ueberschrift, meldet die Pruefung es, statt leise zu bestehen
315
+ # (D-23). Das ist zugleich die Probe auf D-124: Ein Posten ohne
316
+ # Zahl bleibt liegen - und entzoege sich dieser Pruefung.
317
+ M85_ERREICHT = "ist erreicht. Entweder ist der Posten"
318
+ M85_OHNE_ZIEL = "nennen kein Ziel-Release"
319
+ M85_ANKER = "keine Ueberschrift '### Geplant: …' gefunden"
320
+
321
+ P85_ROADMAP = ".koolie/core/docs/ROADMAP.md"
322
+ P85_VERSION = ".koolie/core/VERSION"
323
+
324
+
325
+ def _85_ueberschrift(text: str) -> str:
326
+ """Die erste Planueberschrift mit Zielangabe - ausgerechnet, nicht gewusst."""
327
+ for zeile in text.splitlines():
328
+ if zeile.startswith("### Geplant:") and "Ziel-Release" in zeile:
329
+ return zeile
330
+ raise Praeparationsfehler(
331
+ "Sonden zu 85: keine Ueberschrift '### Geplant: … Ziel-Release …' in %s - die "
332
+ "Sonden haben ihren Gegenstand verloren" % P85_ROADMAP)
333
+
334
+
335
+ def sonden_zielangabe() -> None:
336
+ """Wirkungsnachweis zu Pruefung 85."""
337
+ root = kopie()
338
+ try:
339
+ rpfad = P(root, *P85_ROADMAP.split("/"))
340
+ rtext = lies(rpfad)
341
+ stand = lies(P(root, *P85_VERSION.split("/"))).strip()
342
+ kopf = _85_ueberschrift(rtext)
343
+
344
+ # --- Gegenprobe 85a: die berichtigte ROADMAP laeuft durch ------------------
345
+ aus = validator_ausgabe(root)
346
+ ok = (M85_ERREICHT not in aus and M85_OHNE_ZIEL not in aus
347
+ and M85_ANKER not in aus)
348
+ melde("GEGENPROBE", "85a", ok,
349
+ "Die berichtigte ROADMAP laeuft durch - jede Zielangabe eines "
350
+ "Planabschnitts liegt ueber %s, und die Pruefung ist dabei nachweislich "
351
+ "gelaufen" % stand)
352
+ if not ok:
353
+ notiz(" Ausgabe:", " | ".join(
354
+ z for z in aus.splitlines() if "Ziel-Release" in z)[:400])
355
+
356
+ # --- Gegenprobe 85b: EINE ZIELANGABE IN DER ZUKUNFT LAEUFT DURCH -----------
357
+ # 🔴 DIE EINHEIT, DIE MAN WEGLASSEN WUERDE. Ohne sie waere nicht gemessen, dass
358
+ # die Pruefung die SACHE prueft und nicht die Schreibweise - eine Pruefung, die
359
+ # jede Planueberschrift meldet, saehe an Sonde 85a genauso gruen aus.
360
+ haupt = int(stand.split(".")[0])
361
+ zukunft = re.sub(r"Ziel-Release\s*\**\s*`?~?[\d.]+`?\**",
362
+ "Ziel-Release **%d.0.0**" % (haupt + 1), kopf, count=1)
363
+ if zukunft == kopf:
364
+ raise Praeparationsfehler("Gegenprobe 85b hat nichts geaendert")
365
+ schreib(rpfad, rtext.replace(kopf, zukunft, 1))
366
+ aus = validator_ausgabe(root)
367
+ melde("GEGENPROBE", "85b", M85_ERREICHT not in aus,
368
+ "Eine Zielangabe in der ZUKUNFT laeuft durch - die Pruefung misst die "
369
+ "Zahl gegen VERSION und nicht die Schreibweise. Sie traegt damit ihre "
370
+ "benannte Grenze: ein Abschnitt, dessen Ziel noch aussteht, kann laengst "
371
+ "erledigt sein und kommt durch (K-116)")
372
+ if M85_ERREICHT in aus:
373
+ notiz(" Ausgabe:", " | ".join(
374
+ z for z in aus.splitlines() if "Ziel-Release" in z)[:400])
375
+
376
+ # --- Sonde 85a: eine Zielangabe, die VERSION erreicht hat ------------------
377
+ vorher = baumhash(root)
378
+ erreicht = re.sub(r"Ziel-Release\s*\**\s*`?~?[\d.]+`?\**",
379
+ "Ziel-Release **0.1.0**", kopf, count=1)
380
+ schreib(rpfad, rtext.replace(kopf, erreicht, 1))
381
+ if baumhash(root) == vorher:
382
+ raise Praeparationsfehler("Sonde 85a hat nichts geschrieben")
383
+ aus = validator_ausgabe(root)
384
+ melde("SONDE", "85a", M85_ERREICHT in aus,
385
+ "Ein Planabschnitt, dessen Ziel-Release erreicht ist, wird gemeldet - der "
386
+ "gemessene Fall: ALLE DREI Abschnitte standen so da, einer davon seit "
387
+ "fuenfzehn Releases (D-342)")
388
+ if M85_ERREICHT not in aus:
389
+ notiz(" Ausgabe:", " | ".join(
390
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
391
+
392
+ # --- Sonde 85b: der verlorene Anker ----------------------------------------
393
+ ohne = re.sub(r"\s*–?\s*Ziel-Release\s*\**\s*`?~?[\d.]+`?\**", "", kopf, count=1)
394
+ if ohne == kopf:
395
+ raise Praeparationsfehler("Sonde 85b hat nichts geaendert")
396
+ schreib(rpfad, rtext.replace(kopf, ohne, 1))
397
+ aus = validator_ausgabe(root)
398
+ melde("SONDE", "85b", M85_OHNE_ZIEL in aus,
399
+ "Eine Planueberschrift OHNE Zielangabe wird gemeldet - sonst waere das "
400
+ "Streichen der Zahl der billigste Weg, diese Pruefung loszuwerden, und "
401
+ "ein Posten ohne Zahl bleibt in diesem Projekt liegen (D-124, D-342)")
402
+ if M85_OHNE_ZIEL not in aus:
403
+ notiz(" Ausgabe:", " | ".join(
404
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
405
+ schreib(rpfad, rtext)
406
+ finally:
407
+ aufraeumen(os.path.dirname(root))
408
+
409
+
410
+ buendel(sonden_zielangabe,
411
+ "Pruefung 85 haelt die Zielangabe eines Planabschnitts gegen VERSION, und die "
412
+ "zweite Gegenprobe belegt, dass sie die Zahl misst und nicht die Schreibweise")
413
+
414
+
415
+
416
+ # --- Pruefung 86: die Sperrform des Schutz-Hooks (CR-2026-133) ----------------------
417
+ #
418
+ # VIER EINHEITEN, UND DIE ZWEITE GEGENPROBE IST DIE, DIE MAN WEGLASSEN WUERDE.
419
+ # 86a (Gegenprobe) - der ausgelieferte Bestand laeuft durch: Das Pack nennt eine
420
+ # Sperrform, das Skript kennt sie, das Kommando reicht sie durch.
421
+ # 86b (Gegenprobe) - 🔴 EIN PACK OHNE EIGENE SPERRFORM MUSS DURCHLAUFEN. Ohne diese
422
+ # Einheit koennte die Pruefung jedes Pack melden und saehe an 86a
423
+ # genauso gruen aus. Zwei der drei Packs fuehren kein
424
+ # hook_block_form, und fuer sie gilt die Standardform.
425
+ # 86a (Sonde) - eine Sperrform, die das Skript nicht kennt, wird gemeldet. Das
426
+ # ist der gemessene Fall in seiner gefaehrlichen Richtung: Der
427
+ # Hook laeuft, gibt etwas aus und sperrt nichts.
428
+ # 86b (Sonde) - der verlorene Durchreich: Verschwindet die Form aus dem Kommando
429
+ # der erzeugten Hook-Datei, meldet die Pruefung es. Ohne diese
430
+ # Einheit waere die dritte Stufe der Kette ungemessen - und genau
431
+ # sie ist die, die im Projekt ankommt.
432
+ M86_UNBEKANNT = "kennt das Skript des Schutz-Hooks nicht"
433
+ M86_KOMMANDO = "das Kommando des Schutz-Hooks trägt die Sperrform"
434
+
435
+ P86_PACK = "openai-codex"
436
+
437
+
438
+ def sonden_sperrform() -> None:
439
+ """Wirkungsnachweis zu Pruefung 86."""
440
+ root = installation(P86_PACK)
441
+ try:
442
+ mpfad = P(root, ".koolie/core", "clients", P86_PACK, "manifest.json")
443
+ mtext = lies(mpfad)
444
+ man = json.loads(mtext)
445
+ form = man.get("hook_block_form")
446
+ if not form:
447
+ raise Praeparationsfehler(
448
+ "Sonden zu 86: %s fuehrt kein hook_block_form - die Sonden haben "
449
+ "ihren Gegenstand verloren" % P86_PACK)
450
+ hpfad = P(root, *man["runtime_placeholders"]["<HOOKS_FILE>"].split("/"))
451
+ htext = lies(hpfad)
452
+
453
+ # --- Gegenprobe 86a: der ausgelieferte Bestand laeuft durch ----------------
454
+ aus = validator_ausgabe(root)
455
+ ok = M86_UNBEKANNT not in aus and M86_KOMMANDO not in aus
456
+ melde("GEGENPROBE", "86a", ok,
457
+ "Das ausgelieferte Pack laeuft durch: Es nennt die Sperrform '%s', das "
458
+ "Skript kennt sie und gibt sie aus, und das erzeugte Kommando reicht sie "
459
+ "durch" % form)
460
+ if not ok:
461
+ notiz(" Ausgabe:", " | ".join(
462
+ z for z in aus.splitlines() if "Sperrform" in z)[:400])
463
+
464
+ # --- Gegenprobe 86b: ein Pack OHNE eigene Sperrform laeuft durch -----------
465
+ # 🔴 DIE EINHEIT, DIE MAN WEGLASSEN WUERDE. Zwei der drei Packs fuehren kein
466
+ # hook_block_form; fuer sie gilt die Standardform, und die Pruefung darf sie
467
+ # nicht melden. Ohne diese Einheit waere nicht gemessen, dass sie die SACHE
468
+ # prueft und nicht die Anwesenheit eines Feldes.
469
+ schreib(mpfad, mtext.replace('"hook_block_form": "%s",' % form, "", 1))
470
+ aus = validator_ausgabe(root)
471
+ melde("GEGENPROBE", "86b", M86_UNBEKANNT not in aus,
472
+ "Ein Pack ohne eigene Sperrform laeuft durch - es faellt auf die "
473
+ "Standardform zurueck, und die pruefen dieselben drei Stufen")
474
+ if M86_UNBEKANNT in aus:
475
+ notiz(" Ausgabe:", " | ".join(
476
+ z for z in aus.splitlines() if "Sperrform" in z)[:400])
477
+ schreib(mpfad, mtext)
478
+
479
+ # --- Sonde 86a: eine Sperrform, die das Skript nicht kennt -----------------
480
+ vorher = baumhash(root)
481
+ schreib(mpfad, mtext.replace('"hook_block_form": "%s"' % form,
482
+ '"hook_block_form": "gibt-es-nicht"', 1))
483
+ if baumhash(root) == vorher:
484
+ raise Praeparationsfehler("Sonde 86a hat nichts geschrieben")
485
+ aus = validator_ausgabe(root)
486
+ melde("SONDE", "86a", M86_UNBEKANNT in aus,
487
+ "Eine Sperrform, die das Skript nicht kennt, wird gemeldet - sonst liefe "
488
+ "der Hook mit der Standardform, und die ist bei diesem Client gemessen "
489
+ "wirkungslos (D-347)")
490
+ if M86_UNBEKANNT not in aus:
491
+ notiz(" Ausgabe:", " | ".join(
492
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
493
+ schreib(mpfad, mtext)
494
+
495
+ # --- Sonde 86b: der verlorene Durchreich -----------------------------------
496
+ schreib(hpfad, htext.replace(" --sperrform " + form, "", 1))
497
+ aus = validator_ausgabe(root)
498
+ melde("SONDE", "86b", M86_KOMMANDO in aus,
499
+ "Faellt die Sperrform aus dem erzeugten Kommando, wird es gemeldet - das "
500
+ "Manifest allein belegt nichts, im Projekt ankommt das Kommando")
501
+ if M86_KOMMANDO not in aus:
502
+ notiz(" Ausgabe:", " | ".join(
503
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
504
+ schreib(hpfad, htext)
505
+ finally:
506
+ aufraeumen(os.path.dirname(root))
507
+
508
+
509
+ buendel(sonden_sperrform,
510
+ "Pruefung 86 misst die Sperrform an ihrer Wirkung und an ihrem Durchreich, und "
511
+ "die zweite Gegenprobe belegt, dass ein Pack ohne eigene Form durchlaeuft")
512
+
513
+
514
+ # --- Pruefung 87: die formatgebundenen Pruefungen stehen im Pack (CR-2026-133) ------
515
+ #
516
+ # 87a (Gegenprobe) - das ausgelieferte Pack nennt alle Nummern und laeuft durch.
517
+ # 87b (Gegenprobe) - 🔴 EIN PACK MIT DER FORM 'json' WIRD NICHT GEFRAGT. Ohne diese
518
+ # Einheit koennte die Pruefung von jedem Pack die Liste verlangen
519
+ # und saehe an 87a genauso gruen aus - zwei der drei Packs haben
520
+ # keine Luecke zu erklaeren.
521
+ # 87a (Sonde) - fehlt eine Nummer, wird sie gemeldet. Der eigentliche Zweck:
522
+ # Eine Pruefung, die ein Pack nicht erreicht, steht dort.
523
+ # 87b (Sonde) - steht eine Nummer zuviel, wird sie gemeldet. Eine behauptete
524
+ # Luecke, die es nicht gibt, ist so falsch wie eine verschwiegene.
525
+ M87_FEHLEND = "sind an die Ausgabeform 'json'"
526
+ M87_ZUVIEL = "werden als formatgebunden"
527
+
528
+
529
+ # Die Menge steht seit 1.19.1 im gemeinsamen Modul des Validators (K-174).
530
+ P87_GEMEINSAM = ".koolie/core/tests/scripts/pruefungen/gemeinsam.py"
531
+
532
+
533
+ def sonden_formatgebunden() -> None:
534
+ """Wirkungsnachweis zu Pruefung 87."""
535
+ root = kopie()
536
+ try:
537
+ ppfad = P(root, ".koolie/core", "clients", P86_PACK, "CLIENT_PACK.md")
538
+ ptext = lies(ppfad)
539
+ nummern = sorted(re.findall(r"^ *(\d+): ", lies(
540
+ P(root, *P87_GEMEINSAM.split("/"))).split("FORMATGEBUNDENE_PRUEFUNGEN = {")[1]
541
+ .split("}")[0], re.M), key=int)
542
+ if not nummern:
543
+ raise Praeparationsfehler(
544
+ "Sonden zu 87: FORMATGEBUNDENE_PRUEFUNGEN ist leer - die Sonden haben "
545
+ "ihren Gegenstand verloren")
546
+
547
+ # --- Gegenprobe 87a: das ausgelieferte Pack laeuft durch -------------------
548
+ aus = validator_ausgabe(root)
549
+ ok = M87_FEHLEND not in aus and M87_ZUVIEL not in aus
550
+ melde("GEGENPROBE", "87a", ok,
551
+ "Das ausgelieferte Pack nennt alle %d formatgebundenen Pruefungen in "
552
+ "Abschnitt 5 und laeuft durch" % len(nummern))
553
+ if not ok:
554
+ notiz(" Ausgabe:", " | ".join(
555
+ z for z in aus.splitlines() if "formatgebunden" in z
556
+ or "Ausgabeform" in z)[:400])
557
+
558
+ # --- Gegenprobe 87b: ein Pack mit der Form 'json' wird nicht gefragt -------
559
+ # 🔴 DIE EINHEIT, DIE MAN WEGLASSEN WUERDE.
560
+ cc = P(root, ".koolie/core", "clients", "claude-code", "CLIENT_PACK.md")
561
+ ccalt = lies(cc)
562
+ melde("GEGENPROBE", "87b",
563
+ ("clients/claude-code/CLIENT_PACK.md Abschnitt 5" not in aus
564
+ and "clients/devin-desktop/CLIENT_PACK.md Abschnitt 5" not in aus),
565
+ "Die beiden Packs mit der Ausgabeform 'json' werden nicht gefragt - sie "
566
+ "haben keine Luecke zu erklaeren, und die Pruefung verlangt von ihnen "
567
+ "keine Liste")
568
+ del ccalt, cc
569
+
570
+ # --- Sonde 87a: eine fehlende Nummer ---------------------------------------
571
+ vorher = baumhash(root)
572
+ weg = "Prüfung " + nummern[0]
573
+ if weg not in ptext:
574
+ raise Praeparationsfehler(
575
+ "Sonde 87a: '%s' steht nicht in Abschnitt 5 des Packs" % weg)
576
+ schreib(ppfad, ptext.replace(weg, "Pruefung " + nummern[0], 1))
577
+ if baumhash(root) == vorher:
578
+ raise Praeparationsfehler("Sonde 87a hat nichts geschrieben")
579
+ aus = validator_ausgabe(root)
580
+ melde("SONDE", "87a", M87_FEHLEND in aus,
581
+ "Eine formatgebundene Pruefung, die das Pack nicht nennt, wird gemeldet - "
582
+ "eine Luecke, die nirgends steht, ist ein blinder Fleck (D-346)")
583
+ if M87_FEHLEND not in aus:
584
+ notiz(" Ausgabe:", " | ".join(
585
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
586
+
587
+ # --- Sonde 87b: eine Nummer zuviel ------------------------------------------
588
+ schreib(ppfad, ptext.replace("## 6.", "Prüfung 999 erreicht dieses Pack "
589
+ "ebenfalls nicht.\n\n## 6.", 1))
590
+ aus = validator_ausgabe(root)
591
+ melde("SONDE", "87b", M87_ZUVIEL in aus,
592
+ "Eine behauptete Luecke, die es nicht gibt, wird gemeldet - sonst waere "
593
+ "die Liste eine Erzaehlung und kein Abbild des Pruefapparats")
594
+ if M87_ZUVIEL not in aus:
595
+ notiz(" Ausgabe:", " | ".join(
596
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
597
+ schreib(ppfad, ptext)
598
+ finally:
599
+ aufraeumen(os.path.dirname(root))
600
+
601
+
602
+ buendel(sonden_formatgebunden,
603
+ "Pruefung 87 verlangt die Liste der formatgebundenen Pruefungen nur von dem "
604
+ "Pack, das eine andere Ausgabeform fuehrt - und in beide Richtungen")
605
+
606
+
607
+ # --- Pruefung 88: die verdraengende Wurzel-Anweisung (CR-2026-133) ------------------
608
+ #
609
+ # 88a (Gegenprobe) - die frische Installation laeuft durch; die Datei gibt es nicht.
610
+ # 88b (Gegenprobe) - 🔴 EIN PACK OHNE VERDRAENGUNG WIRD NICHT GEFRAGT. Bei den beiden
611
+ # aelteren Packs ERGAENZT die nutzerlokale Datei, sie ersetzt
612
+ # nicht - dort waere ihre Anwesenheit kein Befund. Ohne diese
613
+ # Einheit koennte die Pruefung jede nutzerlokale Datei melden und
614
+ # saehe an 88a genauso gruen aus.
615
+ # 88a (Sonde) - liegt die Datei im Projekt, wird sie gemeldet.
616
+ # 88b (Sonde) - der verlorene Anker: Faellt das Feld root_instruction_override
617
+ # weg, prueft die Pruefung nichts mehr - und sagt es, statt leise
618
+ # zu bestehen (D-23).
619
+ M88_VERDRAENGT = "VERDRÄNGT bei diesem Client die"
620
+ M88_ANKER = "ist gesetzt, aber <ROOT_INSTRUCTION_LOCAL> fehlt"
621
+
622
+
623
+ def sonden_verdraengung() -> None:
624
+ """Wirkungsnachweis zu Pruefung 88."""
625
+ root = installation(P86_PACK)
626
+ try:
627
+ mpfad = P(root, ".koolie/core", "clients", P86_PACK, "manifest.json")
628
+ mtext = lies(mpfad)
629
+ man = json.loads(mtext)
630
+ lokal = man["runtime_placeholders"]["<ROOT_INSTRUCTION_LOCAL>"]
631
+ lpfad = P(root, *lokal.split("/"))
632
+
633
+ # --- Gegenprobe 88a: die frische Installation laeuft durch ----------------
634
+ aus = validator_ausgabe(root)
635
+ melde("GEGENPROBE", "88a", M88_VERDRAENGT not in aus,
636
+ "Die frische Installation laeuft durch - das Framework legt die "
637
+ "verdraengende Datei nicht an, und es liefert auch keine Vorlage dafuer")
638
+
639
+ # --- Gegenprobe 88b: ein Pack ohne Verdraengung wird nicht gefragt ---------
640
+ # 🔴 DIE EINHEIT, DIE MAN WEGLASSEN WUERDE.
641
+ schreib(lpfad, "# Persoenliche Fassung\n")
642
+ schreib(mpfad, mtext.replace('"root_instruction_override": true,', "", 1))
643
+ aus = validator_ausgabe(root)
644
+ melde("GEGENPROBE", "88b", M88_VERDRAENGT not in aus,
645
+ "Dieselbe Datei bei einem Pack OHNE Verdraengung ist kein Befund - dort "
646
+ "ergaenzt sie, und eine Ergaenzung ist der dokumentierte Weg")
647
+ if M88_VERDRAENGT in aus:
648
+ notiz(" Ausgabe:", " | ".join(
649
+ z for z in aus.splitlines() if "VERDR" in z)[:400])
650
+ schreib(mpfad, mtext)
651
+
652
+ # --- Sonde 88a: die Datei liegt im Projekt ---------------------------------
653
+ aus = validator_ausgabe(root)
654
+ melde("SONDE", "88a", M88_VERDRAENGT in aus,
655
+ "Liegt die verdraengende Datei im Projekt, wird sie gemeldet - sonst "
656
+ "ersetzt eine ungepruefte Datei die Ebene 1, und nichts sagt es (D-341)")
657
+ if M88_VERDRAENGT not in aus:
658
+ notiz(" Ausgabe:", " | ".join(
659
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
660
+
661
+ # --- Sonde 88b: der verlorene Anker ----------------------------------------
662
+ ohne = json.loads(mtext)
663
+ ohne["runtime_placeholders"].pop("<ROOT_INSTRUCTION_LOCAL>", None)
664
+ schreib(mpfad, json.dumps(ohne, indent=2, ensure_ascii=False) + "\n")
665
+ aus = validator_ausgabe(root)
666
+ melde("SONDE", "88b", M88_ANKER in aus,
667
+ "Verschwindet die Angabe, welche Datei verdraengt, meldet die Pruefung "
668
+ "das selbst - eine Pruefung ohne Gegenstand besteht sonst leise (D-23)")
669
+ if M88_ANKER not in aus:
670
+ notiz(" Ausgabe:", " | ".join(
671
+ z for z in aus.splitlines() if "FEHLER" in z)[:400])
672
+ schreib(mpfad, mtext)
673
+ os.remove(lpfad)
674
+ finally:
675
+ aufraeumen(os.path.dirname(root))
676
+
677
+
678
+ buendel(sonden_verdraengung,
679
+ "Pruefung 88 meldet die Datei, die die Wurzel-Anweisung verdraengt - und die "
680
+ "zweite Gegenprobe belegt, dass sie nur dort fragt, wo sie verdraengt")
681
+
682
+
683
+ # --- Pruefungen 91 bis 94: die Dokumentation (CR-2026-142) --------------------------
684
+ #
685
+ # Je Pruefung ein Buendel auf EINER Kopie. Die Gegenproben tragen das Gewicht: Jede der
686
+ # vier Pruefungen liest ueber zweihundert Dokumente, und eine, die zu breit greift,
687
+ # meldete Zitate, Register oder Vorlagen - und saehe an ihrer Sonde genauso gruen aus.
688
+ M91_STAND = "die Standüberschrift nennt Release"
689
+ M91_ANKER = "Prüfung 91 hält sie gegen"
690
+ M92 = "in der Schreibung vor 1996"
691
+ M93_ZAUN = "ein Codeblock ist bis zum Dateiende nicht geschlossen"
692
+ M93_H1 = "Hauptüberschriften ('# ')"
693
+ M93_EBENE = "eine Ebene ist übersprungen"
694
+ M93_TABELLE = "Spalten – ein ungeschützter senkrechter Strich"
695
+ M94_OHNE_ID = "Steckbrief ohne ID"
696
+ M94_KEINER = "kein Steckbrief vor dem ersten Abschnitt"
697
+
698
+ P91_ROADMAP = ".koolie/core/docs/ROADMAP.md"
699
+ P92_REGEL = ".koolie/core/governance/RELEASE_PROCESS.md"
700
+ P92_KAPITEL = ".koolie/core/build/doc/29-grenzen.md"
701
+ P92_REGISTER = ".koolie/core/CHANGELOG.md"
702
+ P92_KENNZEICHEN = ".koolie/QUELLREPOSITORIUM.md"
703
+ P93_REGEL = ".koolie/core/framework/core/05-working-model.md"
704
+ P94_REGEL = ".koolie/core/governance/RACI.md"
705
+
706
+
707
+ def _anhaengen(pfad: str, *zeilen: str) -> None:
708
+ schreib(pfad, lies(pfad).rstrip("\r\n") + "\r\n\r\n" + "\r\n".join(zeilen) + "\r\n")
709
+
710
+
711
+ def _zeilen_mit(aus: str, marke: str) -> str:
712
+ return " | ".join(z for z in aus.splitlines() if marke in z)[:400]
713
+
714
+
715
+ def sonden_roadmapstand() -> None:
716
+ """Wirkungsnachweis zu Pruefung 91."""
717
+ root = kopie()
718
+ try:
719
+ pfad = P(root, *P91_ROADMAP.split("/"))
720
+ text = lies(pfad)
721
+ kopf = next((z for z in text.split("\r\n") if z.startswith("## Stand nach Release ")), None)
722
+ if kopf is None:
723
+ raise Praeparationsfehler("Sonden zu 91: keine Standueberschrift in %s" % P91_ROADMAP)
724
+
725
+ aus = validator_ausgabe(root)
726
+ melde("GEGENPROBE", "91a", M91_STAND not in aus and M91_ANKER not in aus,
727
+ "Die Standueberschrift der ausgelieferten Roadmap nennt VERSION und laeuft "
728
+ "durch")
729
+
730
+ alt = re.sub(r"Release `?\d+\.\d+\.\d+`?", "Release 1.4.4", kopf, count=1)
731
+ if alt == kopf:
732
+ raise Praeparationsfehler("Sonde 91a hat nichts geaendert")
733
+ schreib(pfad, text.replace(kopf, alt, 1))
734
+ aus = validator_ausgabe(root)
735
+ melde("SONDE", "91a", M91_STAND in aus,
736
+ "Eine Standueberschrift, die ein frueheres Release nennt, wird gemeldet - "
737
+ "der gemessene Fall von 1.8.0: vier Releases zurueck")
738
+ if M91_STAND not in aus:
739
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
740
+
741
+ schreib(pfad, text.replace(kopf, "## Stand der Dinge", 1))
742
+ aus = validator_ausgabe(root)
743
+ melde("SONDE", "91b", M91_ANKER in aus,
744
+ "Der verlorene Anker: ohne Standueberschrift meldet die Pruefung es, statt "
745
+ "leise zu bestehen (D-23)")
746
+ if M91_ANKER not in aus:
747
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
748
+ schreib(pfad, text)
749
+ finally:
750
+ aufraeumen(os.path.dirname(root))
751
+
752
+
753
+ buendel(sonden_roadmapstand,
754
+ "Pruefung 91 haelt die Standueberschrift der Roadmap gegen VERSION und meldet "
755
+ "den verlorenen Anker")
756
+
757
+
758
+ def sonden_rechtschreibung() -> None:
759
+ """Wirkungsnachweis zu Pruefung 92."""
760
+ root = kopie()
761
+ try:
762
+ regel, kapitel, register = (P(root, *x.split("/")) for x in (P92_REGEL, P92_KAPITEL,
763
+ P92_REGISTER))
764
+ texte = {p: lies(p) for p in (regel, kapitel, register)}
765
+
766
+ aus = validator_ausgabe(root)
767
+ melde("GEGENPROBE", "92a", M92 not in aus,
768
+ "Der ausgelieferte Bestand der Klassen A, B und D laeuft durch - ohne "
769
+ "Schreibung vor 1996")
770
+ if M92 in aus:
771
+ notiz(" Ausgabe:", _zeilen_mit(aus, M92))
772
+
773
+ # --- Gegenprobe 92b: Zitat und Register ------------------------------------
774
+ # 🔴 DIE EINHEIT, DIE MAN WEGLASSEN WUERDE. Code ist Zitat - ein Befehl, eine
775
+ # Meldung, die woertlich so lautet -, und ein Register wird nicht umgeschrieben
776
+ # (D-371). Eine Pruefung, die beides meldete, verlangte eine Faelschung.
777
+ _anhaengen(regel, "Zitat einer alten Meldung: `daß der Lauf mißt`", "",
778
+ "```text", "Meßbaum muß bleiben, weil es ein Zitat ist", "```")
779
+ _anhaengen(register, "Sondenzeile im Register: daß, muß, Meßbaum")
780
+ aus = validator_ausgabe(root)
781
+ melde("GEGENPROBE", "92b", M92 not in aus,
782
+ "Alte Schreibung im Inline-Code, im Codeblock und im CHANGELOG wird NICHT "
783
+ "gemeldet - Zitat und Register bleiben, wie sie sind")
784
+ if M92 in aus:
785
+ notiz(" Ausgabe:", _zeilen_mit(aus, M92))
786
+ for p, t in texte.items():
787
+ schreib(p, t)
788
+
789
+ # --- Sonde 92a: Klasse B -----------------------------------------------------
790
+ _anhaengen(regel, "Sondenzeile: Der Schritt mißt, daß nichts fehlt.")
791
+ aus = validator_ausgabe(root)
792
+ treffer = [z for z in aus.splitlines() if M92 in z and "RELEASE_PROCESS.md" in z]
793
+ melde("SONDE", "92a", bool(treffer) and "mißt" in treffer[0] and "daß" in treffer[0],
794
+ "Alte Schreibung im Fliesstext eines Regeldokuments wird gemeldet, mit "
795
+ "Zeile und Wort")
796
+ if not treffer:
797
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
798
+ schreib(regel, texte[regel])
799
+
800
+ # --- Sonde 92b: Klasse D -----------------------------------------------------
801
+ _anhaengen(kapitel, "Sondenzeile: der Meßbaum.")
802
+ aus = validator_ausgabe(root)
803
+ ok = any(M92 in z and "29-grenzen.md" in z for z in aus.splitlines())
804
+ melde("SONDE", "92b", ok,
805
+ "Alte Schreibung in einer Kapitelquelle des Hauptdokuments wird gemeldet - "
806
+ "build/doc gehoert zu Klasse D, obwohl build/ Nachweisschicht ist")
807
+ if not ok:
808
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
809
+ schreib(kapitel, texte[kapitel])
810
+
811
+ # --- Gegenprobe 92c: die Wurzel eines Projekts gehoert dem Projekt -----------
812
+ # D-299: Ohne das Kennzeichen des Quellrepositoriums ist dieser Baum ein
813
+ # Projekt, und dessen README.md ist nicht Gegenstand dieser Pruefung.
814
+ readme = P(root, "README.md")
815
+ rtext = lies(readme)
816
+ _anhaengen(readme, "Sondenzeile im Projekt: daß.")
817
+ os.remove(P(root, *P92_KENNZEICHEN.split("/")))
818
+ aus = validator_ausgabe(root)
819
+ melde("GEGENPROBE", "92c",
820
+ not any(M92 in z and z.split()[1].startswith("README.md") for z in aus.splitlines()
821
+ if z.startswith("FEHLER")),
822
+ "In einem Projekt ohne Kennzeichen des Quellrepositoriums wird die "
823
+ "Wurzel-README nicht geprueft - sie gehoert dem Projekt (D-299)")
824
+ schreib(readme, rtext)
825
+ finally:
826
+ aufraeumen(os.path.dirname(root))
827
+
828
+
829
+ buendel(sonden_rechtschreibung,
830
+ "Pruefung 92 meldet alte Schreibung in Regel- und Kapiteltexten und laesst Zitat, "
831
+ "Register und die Wurzel eines Projekts stehen")
832
+
833
+
834
+ def sonden_dokumentform() -> None:
835
+ """Wirkungsnachweis zu Pruefung 93."""
836
+ root = kopie()
837
+ try:
838
+ pfad = P(root, *P93_REGEL.split("/"))
839
+ text = lies(pfad)
840
+ alle = (M93_ZAUN, M93_H1, M93_EBENE, M93_TABELLE)
841
+
842
+ aus = validator_ausgabe(root)
843
+ melde("GEGENPROBE", "93a", not any(m in aus for m in alle),
844
+ "Der ausgelieferte Bestand aller vier Klassen ist formal sauber")
845
+ if any(m in aus for m in alle):
846
+ notiz(" Ausgabe:", _zeilen_mit(aus, "(D-374)"))
847
+
848
+ # --- Gegenprobe 93b: was wie ein Formfehler aussieht und keiner ist ----------
849
+ _anhaengen(pfad,
850
+ "| Befehl | Wirkung |", "|---|---|",
851
+ "| `a | b` | ein senkrechter Strich im Code |",
852
+ "| a \\| b | ein geschuetzter Strich |", "",
853
+ "```text", "# keine Ueberschrift, sondern eine Zeile im Codeblock",
854
+ "#### auch keine", "```")
855
+ aus = validator_ausgabe(root)
856
+ melde("GEGENPROBE", "93b", not any(m in aus for m in alle),
857
+ "Senkrechter Strich im Code und geschuetzt sowie Rautenzeilen im Codeblock "
858
+ "werden NICHT gemeldet")
859
+ if any(m in aus for m in alle):
860
+ notiz(" Ausgabe:", _zeilen_mit(aus, "(D-374)"))
861
+ schreib(pfad, text)
862
+
863
+ def _sonde_93(zeilen: tuple, marke: str) -> tuple:
864
+ _anhaengen(pfad, *zeilen)
865
+ aus = validator_ausgabe(root)
866
+ schreib(pfad, text)
867
+ ok = any(marke in z and "05-working-model.md" in z for z in aus.splitlines())
868
+ return ok, aus
869
+
870
+ ok, aus = _sonde_93(("```text", "offen bis zum Ende"), M93_ZAUN)
871
+ melde("SONDE", "93a", ok,
872
+ "Ein Codeblock, der bis zum Dateiende offen bleibt, wird gemeldet (D-374)")
873
+ if not ok:
874
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
875
+
876
+ ok, aus = _sonde_93(("# Zweite Hauptueberschrift",), M93_H1)
877
+ melde("SONDE", "93b", ok, "Eine zweite Hauptueberschrift wird gemeldet (D-374)")
878
+ if not ok:
879
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
880
+
881
+ ok, aus = _sonde_93(("## Sondenabschnitt", "", "#### Sprung ueber eine Ebene"),
882
+ M93_EBENE)
883
+ melde("SONDE", "93c", ok,
884
+ "Eine uebersprungene Ueberschriftenebene wird gemeldet (D-374)")
885
+ if not ok:
886
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
887
+
888
+ ok, aus = _sonde_93(("| A | B |", "|---|---|", "| eins | zwei | drei |"),
889
+ M93_TABELLE)
890
+ melde("SONDE", "93d", ok,
891
+ "Eine Tabellenzeile mit mehr Spalten als ihre Kopfzeile wird gemeldet (D-374)")
892
+ if not ok:
893
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
894
+ finally:
895
+ aufraeumen(os.path.dirname(root))
896
+
897
+
898
+ buendel(sonden_dokumentform,
899
+ "Pruefung 93 meldet offenen Codeblock, zweite Hauptueberschrift, Ebenensprung und "
900
+ "verschobene Tabellenspalten - nicht aber Striche und Rauten im Code")
901
+
902
+
903
+ def sonden_steckbrief() -> None:
904
+ """Wirkungsnachweis zu Pruefung 94."""
905
+ root = kopie()
906
+ try:
907
+ pfad = P(root, *P94_REGEL.split("/"))
908
+ text = lies(pfad)
909
+ idzeile = next((z for z in text.split("\r\n") if re.match(r"\|\s*ID\s*\|", z)), None)
910
+ kopf = next((z for z in text.split("\r\n") if re.sub(r"\s+", " ", z) == "| Attribut | Wert |"),
911
+ None)
912
+ if idzeile is None or kopf is None:
913
+ raise Praeparationsfehler("Sonden zu 94: %s hat keinen Steckbrief mit ID" % P94_REGEL)
914
+
915
+ aus = validator_ausgabe(root)
916
+ ausgenommen = ("framework/runtime/rules/", "templates/", "checklists/README.md",
917
+ "examples/")
918
+ ok = M94_OHNE_ID not in aus and M94_KEINER not in aus
919
+ melde("GEGENPROBE", "94a", ok,
920
+ "Der ausgelieferte Bestand laeuft durch - Laufzeitregeln, Vorlagen, "
921
+ "Beispiele und README-Verzeichnisse ohne Steckbrief sind ausgenommen")
922
+ if not ok:
923
+ notiz(" Ausgabe:", _zeilen_mit(aus, "(D-375)"))
924
+ # Die Gegenprobe ist nur dann eine, wenn es die Ausgenommenen wirklich gibt.
925
+ fehlend = [a for a in ausgenommen
926
+ if not os.path.exists(P(root, ".koolie", "core", *a.rstrip("/").split("/")))]
927
+ if fehlend:
928
+ raise Praeparationsfehler("Gegenprobe 94a: Ausnahmen ohne Gegenstand: %s" % fehlend)
929
+
930
+ schreib(pfad, text.replace(idzeile + "\r\n", "", 1))
931
+ aus = validator_ausgabe(root)
932
+ ok = any(M94_OHNE_ID in z and "RACI.md" in z for z in aus.splitlines())
933
+ melde("SONDE", "94a", ok,
934
+ "Ein Steckbrief ohne Kennungszeile wird gemeldet (D-375)")
935
+ if not ok:
936
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
937
+
938
+ schreib(pfad, text.replace(kopf, "| Eigenschaft | Wert |", 1))
939
+ aus = validator_ausgabe(root)
940
+ ok = any(M94_KEINER in z and "RACI.md" in z for z in aus.splitlines())
941
+ melde("SONDE", "94b", ok,
942
+ "Ein Regeldokument ohne Tabelle 'Attribut | Wert' vor dem ersten Abschnitt "
943
+ "wird gemeldet (D-375)")
944
+ if not ok:
945
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
946
+ schreib(pfad, text)
947
+ finally:
948
+ aufraeumen(os.path.dirname(root))
949
+
950
+
951
+ buendel(sonden_steckbrief,
952
+ "Pruefung 94 verlangt Kennung, Version und Status im Steckbrief der Klassen A "
953
+ "und B und laesst Laufzeit, Vorlagen und Verzeichnisse aus")
954
+
955
+
956
+ # --- D-437: die Einstiegsdokumente der Wurzel (CR-2026-154) ---------------------------
957
+ #
958
+ # Bis 1.14.2 kannte dokumentklasse() ausserhalb des Kerns nur README.md. Mit 1.15.0 liegen
959
+ # daneben README.en.md, QUICKSTART.md und QUICKSTART.en.md - ohne die Erweiterung waeren
960
+ # sie fuer die Pruefungen 92 und 93 unsichtbar gewesen, und ein offener Codeblock im
961
+ # englischen Quickstart haette den Rest der Seite verschluckt, ohne dass etwas meldet.
962
+ # Die Gegenproben halten die beiden Ausnahmen: kein Steckbrief (94) und keine Pruefung
963
+ # in einem Projekt, dem die Wurzel gehoert (D-299).
964
+ P437_EN = "QUICKSTART.en.md"
965
+ P437_README_EN = "README.en.md"
966
+ P437_DE = "QUICKSTART.md"
967
+ P437_KENNZEICHEN = ".koolie/QUELLREPOSITORIUM.md"
968
+
969
+
970
+ def sonden_wurzeldokumente() -> None:
971
+ """Wirkungsnachweis zu D-437: README, Quickstart und ihre englischen Fassungen."""
972
+ root = kopie()
973
+ try:
974
+ pfade = {r: P(root, r) for r in (P437_EN, P437_README_EN, P437_DE)}
975
+ fehlend = [r for r, p in pfade.items() if not os.path.isfile(p)]
976
+ if fehlend:
977
+ raise Praeparationsfehler("Sonden zu D-437: Einstiegsdokumente fehlen: %s" % fehlend)
978
+ texte = {r: lies(p) for r, p in pfade.items()}
979
+
980
+ # --- Gegenprobe D437a: der ausgelieferte Stand, ohne Steckbrief --------------
981
+ aus = validator_ausgabe(root)
982
+ stoert = [z for z in aus.splitlines() if z.startswith("FEHLER")
983
+ and z.split()[1].rstrip(":") in pfade]
984
+ melde("GEGENPROBE", "D437a", not stoert and M94_KEINER not in aus,
985
+ "Die vier Einstiegsdokumente laufen durch - ohne Steckbrief, weil sie von "
986
+ "Pruefung 94 ausgenommen sind wie die README")
987
+ if stoert:
988
+ notiz(" Ausgabe:", " | ".join(stoert)[:400])
989
+
990
+ # --- Sonde D437b: ein offener Codeblock im englischen Quickstart ------------
991
+ _anhaengen(pfade[P437_EN], "```bash", "echo offen")
992
+ aus = validator_ausgabe(root)
993
+ ok = any(M93_ZAUN in z and P437_EN in z for z in aus.splitlines())
994
+ melde("SONDE", "D437b", ok,
995
+ "Ein offener Codeblock in QUICKSTART.en.md wird von Pruefung 93 gemeldet")
996
+ if not ok:
997
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
998
+ schreib(pfade[P437_EN], texte[P437_EN])
999
+
1000
+ # --- Sonde D437c: alte Schreibung im deutschen Quickstart -------------------
1001
+ _anhaengen(pfade[P437_DE], "Sondenzeile: Der Schritt zeigt, daß nichts fehlt.")
1002
+ aus = validator_ausgabe(root)
1003
+ ok = any(M92 in z and z.split()[1].startswith(P437_DE) for z in aus.splitlines())
1004
+ melde("SONDE", "D437c", ok,
1005
+ "Alte Schreibung in QUICKSTART.md wird von Pruefung 92 gemeldet")
1006
+ if not ok:
1007
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
1008
+ schreib(pfade[P437_DE], texte[P437_DE])
1009
+
1010
+ # --- Sonde D437d: zwei Hauptueberschriften in der englischen README ---------
1011
+ _anhaengen(pfade[P437_README_EN], "# Zweite Hauptueberschrift")
1012
+ aus = validator_ausgabe(root)
1013
+ ok = any(M93_H1 in z and P437_README_EN in z for z in aus.splitlines())
1014
+ melde("SONDE", "D437d", ok,
1015
+ "Eine zweite Hauptueberschrift in README.en.md wird von Pruefung 93 gemeldet")
1016
+ if not ok:
1017
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
1018
+
1019
+ # --- Gegenprobe D437e: in einem Projekt gehoert die Wurzel dem Projekt ------
1020
+ _anhaengen(pfade[P437_EN], "```bash", "echo offen")
1021
+ os.remove(P(root, *P437_KENNZEICHEN.split("/")))
1022
+ aus = validator_ausgabe(root)
1023
+ stoert = [z for z in aus.splitlines() if z.startswith("FEHLER")
1024
+ and z.split()[1].rstrip(":") in pfade]
1025
+ melde("GEGENPROBE", "D437e", not stoert,
1026
+ "Ohne Kennzeichen des Quellrepositoriums werden die Einstiegsdokumente der "
1027
+ "Wurzel nicht geprueft - sie gehoeren dem Projekt (D-299)")
1028
+ if stoert:
1029
+ notiz(" Ausgabe:", " | ".join(stoert)[:400])
1030
+ finally:
1031
+ aufraeumen(os.path.dirname(root))
1032
+
1033
+
1034
+ buendel(sonden_wurzeldokumente,
1035
+ "Die Einstiegsdokumente der Wurzel sind Klasse A: 92 und 93 pruefen sie im "
1036
+ "Quellrepositorium, 94 laesst sie aus, im Projekt bleiben sie unberuehrt (D-437)")
1037
+
1038
+
1039
+ # --- Pruefung 4: die Zeichengrenze der Wurzel-Anweisung (D-381, CR-2026-143) ---------
1040
+ #
1041
+ # Die Grenze von 12.000 Zeichen ist eine Vorgabe des Frameworks, keine Eigenschaft eines
1042
+ # Clients (CR-2026-027 E3). Sie gilt fuer die INSTALLIERTE Fassung, und die ist je Pack
1043
+ # verschieden lang: Dieselbe Quelle ergab am 2026-09-25 11.894 Zeichen bei claude-code,
1044
+ # 11.887 bei devin-desktop und 12.516 bei openai-codex. Dort gilt sie nicht, weil der
1045
+ # Client Regeldateien nicht von sich aus laedt (has_rule_triggers = false); die Summe
1046
+ # des stets Geladenen haelt eine Warnung bei 40.000.
1047
+ # Bis 1.9.0 hatte die Pruefung keine Sonde - eine Durchsicht der Laufzeitschicht, die
1048
+ # die Wurzel-Anweisung um hundert Zeichen verlaengert, waere erst im Projekt aufgefallen.
1049
+ M4_GRENZE = "Zeichen (> 12.000, SOLL-Grenze je Datei)"
1050
+ M4_BUDGET = "Zeichen, die in jeder Sitzung geladen werden (> 40.000"
1051
+
1052
+
1053
+ def _regel_mit_trigger(root: str, man: dict, trigger: str) -> str:
1054
+ rd = os.path.join(root, *man["pack_runtime_dir"].split("/"))
1055
+ for fn in sorted(os.listdir(rd)):
1056
+ p = os.path.join(rd, fn)
1057
+ if fn.endswith(".md") and re.search(r"^trigger:\s*%s\s*$" % trigger, lies(p), re.M):
1058
+ return p
1059
+ raise Praeparationsfehler("Sonden zu 4: keine Regel mit trigger %s" % trigger)
1060
+
1061
+
1062
+ def sonden_zeichengrenze() -> None:
1063
+ """Wirkungsnachweis zur Zeichengrenze der Pruefung 4, je Pack gegen die Installation.
1064
+
1065
+ Seit D-387 ist die Summe des stets Geladenen verbindlich (40.000, Fehler) und die
1066
+ Grenze je Datei eine Warnung (12.000)."""
1067
+ ergebnisse = {}
1068
+ for pack in ("claude-code", "devin-desktop", "openai-codex"):
1069
+ root = installation(pack)
1070
+ try:
1071
+ man = json.loads(lies(os.path.join(QUELLE, ".koolie/core", "clients", pack,
1072
+ "manifest.json")))
1073
+ wurzel = os.path.join(root, *man["root_instruction_file"].split("/"))
1074
+ if not os.path.isfile(wurzel):
1075
+ raise Praeparationsfehler("Sonden zu 4: %s fehlt in der Installation (%s)"
1076
+ % (man["root_instruction_file"], pack))
1077
+ laenge = len(lies(wurzel))
1078
+ aus = validator_ausgabe(root)
1079
+ ergebnisse[pack] = (laenge, M4_GRENZE not in aus and M4_BUDGET not in aus)
1080
+ if pack == "claude-code":
1081
+ schreib(wurzel, lies(wurzel) + "\r\n" + "x" * (12001 - laenge) + "\r\n")
1082
+ aus = validator_ausgabe(root)
1083
+ ok = any(z.startswith("WARNUNG") and M4_GRENZE in z
1084
+ and man["root_instruction_file"] in z for z in aus.splitlines())
1085
+ als_fehler = any(z.startswith("FEHLER") and M4_GRENZE in z
1086
+ for z in aus.splitlines())
1087
+ melde("SONDE", "4a", ok and not als_fehler,
1088
+ "Eine installierte Wurzel-Anweisung ueber 12.000 Zeichen wird als "
1089
+ "Warnung gemeldet, nicht als Fehler (D-387)")
1090
+ if not ok:
1091
+ notiz(" Ausgabe:", _zeilen_mit(aus, "WARNUNG"))
1092
+ if pack == "devin-desktop":
1093
+ bedingt = _regel_mit_trigger(root, man, "model_decision")
1094
+ schreib(bedingt, lies(bedingt) + "\r\n" + "x" * 30000 + "\r\n")
1095
+ aus = validator_ausgabe(root)
1096
+ melde("GEGENPROBE", "4d", M4_BUDGET not in aus,
1097
+ "Eine Regel mit trigger model_decision zaehlt nicht zur Summe des stets "
1098
+ "Geladenen")
1099
+ if M4_BUDGET in aus:
1100
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
1101
+ immer = _regel_mit_trigger(root, man, "always_on")
1102
+ schreib(immer, lies(immer) + "\r\n" + "x" * 30000 + "\r\n")
1103
+ aus = validator_ausgabe(root)
1104
+ ok = any(z.startswith("FEHLER") and M4_BUDGET in z for z in aus.splitlines())
1105
+ melde("SONDE", "4b", ok,
1106
+ "Wurzel-Anweisung und Regeln mit trigger always_on ueber 40.000 Zeichen "
1107
+ "werden als Fehler gemeldet (D-387)")
1108
+ if not ok:
1109
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
1110
+ finally:
1111
+ aufraeumen(os.path.dirname(root))
1112
+
1113
+ laenge, ok = ergebnisse["claude-code"]
1114
+ melde("GEGENPROBE", "4a", ok and laenge <= 12000,
1115
+ "Die ausgelieferte Installation des Packs claude-code meldet weder Budget noch "
1116
+ "Grenze (Wurzel-Anweisung %d Zeichen)" % laenge)
1117
+ laenge, ok = ergebnisse["devin-desktop"]
1118
+ melde("GEGENPROBE", "4b", ok and laenge <= 12000,
1119
+ "Die ausgelieferte Installation des Packs devin-desktop meldet weder Budget noch "
1120
+ "Grenze (Wurzel-Anweisung %d Zeichen)" % laenge)
1121
+ laenge, ok = ergebnisse["openai-codex"]
1122
+ melde("GEGENPROBE", "4c", ok,
1123
+ "Beim Pack openai-codex meldet die Grenze je Datei nichts, weil die Regeln ueber "
1124
+ "die Wurzel-Anweisung eingebunden werden, und das Budget haelt (%d Zeichen)" % laenge)
1125
+ notiz(" Zeichen je Pack: " + ", ".join(
1126
+ "%s %d" % (p, ergebnisse[p][0]) for p in sorted(ergebnisse)))
1127
+
1128
+
1129
+ buendel(sonden_zeichengrenze,
1130
+ "Pruefung 4 haelt das stets Geladene je Pack unter 40.000 Zeichen und warnt ueber "
1131
+ "12.000 Zeichen je Datei (D-387)")
1132
+
1133
+
1134
+ # --- Pruefung 95: der Aenderungsverlauf eines Skills nennt die Art (D-403, CR-2026-147) --
1135
+ #
1136
+ # Gegenstand ist die Zeile der aktuellen Version und jede Zeile nach dem Stichtag. Die
1137
+ # Gegenprobe ist der ausgelieferte Bestand: Er fuehrt aeltere Zeilen ohne die Nennung, und
1138
+ # die duerfen nicht gemeldet werden - sonst schriebe die Pruefung Register um (Klasse C).
1139
+ M95 = "nennt nicht, ob sie eine Anweisung berührt"
1140
+ P95_SKILL = ".koolie/core/framework/skills/fw-docs-update"
1141
+
1142
+
1143
+ def sonden_aenderungsart() -> None:
1144
+ """Wirkungsnachweis zu Pruefung 95."""
1145
+ root = kopie()
1146
+ try:
1147
+ cl = P(root, *(P95_SKILL + "/CHANGELOG.md").split("/"))
1148
+ sk = P(root, *(P95_SKILL + "/SKILL.md").split("/"))
1149
+ text = lies(cl)
1150
+ m = re.search(r"^\|\s*Version\s*\|\s*`?([^`|]+?)`?\s*\|", lies(sk), re.M)
1151
+ if m is None:
1152
+ raise Praeparationsfehler("Sonden zu 95: %s/SKILL.md ohne Version" % P95_SKILL)
1153
+ zeilen = text.split("\r\n")
1154
+ aktuell = [z for z in zeilen if re.match(r"\|\s*%s\s*\|" % re.escape(m.group(1)), z)]
1155
+ alt = [z for z in zeilen if re.match(r"\|\s*\d+\.\d+\.\d+\s*\|\s*2026-09-1\d\s*\|", z)
1156
+ and not re.search(r"Anweisung\s+ber(?:ü|ue)hrt", z, re.I)]
1157
+ if len(aktuell) != 1 or not alt:
1158
+ raise Praeparationsfehler("Sonden zu 95: aktuelle Zeile %d-mal, alte Zeile ohne "
1159
+ "Nennung %d-mal" % (len(aktuell), len(alt)))
1160
+
1161
+ aus = validator_ausgabe(root)
1162
+ ok = M95 not in aus
1163
+ melde("GEGENPROBE", "95a", ok,
1164
+ "Der ausgelieferte Bestand laeuft durch - aeltere Zeilen ohne Nennung "
1165
+ "werden nicht gemeldet")
1166
+ if not ok:
1167
+ notiz(" Ausgabe:", _zeilen_mit(aus, "(D-403)"))
1168
+
1169
+ ohne = re.sub(r"\*{0,2}Keine Anweisung ber(?:ü|ue)hrt\*{0,2}", "Berichtigt",
1170
+ aktuell[0], flags=re.I)
1171
+ if ohne == aktuell[0]:
1172
+ raise Praeparationsfehler("Sonde 95a: die aktuelle Zeile traegt keine Nennung")
1173
+ schreib(cl, text.replace(aktuell[0], ohne, 1))
1174
+ aus = validator_ausgabe(root)
1175
+ ok = any(M95 in z and "fw-docs-update" in z for z in aus.splitlines())
1176
+ melde("SONDE", "95a", ok,
1177
+ "Die Zeile der aktuellen Version ohne Nennung der Art wird gemeldet (D-403)")
1178
+ if not ok:
1179
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
1180
+
1181
+ # Gegenprobe 95b: ein projekteigener Skill in der Laufzeitablage mit einer Zeile
1182
+ # ohne Nennung - beim ersten Heben meldete die Pruefung genau das im
1183
+ # Uebungsrepositorium (die Erstfassung eines prj-Skills).
1184
+ ablage = P(root, ".devin", "skills")
1185
+ if not os.path.isdir(ablage):
1186
+ raise Praeparationsfehler("Gegenprobe 95b: keine Laufzeitablage .devin/skills "
1187
+ "in der Kopie - ohne sie hat die Gegenprobe keinen Gegenstand")
1188
+ prj = os.path.join(ablage, "prj-sonde95")
1189
+ shutil.copytree(P(root, *P95_SKILL.split("/")), prj)
1190
+ schreib(os.path.join(prj, "CHANGELOG.md"),
1191
+ "# prj-sonde95\r\n\r\n| Version | Datum | Änderung | Autor (Rolle) |\r\n"
1192
+ "|---|---|---|---|\r\n| 0.1.0 | 2026-09-24 | Erstfassung | Projekt |\r\n")
1193
+ aus = validator_ausgabe(root)
1194
+ ok = not any(M95 in z and "prj-sonde95" in z for z in aus.splitlines())
1195
+ melde("GEGENPROBE", "95b", ok,
1196
+ "Ein projekteigener Skill wird nicht gemeldet - D-303 regelt die Testblaetter "
1197
+ "des Kerns")
1198
+ if not ok:
1199
+ notiz(" Ausgabe:", _zeilen_mit(aus, "prj-sonde95"))
1200
+ shutil.rmtree(prj)
1201
+
1202
+ spaet = re.sub(r"2026-09-1\d", "2026-09-24", alt[0], count=1)
1203
+ schreib(cl, text.replace(alt[0], spaet, 1))
1204
+ aus = validator_ausgabe(root)
1205
+ ok = any(M95 in z and "fw-docs-update" in z for z in aus.splitlines())
1206
+ melde("SONDE", "95b", ok,
1207
+ "Eine Zeile nach dem Stichtag ohne Nennung wird gemeldet, auch wenn sie "
1208
+ "nicht die aktuelle Version ist (D-403)")
1209
+ if not ok:
1210
+ notiz(" Ausgabe:", _zeilen_mit(aus, "FEHLER"))
1211
+ schreib(cl, text)
1212
+ finally:
1213
+ aufraeumen(os.path.dirname(root))
1214
+
1215
+
1216
+ buendel(sonden_aenderungsart,
1217
+ "Pruefung 95 verlangt im Aenderungsverlauf eines Skills die Nennung, ob eine "
1218
+ "Anweisung beruehrt ist - fuer die aktuelle Version und nach dem Stichtag")