@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,1184 @@
1
+ """Sonden zu den Pruefungen 102 und 103 sowie 26 bis 36, zum Suchkanal, zu den
2
+ Zusagenfeldern bei der Installation, zur Kandidatenpruefung; Selbstproben des
3
+ Praeparations- und des Kennungswaechters.
4
+
5
+ Teil des Sondenskripts probe-pruefungen.py, seit 1.19.1 in Module geteilt (K-174). Die
6
+ Einheiten melden sich beim Laden dieses Moduls an; der Einstieg laedt die Module in der
7
+ Reihenfolge ihrer Nummer, und das ist die Reihenfolge der Ausgabe (D-49). Ein Modul
8
+ liest nur aus dem Apparat und aus frueheren Teilen."""
9
+ from __future__ import annotations
10
+
11
+ import io
12
+ import json
13
+ import os
14
+ import re
15
+ import shutil
16
+ import sys
17
+ import tempfile
18
+
19
+ from .apparat import (
20
+ _p, aufraeumen, buendel, ersetze, ersetzt, frei, gegenprobe, installation, kopie,
21
+ lies, melde, notiz, P, Praeparationsfehler, QUELLE, schreib, sonde, unterprozess,
22
+ VALIDATOR, validator_ausgabe, zeile_nach)
23
+ from .teil01_grundbestand_und_installation import _so_status, SO_PLATZHALTER
24
+
25
+
26
+ # --- Pruefung 102: die Form des Klaerungsregisters (CR-2026-158, D-465) -------------------
27
+ M102_LAGE = "statt in der Klärungstabelle (Abschnitt 1)"
28
+ M102_STATUS = "kein Wert der Legende"
29
+ M102_KETTE = "das selbst zusammengelegt ist"
30
+ M102_ANKER = "Prüfung 102 leitet ihr Vokabular daraus ab und hat ihren Anker verloren"
31
+ P102_LOG = ".koolie/core/governance/DECISION_LOG.md".replace("/", os.sep)
32
+ P102_ANKER_K = "| K-56 | "
33
+ P102_ANKER_D = "| D-464 | "
34
+ # Zusammengesetzt wie K50_SYNTH: Pruefung 50 meldet jede im Kern genannte Kennung ohne Zeile.
35
+ K102_SYNTH = "K-" + "95"
36
+
37
+
38
+ def _102_zeile(status: str) -> str:
39
+ return "| %s | Sondenfrage? | niedrig | Sondenbegruendung | Sondenweg | %s |" % (K102_SYNTH, status)
40
+
41
+
42
+ def _102_in_entscheidungstabelle(root: str) -> None:
43
+ """Ein Klaerungspunkt unter den Decision Records - der Zustand vor 1.18.1 (114 Zeilen)."""
44
+ zeile_nach(P(root, P102_LOG), P102_ANKER_D, _102_zeile("offen"))
45
+
46
+
47
+ def _102_status_ausserhalb(root: str) -> None:
48
+ """Eine Statuszelle, die mit einem Wort ausserhalb der Legende beginnt."""
49
+ zeile_nach(P(root, P102_LOG), P102_ANKER_K, _102_zeile("**beantwortet mit `1.0.0`**"))
50
+
51
+
52
+ def _102_kette(root: str) -> None:
53
+ """Zusammengelegt mit einem Punkt, der selbst zusammengelegt ist (K-43 -> K-185)."""
54
+ zeile_nach(P(root, P102_LOG), P102_ANKER_K, _102_zeile("zusammengelegt mit K-43: Sonde"))
55
+
56
+
57
+ def _102_anker_verlieren(root: str) -> None:
58
+ ersetze(P(root, P102_LOG), ("*Klärungspunkte:*", "*Offene Punkte:*"))
59
+
60
+
61
+ def _102_eingeplant(root: str) -> None:
62
+ """Erlaubt: ein neuer Punkt in Abschnitt 1, eingeplant mit Ziel in der Klammer."""
63
+ zeile_nach(P(root, P102_LOG), P102_ANKER_K,
64
+ _102_zeile("🔴 **eingeplant (1.20.0 Schutzschicht)**: Sonde"))
65
+
66
+
67
+ sonde("102a", "Pruefung 102: ein Klaerungspunkt steht unter den Decision Records statt "
68
+ "in der Klaerungstabelle", _102_in_entscheidungstabelle, M102_LAGE)
69
+ sonde("102b", "Pruefung 102: eine Statuszelle beginnt mit einem Wort ausserhalb der Legende",
70
+ _102_status_ausserhalb, M102_STATUS)
71
+ sonde("102c", "Pruefung 102: ein Punkt ist mit einem Punkt zusammengelegt, der selbst "
72
+ "zusammengelegt ist", _102_kette, M102_KETTE)
73
+ sonde("102d", "Pruefung 102: ohne den Legendenanker meldet sie den Verlust statt still "
74
+ "nichts zu pruefen", _102_anker_verlieren, M102_ANKER)
75
+ gegenprobe("102a", "Pruefung 102: das ausgelieferte Register traegt Lage und Statusanfang "
76
+ "jedes Klaerungspunkts richtig", None, M102_STATUS)
77
+ gegenprobe("102b", "Pruefung 102: ein neuer Punkt mit Markierung und Ziel in der Klammer "
78
+ "bleibt unbeanstandet", _102_eingeplant, M102_STATUS)
79
+
80
+
81
+ # --- Pruefung 103: der Stand einer Ergebniszelle (CR-2026-160, D-472, K-61) --------------
82
+ # Die Gegenprobe rechnet den Stand HIER nach, nicht mit der Funktion des Validators: Stimmen
83
+ # beide Rechnungen nicht ueberein, faellt sie - zwei Stellen, die einander pruefen, statt
84
+ # einer, die sich selbst bestaetigt.
85
+ M103_VERALTET = "Belegstand veraltet"
86
+ M103_LEER = "ein Stand ohne Gegenstand belegt nichts"
87
+ P103_BLATT = ".koolie/core/framework/skills/fw-refactor/TESTS.md".replace("/", os.sep)
88
+ P103_ANKER = "`validate-output.py --skill fw-refactor`: **bestanden**."
89
+ P103_GEGENSTAND = "framework/skills/fw-refactor/SKILL.md"
90
+
91
+
92
+ def _103_stand(root: str, pfade: list) -> str:
93
+ import hashlib
94
+ h = hashlib.sha256()
95
+ for pfad in pfade:
96
+ inhalt = io.open(os.path.join(root, ".koolie", "core", *pfad.split("/")), "rb").read()
97
+ h.update(pfad.encode("utf-8") + b"\n" + inhalt.replace(b"\r\n", b"\n") + b"\n")
98
+ return h.hexdigest()[:12]
99
+
100
+
101
+ def _103_marke(root: str, wert: str, pfad: str) -> None:
102
+ ersetze(P(root, P103_BLATT), (P103_ANKER, P103_ANKER + " [Stand: %s; %s]" % (wert, pfad)))
103
+
104
+
105
+ def _103_veraltet(root: str) -> None:
106
+ # ein Stand, der zu keinem heutigen Inhalt passt
107
+ _103_marke(root, "0123456789ab", P103_GEGENSTAND)
108
+
109
+
110
+ def _103_ohne_gegenstand(root: str) -> None:
111
+ _103_marke(root, "0123456789ab", "framework/skills/fw-refactor/GIBTESNICHT.md")
112
+
113
+
114
+ def _103_passend(root: str) -> None:
115
+ _103_marke(root, _103_stand(root, [P103_GEGENSTAND]), P103_GEGENSTAND)
116
+
117
+
118
+ sonde("103a", "Pruefung 103: eine Ergebniszelle traegt einen Stand, der nicht zum heutigen "
119
+ "Gegenstand passt", _103_veraltet, M103_VERALTET)
120
+ sonde("103b", "Pruefung 103: eine Standmarke nennt einen Gegenstand, den es nicht gibt",
121
+ _103_ohne_gegenstand, M103_LEER)
122
+ gegenprobe("103a", "Pruefung 103: ein Stand, der zum Gegenstand passt, bleibt unbeanstandet",
123
+ _103_passend, M103_VERALTET)
124
+
125
+ # --- Pruefung 26 und der Suchkanal (CR-2026-047, D-47) ----------------------------
126
+ #
127
+ # Zwei Gegenstaende in einem Block, weil sie dieselbe Entscheidung tragen: Der Suchkanal
128
+ # wird vom Schutz-Hook durchgesetzt (nicht von der Berechtigungsdatei), und ein Client
129
+ # ohne Suchwerkzeug darf das erklaeren, ohne dass daraus ein Schlupfloch wird.
130
+
131
+ def _manifest_pfad(root: str, pack: str) -> str:
132
+ return os.path.join(root, ".koolie/core", "clients", pack, "manifest.json")
133
+
134
+
135
+ def _manifest_aendern(root: str, pack: str, aenderung) -> None:
136
+ pfad = _manifest_pfad(root, pack)
137
+ man = json.loads(lies(pfad))
138
+ aenderung(man)
139
+ schreib(pfad, json.dumps(man, ensure_ascii=False, indent=2) + "\r\n")
140
+
141
+
142
+ def _abwesenheit_ohne_begruendung(root: str) -> None:
143
+ def f(man):
144
+ man["hook_tools_absent"] = ["search"]
145
+ man.pop("_hook_tools_absent_note", None)
146
+ _manifest_aendern(root, "devin-desktop", f)
147
+
148
+
149
+ def _abwesenheit_widerspricht(root: str) -> None:
150
+ # 'write' fuer abwesend erklaeren, obwohl die Berechtigungsschicht ein
151
+ # Schreibwerkzeug kennt - das ist der Missbrauchsfall, gegen den die Pruefung steht.
152
+ def f(man):
153
+ man["hook_tools_absent"] = ["write"]
154
+ man["_hook_tools_absent_note"] = "Sonde: absichtlich widerspruechlich."
155
+ _manifest_aendern(root, "devin-desktop", f)
156
+
157
+
158
+ sonde("26", "Erklaerte Abwesenheit ohne Begruendung wird gemeldet",
159
+ _abwesenheit_ohne_begruendung, "_hook_tools_absent_note fehlt oder ist leer")
160
+ sonde("26", "Erklaerte Abwesenheit im Widerspruch zu permission_tools wird gemeldet",
161
+ _abwesenheit_widerspricht, "permission_tools nennt dafuer aber")
162
+ gegenprobe("26", "Die ausgelieferte Abwesenheitserklaerung bleibt unbeanstandet",
163
+ None, "hook_tools_absent")
164
+
165
+
166
+ def sonden_suchkanal() -> None:
167
+ """Der Schutz-Hook erreicht die Suchwerkzeuge - und nur mit dem richtigen Pfad.
168
+
169
+ Bis 0.29.0 war der Suchkanal auf beiden Schichten unbewacht: kein Hook-Eintrag und
170
+ keine Berechtigungsregel (B04, Lauf B04-5). Eine Regel traegt hier auch nicht - die
171
+ Suchwerkzeuge dieses Clients werten keine Pfadregeln aus (AP2-CC-02). Der Hook ist
172
+ die einzige Schranke, und deshalb wird sie gemessen.
173
+
174
+ Die Gegenprobe ist der wichtigere Teil: Ein Hook, der jede Suche blockiert, bestuende
175
+ die Sonde und machte das Suchwerkzeug unbenutzbar.
176
+ """
177
+ hook = os.path.join(QUELLE, ".koolie/core", "tests", "scripts",
178
+ "hook-check-secrets.py")
179
+
180
+ def hooklauf(werkzeug: str, eingabe: dict) -> int:
181
+ p = unterprozess([sys.executable, hook, "--fail-closed"],
182
+ input=json.dumps({"tool_name": werkzeug,
183
+ "tool_input": eingabe},
184
+ ensure_ascii=False))
185
+ return p.returncode
186
+
187
+ melde("SONDE", "B04", hooklauf("Grep", {"pattern": "x", "path": "sonde/.env"}) == 2,
188
+ "Suchwerkzeug auf einen Secret-Pfad wird blockiert")
189
+ melde("SONDE", "B04", hooklauf("Glob", {"pattern": "**/*.pem"}) == 2,
190
+ "Suchmuster auf Schluesseldateien wird blockiert")
191
+ melde("GEGENPROBE", "B04",
192
+ hooklauf("Grep", {"pattern": "x", "path": "src/"}) == 0,
193
+ "Suche in einem gewoehnlichen Pfad bleibt moeglich")
194
+ melde("GEGENPROBE", "B04",
195
+ hooklauf("Grep", {"pattern": "x", "path": ".koolie/core/framework/core/"}) == 0,
196
+ "Suche im Kernverzeichnis bleibt moeglich - lesen darf der Agent ihn")
197
+
198
+
199
+ buendel(sonden_suchkanal,
200
+ "Der Schutz-Hook faengt Grep und Glob auf geschuetzte Pfade ab und laesst eine "
201
+ "gewoehnliche Suche durch - die einzige Schranke des Suchkanals")
202
+
203
+
204
+ # --- Pruefung 27 und der Installationsabbruch (CR-2026-050, D-50) -----------------
205
+ #
206
+ # Zwei Schichten, zwei Sonden: Der Validator findet das verworfene Zusagenfeld im
207
+ # Repositorium, install.py bricht bei der Installation ab. Die zweite ist die
208
+ # wirksamere - sie steht zwischen dem Befund und einer ausgelieferten Installation.
209
+
210
+ def _ersatz_entfernen(root: str) -> None:
211
+ pfad = _manifest_pfad(root, "claude-code")
212
+ man = json.loads(lies(pfad))
213
+ man["skill_frontmatter"].pop("skill_permissions_ersatz", None)
214
+ schreib(pfad, json.dumps(man, ensure_ascii=False, indent=2) + "\r\n")
215
+
216
+
217
+ def _ersatz_leeren(root: str) -> None:
218
+ # Ein leerer Begleitsatz ist kein Begleitsatz - dieselbe Strenge wie bei Pruefung 26.
219
+ pfad = _manifest_pfad(root, "claude-code")
220
+ man = json.loads(lies(pfad))
221
+ man["skill_frontmatter"]["skill_permissions_ersatz"] = " "
222
+ schreib(pfad, json.dumps(man, ensure_ascii=False, indent=2) + "\r\n")
223
+
224
+
225
+ sonde("27", "Verworfenes Zusagenfeld ohne benannten Ersatz wird gemeldet",
226
+ _ersatz_entfernen, "traegt eine Zusage und steht in skill_frontmatter.drop_fields")
227
+ sonde("27", "Leerer Ersatzsatz gilt nicht als benannter Ersatz",
228
+ _ersatz_leeren, "traegt eine Zusage und steht in skill_frontmatter.drop_fields")
229
+ gegenprobe("27", "Der ausgelieferte Ersatzsatz bleibt unbeanstandet",
230
+ None, "traegt eine Zusage und steht in skill_frontmatter.drop_fields")
231
+
232
+
233
+ def sonden_zusagenfeld_installation() -> None:
234
+ """install.py bricht ab, statt eine Zusage folgenlos zu verwerfen.
235
+
236
+ Der Validator meldet denselben Fehler im Repositorium; diese Sonde misst die Stelle,
237
+ an der es zaehlt - den Schreibvorgang in ein Projekt. Die Gegenprobe belegt, dass die
238
+ Installation mit benanntem Ersatz weiterhin durchlaeuft; ohne sie stuende nur fest,
239
+ dass irgendetwas abbricht.
240
+ """
241
+ ziel = tempfile.mkdtemp(prefix="lw-b01-")
242
+ try:
243
+ quelle = os.path.join(ziel, "quelle")
244
+ shutil.copytree(QUELLE, quelle, ignore=shutil.ignore_patterns(".git"))
245
+ werkzeug = os.path.join(quelle, ".koolie/core", "install.py")
246
+
247
+ frei = os.path.join(ziel, "mit-ersatz")
248
+ os.makedirs(frei)
249
+ p = unterprozess([sys.executable, werkzeug, "--client", "claude-code",
250
+ "--root", frei])
251
+ melde("GEGENPROBE", "B01", p.returncode == 0,
252
+ "Installation mit benanntem Ersatz laeuft durch")
253
+ if p.returncode != 0:
254
+ notiz(" Ausgabe:", " | ".join(
255
+ ((p.stdout or "") + (p.stderr or "")).splitlines()[:4]))
256
+
257
+ _ersatz_entfernen(quelle)
258
+ ohne = os.path.join(ziel, "ohne-ersatz")
259
+ os.makedirs(ohne)
260
+ q = unterprozess([sys.executable, werkzeug, "--client", "claude-code",
261
+ "--root", ohne])
262
+ aus = (q.stdout or "") + (q.stderr or "")
263
+ gemeldet = "traegt eine Zusage und steht in drop_fields" in aus
264
+ melde("SONDE", "B01", q.returncode != 0 and gemeldet,
265
+ "Installation bricht ab, wenn das Zusagenfeld ersatzlos entfiele")
266
+ if not (q.returncode != 0 and gemeldet):
267
+ notiz(" Exit:", q.returncode, "| Ausgabe:",
268
+ " | ".join(aus.splitlines()[:4]))
269
+ finally:
270
+ aufraeumen(ziel)
271
+
272
+
273
+ buendel(sonden_zusagenfeld_installation,
274
+ "install.py bricht beim Schreiben in ein Projekt ab, wenn eine Zusage ohne "
275
+ "benannten Ersatz verworfen wurde, und laeuft mit Ersatz durch")
276
+
277
+
278
+ # --- 28: Lesesperre gegen Schreibsperre (B07, D-55) ------------------------------
279
+ # Drei Sonden, weil die Pruefung drei Wege hat, falsch zu sein: Sie kann den Fehler in
280
+ # der Quelle uebersehen, ihn in der Installation uebersehen - und sie kann ihre eigene
281
+ # Deklaration nicht mehr finden und dadurch leise bestehen. Die Gegenprobe ist hier die
282
+ # wichtigere Haelfte: Beide Traeger erklaeren im Fliesstext, dass die Strukturpfade
283
+ # gerade NICHT in <EXCLUDED_PATHS> gehoeren, und nennen dabei beides in einer Zeile. Eine
284
+ # Pruefung, die jede Nennung meldet, wuerde den richtigen Text beanstanden.
285
+ VORLAGE_28 = ".koolie/core/templates/project-overlay/OVERLAY.md"
286
+ REGEL_28 = ".koolie/core/framework/runtime/rules/20-project-overlay.md"
287
+
288
+
289
+ def _strukturpfad_in_ausschluss(root: str) -> None:
290
+ pfad = _p(root, VORLAGE_28)
291
+ text = lies(pfad)
292
+ alt = "| Ausgeschlossene Pfade (weder lesen noch \u00e4ndern) | `<EXCLUDED_PATHS>` |"
293
+ schreib(pfad, text.replace(
294
+ alt, alt + " `<RUNTIME_DIR>/`,", 1))
295
+
296
+
297
+ def _strukturpfad_in_laufzeitregel(root: str) -> None:
298
+ pfad = _p(root, REGEL_28)
299
+ text = lies(pfad)
300
+ alt = "- Ausgeschlossene Pfade, weder lesen noch \u00e4ndern (`<EXCLUDED_PATHS>`):"
301
+ schreib(pfad, text.replace(alt, alt + " `<ROOT_INSTRUCTION_FILE>`,", 1))
302
+
303
+
304
+ def _beschriftung_verlieren(root: str) -> None:
305
+ pfad = _p(root, REGEL_28)
306
+ text = lies(pfad)
307
+ schreib(pfad, text.replace(
308
+ "- Ausgeschlossene Pfade, weder lesen noch \u00e4ndern (`<EXCLUDED_PATHS>`):",
309
+ "- Gesperrte Verzeichnisse (`<EXCLUDED_PATHS>`):", 1))
310
+
311
+
312
+ def _hinweis_ohne_deklaration(root: str) -> None:
313
+ """Gegenprobe: dieselben Angaben im Fliesstext, aber keine Deklaration."""
314
+ pfad = _p(root, REGEL_28)
315
+ text = lies(pfad)
316
+ schreib(pfad, text.replace(
317
+ "## Freigegebene Befehle",
318
+ "Hinweis: `<RUNTIME_DIR>/`, `<ROOT_INSTRUCTION_FILE>` und `.koolie/project-overlay/` "
319
+ "geh\u00f6ren nicht in `<EXCLUDED_PATHS>` - ihr Schreibschutz ist kein "
320
+ "Leseverbot.\r\n\r\n## Freigegebene Befehle", 1))
321
+
322
+
323
+ sonde("28a", "Strukturpfad in der <EXCLUDED_PATHS>-Zeile der Overlay-Vorlage",
324
+ _strukturpfad_in_ausschluss, "Die Deklaration von <EXCLUDED_PATHS> nennt")
325
+
326
+ sonde("28b", "Strukturpfad in der <EXCLUDED_PATHS>-Zeile der Laufzeitregel",
327
+ _strukturpfad_in_laufzeitregel, "Die Deklaration von <EXCLUDED_PATHS> nennt")
328
+
329
+ sonde("28c", "Verlorene Beschriftung - die Pruefung darf nicht leise bestehen",
330
+ _beschriftung_verlieren, "keine Zeile ist als Deklaration erkennbar")
331
+
332
+ gegenprobe("28", "Dieselben Pfade im Fliesstext, ausdruecklich ausgeschlossen",
333
+ _hinweis_ohne_deklaration, "Die Deklaration von <EXCLUDED_PATHS> nennt")
334
+
335
+
336
+ # --- 29: K3-Kategorien in Kurz- und Langform (B09, D-52) ------------------------
337
+ # Zwei Fehlerbilder, beide vorgekommen: eine fehlende Kategorie in der Kurzform - sie
338
+ # fuehrte bis 0.31.0 nur sechs von acht - und eine Bedingung an einer Kategorie, die
339
+ # unbedingt gilt. Dazu die dritte Sonde auf den verlorenen Anker, aus demselben Grund
340
+ # wie bei 28c.
341
+ KURZFORM_29 = ".koolie/core/framework/runtime/root-instruction.md"
342
+ LANGFORM_29 = ".koolie/core/framework/core/02-privacy.md"
343
+
344
+
345
+ def _kategorie_entfernen(root: str) -> None:
346
+ pfad = _p(root, KURZFORM_29)
347
+ text = lies(pfad)
348
+ schreib(pfad, text.replace(
349
+ "Sicherheitskonfigurationen mit Schutzwirkung, interne Adressen",
350
+ "interne Adressen", 1))
351
+
352
+
353
+ def _bedingung_einfuegen(root: str) -> None:
354
+ pfad = _p(root, LANGFORM_29)
355
+ text = lies(pfad)
356
+ schreib(pfad, text.replace(
357
+ "- interne Adressen, Hostnamen, Netzpl\u00e4ne, Mandanten- und Umgebungskennungen",
358
+ "- interne Adressen, Hostnamen, Netzpl\u00e4ne, Mandanten- und Umgebungskennungen, "
359
+ "sofern nicht im Overlay ausdr\u00fccklich als K1 eingestuft", 1))
360
+
361
+
362
+ def _29_anker_verlieren(root: str) -> None:
363
+ pfad = _p(root, KURZFORM_29)
364
+ text = lies(pfad)
365
+ schreib(pfad, text.replace("- Immer K3, ausnahmslos", "- Stets K3, ausnahmslos", 1))
366
+
367
+
368
+ def _kurzform_umformulieren(root: str) -> None:
369
+ """Gegenprobe: kuerzer formuliert, aber keine Kategorie weniger."""
370
+ pfad = _p(root, KURZFORM_29)
371
+ text = lies(pfad)
372
+ schreib(pfad, text.replace(
373
+ "Sicherheitskonfigurationen mit Schutzwirkung, interne Adressen",
374
+ "Sicherheitskonfigurationen, interne Adressen", 1))
375
+
376
+
377
+ sonde("29a", "Fehlende K3-Kategorie in der Kurzform",
378
+ _kategorie_entfernen, "nennt die Kategorie 'Sicherheitskonfigurationen' nicht")
379
+
380
+ sonde("29b", "Bedingung an einer unbedingten K3-Kategorie",
381
+ _bedingung_einfuegen, "traegt eine Bedingung")
382
+
383
+ sonde("29c", "Der verlorene Anker der K3-Liste - die Pruefung meldet ihr Fehlen selbst, statt "
384
+ "leise zu bestehen",
385
+ _29_anker_verlieren, "ist nicht mehr auffindbar")
386
+
387
+ gegenprobe("29", "Kuerzere Formulierung derselben acht Kategorien",
388
+ _kurzform_umformulieren, "nennt die Kategorie")
389
+
390
+
391
+ # --- 30: Vollstaendigkeit der Grenzfalltabelle (B07, B09) -----------------------
392
+ # Die Tabelle ist das Abnahmekriterium des Reviews. Drei Wege, sie unbemerkt zu
393
+ # entwerten: eine Zeile verschwindet, eine Spalte bleibt leer, eine Entscheidung ist
394
+ # durch keinen Grenzfall gedeckt.
395
+ EDGE_30 = ".koolie/core/tests/EDGE_CASES.md"
396
+ KATALOG_30 = ".koolie/core/tests/TEST_CATALOG.md"
397
+
398
+
399
+ def _grenzfall_loeschen(root: str) -> None:
400
+ pfad = _p(root, EDGE_30)
401
+ zeilen = lies(pfad).split("\r\n")
402
+ behalten = [z for z in zeilen if not z.startswith("| G-07 |")]
403
+ schreib(pfad, "\r\n".join(behalten))
404
+
405
+
406
+ def _spalte_leeren(root: str) -> None:
407
+ pfad = _p(root, EDGE_30)
408
+ text = lies(pfad)
409
+ start = text.index("| G-05 |")
410
+ ende = text.index("\r\n", start)
411
+ zeile = text[start:ende]
412
+ zellen = zeile.split(" | ")
413
+ zellen[4] = ""
414
+ schreib(pfad, text[:start] + " | ".join(zellen) + text[ende:])
415
+
416
+
417
+ def _entscheidung_entkoppeln(root: str) -> None:
418
+ pfad = _p(root, EDGE_30)
419
+ schreib(pfad, lies(pfad).replace("(D-53)", "(siehe Antrag)"))
420
+
421
+
422
+ def _grenzfall_ergaenzen(root: str) -> None:
423
+ """Gegenprobe: eine weitere Zeile samt mitgezaehlter Anzahl.
424
+
425
+ ZWEIMAL an einem neuen Grenzfall gebrochen, zuletzt mit 0.36.0 an G-18: Die
426
+ Anzahl war woertlich verankert (17 -> 18), und die synthetische Kennung war
427
+ G-18 - dieselbe, die dieses Release wirklich vergeben hat. Beide Fallen sind
428
+ in der Uebergabe benannt gewesen, und beide sind trotzdem zugeschnappt.
429
+
430
+ Die Kennung ist seither G-99 und kollidiert mit keinem echten Fall. Die Anzahl
431
+ bleibt woertlich: Ob eine Gegenprobe ihre Summen ABLEITEN soll, ist eine
432
+ Ermessensfrage und nicht entschieden - eine abgeleitete Summe verdoppelt
433
+ womoeglich nur die Rechenweise der Pruefung, statt sie zu belegen. Die Frage
434
+ ist damit zum VIERTEN Mal aufgetreten und gehoert in einen eigenen Antrag.
435
+
436
+ Seit 0.42.0 zieht diese Gegenprobe ZWEI Register nach: die Anzahl im Steckbrief
437
+ von EDGE_CASES.md und die Arbeitsanweisung in FW-KO-05. Ein Repositorium mit 21
438
+ Grenzfaellen, dessen Testblatt weiter von zwanzig spricht, ist kein erlaubter
439
+ Fall, sondern genau der Befund, gegen den Pruefung 40 gebaut ist (D-86). Der
440
+ Sondenlauf zu 0.42.0 hat ihn gemeldet, bevor jemand ihn behaupten musste.
441
+ """
442
+ pfad = _p(root, EDGE_30)
443
+ frei(pfad, "G-99")
444
+ ersetze(pfad, ("| Anzahl der Grenzf\u00e4lle | 20 |",
445
+ "| Anzahl der Grenzf\u00e4lle | 21 |"))
446
+ zeile_nach(
447
+ pfad, "| G-20 |",
448
+ "| G-99 | Synthetischer Zusatzfall der Gegenprobe | **zul\u00e4ssig** | M1 | "
449
+ "niedrig | keine | `.koolie/core/tests/EDGE_CASES.md` Abschnitt 1 (D-52) |")
450
+ ersetze(_p(root, KATALOG_30),
451
+ ("Die 20 Grenzfälle einzeln", "Die 21 Grenzfälle einzeln"))
452
+
453
+
454
+ sonde("30a", "Geloeschte Grenzfallzeile gegen die Anzahl im Steckbrief",
455
+ _grenzfall_loeschen, "Grenzfallzeilen, der Steckbrief nennt")
456
+
457
+ sonde("30b", "Leere Spalte in einem Grenzfall",
458
+ _spalte_leeren, "ist leer")
459
+
460
+ sonde("30c", "Eine Entscheidung des Logs, die kein Grenzfall mehr deckt, wird gemeldet",
461
+ _entscheidung_entkoppeln, "Keine Grenzfallzeile verweist auf D-53")
462
+
463
+ gegenprobe("30", "Zusaetzlicher Grenzfall mit mitgezaehlter Anzahl",
464
+ _grenzfall_ergaenzen, "Grenzfallzeilen")
465
+
466
+
467
+
468
+ # --- Kandidatenpruefung, Status-Hook und Fetch-Allow (B08, B11) -------------------
469
+ #
470
+ # Je Pack eine eigene Installation, wie bei der Aktivierungspruefung: B02 war nicht, dass
471
+ # eine Pruefung falsch prueft, sondern dass sie einen Client gar nicht sieht. Das faellt
472
+ # nur auf, wenn derselbe Fall in jeder Installation laeuft.
473
+ #
474
+ # Die Gegenproben sind hier die wichtigere Haelfte. Bei der Kandidatenpruefung belegt sie,
475
+ # dass ein vollstaendiger, noch nicht aktiver Kandidat **durchlaeuft** - ohne sie stuende
476
+ # nur fest, dass irgendetwas gemeldet wird, und eine Pruefung, die alles meldet, besteht
477
+ # jede Sonde.
478
+
479
+
480
+ def ready_ausgabe(root: str) -> str:
481
+ """Ausgabe der Kandidatenpruefung (--check-overlay-ready)."""
482
+ p = unterprozess([sys.executable, os.path.join(root, *VALIDATOR.split("/")),
483
+ "--root", root, "--check-overlay-ready"])
484
+ return (p.stdout or "") + (p.stderr or "")
485
+
486
+
487
+ def hook_ausgabe(root: str, regelablage: str) -> str:
488
+ """Ausgabe des Status-Hooks - er blockiert nie, er informiert."""
489
+ p = unterprozess([sys.executable,
490
+ os.path.join(root, ".koolie/core", "tests", "scripts",
491
+ "hook-overlay-status.py"),
492
+ root, regelablage])
493
+ return (p.stdout or "") + (p.stderr or "")
494
+
495
+
496
+ def _kandidat_herstellen(regel: str, overlay: str, rechte: str) -> None:
497
+ """Ein vollstaendig ausgefuellter Kandidat: keine offenen Werte, Status 'inaktiv'."""
498
+ for pfad in (regel, overlay, rechte):
499
+ schreib(pfad, SO_PLATZHALTER.sub("gesetzt", lies(pfad)))
500
+ for pfad in (regel, overlay):
501
+ _so_status(pfad, "inaktiv")
502
+
503
+
504
+ def sonden_kandidatenpruefung() -> None:
505
+ """Wirkungsnachweis der Kandidatenpruefung und des Status-Hooks (B08, D-57, D-58)."""
506
+ for pack in ("claude-code", "devin-desktop"):
507
+ root = installation(pack)
508
+ try:
509
+ man = json.loads(lies(os.path.join(QUELLE, ".koolie/core", "clients", pack,
510
+ "manifest.json")))
511
+ regelablage = man["pack_runtime_dir"]
512
+ regel = os.path.join(root, *regelablage.split("/"), "20-project-overlay.md")
513
+ overlay = os.path.join(root, ".koolie/project-overlay", "OVERLAY.md")
514
+ rechte = os.path.join(root, *man["permissions_file"].split("/"))
515
+
516
+ # --- Gegenprobe: der vollstaendige, noch nicht aktive Kandidat laeuft durch
517
+ _kandidat_herstellen(regel, overlay, rechte)
518
+ aus = ready_ausgabe(root)
519
+ ok = "check-overlay-ready" not in aus and "(check-overlay-ready)" not in aus
520
+ melde("GEGENPROBE", "CR", ok,
521
+ f"Vollstaendiger Kandidat mit Status 'inaktiv' laeuft durch ({pack})")
522
+ if not ok:
523
+ notiz(" Ausgabe:", " | ".join(
524
+ z for z in aus.splitlines() if "check-overlay-ready" in z)[:400])
525
+
526
+ # --- Sonde: ein bereits aktiver Kandidat ist keiner
527
+ for pfad in (regel, overlay):
528
+ _so_status(pfad, "aktiv")
529
+ aus = ready_ausgabe(root)
530
+ melde("SONDE", "CR", "ist bereits 'aktiv'" in aus,
531
+ f"Bereits aktives Overlay wird von der Kandidatenpruefung gemeldet ({pack})")
532
+
533
+ # --- Sonde: Drift zwischen den beiden Traegern
534
+ _so_status(overlay, "inaktiv")
535
+ aus = ready_ausgabe(root)
536
+ melde("SONDE", "CR", "widersprechen sich" in aus,
537
+ f"Abweichende Statusangaben werden gemeldet ({pack})")
538
+
539
+ # --- Sonde: der Status ist ueberhaupt nicht ausgefuellt
540
+ for pfad in (regel, overlay):
541
+ _so_status(pfad, "<TBD: aktiv | inaktiv>")
542
+ aus = ready_ausgabe(root)
543
+ melde("SONDE", "CR", "nicht ausgefuellt" in aus,
544
+ f"Offener Statuswert wird gemeldet ({pack})")
545
+
546
+ # --- Status-Hook: dieselben drei Faelle, dasselbe Ergebnis ---------------
547
+ # Der Hook hatte bis 0.32.0 drei Defekte, und jeder einzelne haette die
548
+ # Meldung 'aktiv' erzeugt, wo sie falsch ist.
549
+ for pfad in (regel, overlay):
550
+ _so_status(pfad, "aktiv")
551
+ aus = hook_ausgabe(root, regelablage)
552
+ melde("GEGENPROBE", "HS", "Overlay-Status: aktiv" in aus and "Modus M1" not in aus,
553
+ f"Hook meldet 'aktiv' ohne M1-Hinweis, wenn alle Angaben aktiv sind ({pack})")
554
+
555
+ _so_status(regel, "aktivierung-ausstehend")
556
+ aus = hook_ausgabe(root, regelablage)
557
+ melde("SONDE", "HS", "Overlay-Status: widerspruechlich" in aus,
558
+ f"'aktivierung-ausstehend' gilt dem Hook nicht als aktiv ({pack})")
559
+
560
+ _so_status(regel, "inaktiv")
561
+ aus = hook_ausgabe(root, regelablage)
562
+ melde("SONDE", "HS", "Overlay-Status: widerspruechlich" in aus,
563
+ f"Hook meldet die Drift statt der ersten gelesenen Datei ({pack})")
564
+
565
+ # Nur die Steckbriefzeile, kein Listeneintrag: Das Suchmuster des Hooks
566
+ # verlangte bis 0.32.0 einen Doppelpunkt und traf die Tabelle nie.
567
+ for pfad in (regel, overlay):
568
+ _so_status(pfad, "inaktiv")
569
+ t = lies(overlay)
570
+ schreib(overlay, re.sub(r"^-\s*Overlay-Status:.*$", "", t, flags=re.M))
571
+ os.remove(regel)
572
+ aus = hook_ausgabe(root, regelablage)
573
+ melde("SONDE", "HS", "Overlay-Status: inaktiv" in aus,
574
+ f"Hook liest den Status auch aus der Steckbriefzeile ({pack})")
575
+
576
+ # --- Fetch-Allow: aus dem Manifest, nicht aus einer Namensliste ---------
577
+ # Bis 0.32.0 standen die Werkzeugnamen fest verdrahtet, und das war
578
+ # asymmetrisch: 'Fetch(domain:...)' lief durch, 'WebFetch(domain:...)' fiel.
579
+ werkzeug = man["permission_tools"]["fetch"][0]
580
+ inhalt = lies(rechte)
581
+ schreib(rechte, ersetzt(
582
+ inhalt,
583
+ ('"allow": [', '"allow": [\r\n "%s(domain:docs.example.invalid)",'
584
+ % werkzeug),
585
+ quelle=os.path.basename(rechte)))
586
+ p = unterprozess([sys.executable, os.path.join(root, *VALIDATOR.split("/")),
587
+ "--root", root])
588
+ aus = (p.stdout or "") + (p.stderr or "")
589
+ melde("SONDE", "FA", "allow-Regel auf ein Abrufwerkzeug" in aus,
590
+ f"Domain-Allow auf das Abrufwerkzeug wird gemeldet ({pack}: {werkzeug})")
591
+
592
+ schreib(rechte, inhalt)
593
+ p = unterprozess([sys.executable, os.path.join(root, *VALIDATOR.split("/")),
594
+ "--root", root])
595
+ aus = (p.stdout or "") + (p.stderr or "")
596
+ melde("GEGENPROBE", "FA", "allow-Regel auf ein Abrufwerkzeug" not in aus,
597
+ f"Die ausgelieferte Regelmenge bleibt unbeanstandet ({pack})")
598
+ finally:
599
+ aufraeumen(os.path.dirname(root))
600
+
601
+
602
+ buendel(sonden_kandidatenpruefung,
603
+ "Kandidatenpruefung, Status-Hook und Freigabenpruefung gegen je eine Installation "
604
+ "beider Packs - widerspruechlicher Status, offene Platzhalter, allow auf ein "
605
+ "Abrufwerkzeug")
606
+
607
+
608
+ # --- 31: Die Summen der Fachmatrix sind ausgerechnet (D-60) ----------------------
609
+ # Dreimal von Hand berichtigt, dreimal wieder gedriftet - deshalb ausgerechnet. Die
610
+ # Gegenprobe ist die wichtigere: Eine zusaetzliche Matrixzeile samt nachgezogener Summe
611
+ # darf nicht auffallen, sonst waere die Pruefung eine Bremse statt einer Pruefung.
612
+ PACK_31 = ".koolie/core/clients/claude-code/CLIENT_PACK.md"
613
+ UEBERSICHT_31 = ".koolie/core/clients/README.md"
614
+
615
+
616
+ def _summe_verfaelschen(root: str) -> None:
617
+ pfad = P(root, PACK_31.replace("/", os.sep))
618
+ schreib(pfad, lies(pfad).replace("| `[TECHNISCH]` | 22 von 32 |",
619
+ "| `[TECHNISCH]` | 23 von 32 |", 1))
620
+
621
+
622
+ def _gesamtzahl_verfaelschen(root: str) -> None:
623
+ pfad = P(root, PACK_31.replace("/", os.sep))
624
+ schreib(pfad, lies(pfad).replace("| 22 von 32 |", "| 22 von 33 |", 1))
625
+
626
+
627
+ def _zusammenfassung_entfernen(root: str) -> None:
628
+ pfad = P(root, PACK_31.replace("/", os.sep))
629
+ schreib(pfad, lies(pfad).replace("## 3. Zusammenfassung",
630
+ "## 3. Uebersicht", 1))
631
+
632
+
633
+ def _zeile_ohne_einstufung(root: str) -> None:
634
+ pfad = P(root, PACK_31.replace("/", os.sep))
635
+ t = lies(pfad)
636
+ marke = "| X2 |"
637
+ i = t.index(marke)
638
+ ende = t.index("\r\n", i)
639
+ schreib(pfad, t[:ende] + "\r\n| Z9 | Sonde ohne Einstufung | - | - | - |" + t[ende:])
640
+
641
+
642
+ def _zeile_mit_summe(root: str) -> None:
643
+ """Gegenprobe: eine zusaetzliche Zeile samt nachgezogenen Summen."""
644
+ pfad = P(root, PACK_31.replace("/", os.sep))
645
+ frei(pfad, "| Z9 |")
646
+ zeile_nach(pfad, "| X2 |",
647
+ "| Z9 | Sonde mit Einstufung | - | `[TECHNISCH]` | `[DOK]` |")
648
+ ersetze(pfad,
649
+ ("| `[TECHNISCH]` | 22 von 32 |", "| `[TECHNISCH]` | 23 von 33 |"),
650
+ ("| 8 von 32 (", "| 8 von 33 ("),
651
+ ("| **2 von 32** (", "| **2 von 33** ("),
652
+ ("| 0 von 32 |", "| 0 von 33 |"))
653
+ # Seit 0.36.0 rechnet Pruefung 31 dieselbe Zahl auch in der Uebersicht der Ablage nach
654
+ # (D-71). Eine Gegenprobe, die nur das Pack nachzieht, faellt seither an der zweiten
655
+ # Stelle - und genau das ist der Zweck der Erweiterung.
656
+ u = P(root, UEBERSICHT_31.replace("/", os.sep))
657
+ # 0.89.0: Der Statuswert dieser Zeile stand hier woertlich und ist mit CR-2026-124
658
+ # von "entwurf" auf "pilot" berichtigt worden - das Pack selbst sagte schon "pilot".
659
+ ersetze(u, ("| pilot | 22 von 32 |", "| pilot | 23 von 33 |"))
660
+
661
+
662
+ sonde("31a", "Verfaelschte Anzahl je Einstufung in der Zusammenfassung",
663
+ _summe_verfaelschen, "Zeile(n) als [TECHNISCH]; gezaehlt sind")
664
+
665
+ sonde("31b", "Eine verfaelschte Gesamtzahl der Matrixzeilen wird gegen die gezaehlte Zahl gemeldet",
666
+ _gesamtzahl_verfaelschen, "Matrixzeilen; gezaehlt sind")
667
+
668
+ sonde("31c", "Fehlende Zusammenfassung - die Pruefung darf nicht leise bestehen",
669
+ _zusammenfassung_entfernen, "kein Abschnitt '## 3. Zusammenfassung")
670
+
671
+ sonde("31d", "Eine Matrixzeile ohne Einstufung faellt aus jeder Summe und wird gemeldet",
672
+ _zeile_ohne_einstufung, "ohne Einstufung: Z9")
673
+
674
+ def _uebersicht_verfaelschen(root: str) -> None:
675
+ pfad = P(root, UEBERSICHT_31.replace("/", os.sep))
676
+ schreib(pfad, lies(pfad).replace("| pilot | 22 von 32 |",
677
+ "| pilot | 25 von 29 |", 1))
678
+
679
+
680
+ def _uebersichtszeile_entfernen(root: str) -> None:
681
+ pfad = P(root, UEBERSICHT_31.replace("/", os.sep))
682
+ t = lies(pfad)
683
+ i = t.index("| `claude-code` | `CP-CC` |")
684
+ ende = t.index("\r\n", i) + 2
685
+ schreib(pfad, t[:i] + t[ende:])
686
+
687
+
688
+ sonde("31e", "Ueberholte Zahl in der Uebersicht der Ablage - der Stand bis 0.35.0",
689
+ _uebersicht_verfaelschen, "technisch durchgesetzte Zeilen; aus der Faehigkeitsmatrix")
690
+
691
+ sonde("31f", "Pack ohne Zeile in der Uebersicht", _uebersichtszeile_entfernen,
692
+ "kein Eintrag fuer das Client Pack 'claude-code'")
693
+
694
+ gegenprobe("31", "Zusaetzliche Matrixzeile samt nachgezogener Summe an BEIDEN Stellen",
695
+ _zeile_mit_summe, "gezaehlt sind")
696
+
697
+
698
+
699
+ # --- 32: Eingabeschema und Pfadidentitaet des Schutz-Hooks (B06, CR-2026-056) -----
700
+ #
701
+ # Sechs Sonden, weil der Hook seit 0.34.0 sechs voneinander unabhaengige Mechanismen
702
+ # traegt. Jede bricht genau EINEN, und keine bricht ihn ueber den naheliegenden Fall:
703
+ # Bei .KOOLIE/CORE/VERSION decken die Aufloesung und re.I einander gegenseitig zu -
704
+ # faellt einer von beiden aus, bestuende die Pruefung, und die Sonde zeigte nichts.
705
+ # 32a und 32e treffen deshalb je einen Fall, den nur ein Mechanismus faengt.
706
+ HOOK_32 = ".koolie/core/tests/scripts/hook-check-secrets.py"
707
+
708
+
709
+ def _hook32(root: str) -> str:
710
+ return P(root, HOOK_32.replace("/", os.sep))
711
+
712
+
713
+ def _tausche(root: str, alt: str, neu: str) -> None:
714
+ """Eine Ersetzung im Hook der Kopie. Trifft der Suchtext nicht, bleibt der Baum
715
+ unveraendert - und sonde() meldet genau das, statt die Pruefung zu messen."""
716
+ pfad = _hook32(root)
717
+ schreib(pfad, lies(pfad).replace(alt, neu, 1))
718
+
719
+
720
+ def _ohne_aufloesung(root: str) -> None:
721
+ """Die Pfadaufloesung liefert nichts - die Muster sehen nur noch den Rohtext."""
722
+ _tausche(root, " voll, nur_secret = [], []", " return [], []")
723
+
724
+
725
+ def _ohne_ereignispruefung(root: str) -> None:
726
+ """Eine leere Eingabe gilt wieder als harmloses Ereignis - der Stand bis 0.33.0."""
727
+ _tausche(root, ' raise Unpruefbar("leere Eingabe")',
728
+ ' raw = \'{"tool_name": "x", "tool_input": {}}\'')
729
+
730
+
731
+ def _umschlag_im_pruefmaterial(root: str) -> None:
732
+ """Der Umschlag wandert zurueck ins Pruefmaterial - der Stand bis 0.33.0."""
733
+ _tausche(root, " return tool_name.strip().lower(), tool_input, basis",
734
+ " return tool_name.strip().lower(), dict(payload, **tool_input), basis")
735
+ # Seit 1.17.0 misst ein Schreibwerkzeug nur seine Ziele (D-449). Der alte Stand
736
+ # hielt ALLE Zeichenketten gegen die Muster - erst beides zusammen stellt ihn her.
737
+ _tausche(root, " zu_pruefen = list(ziele)",
738
+ " zu_pruefen = list(ziele) + list(strings)")
739
+
740
+
741
+ def _unbekanntes_werkzeug_lax(root: str) -> None:
742
+ """Eine unbekannte Operation gilt wieder als lesend statt als die strengste."""
743
+ _tausche(root, ' schreibend = verb in ("write", "unbekannt")',
744
+ ' schreibend = verb == "write"')
745
+
746
+
747
+ def _ohne_schreibweise(root: str) -> None:
748
+ """Das Secret-Muster fuer .env wird wieder schreibungssensitiv."""
749
+ _tausche(root, r'\.env(\.|$)", re.I', r'\.env(\.|$)"')
750
+
751
+
752
+ def _32_anker_verlieren(root: str) -> None:
753
+ """Der Suchtext, ueber den Pruefung 32 ihren Gegenstand findet, geht verloren."""
754
+ pfad = _hook32(root)
755
+ schreib(pfad, lies(pfad).replace("ereignis_lesen(", "ereignis_pruefen("))
756
+
757
+
758
+ def _zusaetzliches_pfadfeld(root: str) -> None:
759
+ """Gegenprobe: ein weiteres Pfadfeld im Manifest - eine zulaessige Verschaerfung."""
760
+ for pack in ("claude-code", "devin-desktop"):
761
+ pfad = P(root, (".koolie/core/clients/%s/manifest.json" % pack).replace("/", os.sep))
762
+ ersetze(pfad, ('"hook_path_fields": ["file_path"',
763
+ '"hook_path_fields": ["zielpfad", "file_path"'))
764
+
765
+
766
+ sonde("32a", "Pfadaufloesung aus - nur sie faengt einen Pfad, der den Kern nicht nennt",
767
+ _ohne_aufloesung, "ohne es zu nennen")
768
+
769
+ sonde("32b", "Ereignispruefung aus - eine leere Eingabe gilt wieder als Ereignis",
770
+ _ohne_ereignispruefung, "ist kein Werkzeugereignis")
771
+
772
+ sonde("32c", "Umschlag zurueck im Pruefmaterial - der Stand bis 0.33.0",
773
+ _umschlag_im_pruefmaterial, "je nachdem ob der Umschlag")
774
+
775
+ sonde("32d", "Unbekannte Operation gilt wieder als lesend",
776
+ _unbekanntes_werkzeug_lax, "unbekanntes Werkzeug in das Kernverzeichnis")
777
+
778
+ sonde("32e", "Secret-Muster wieder schreibungssensitiv - nur re.I faengt die nicht "
779
+ "vorhandene Datei", _ohne_schreibweise, "wenn die Datei nicht existiert")
780
+
781
+ sonde("32f", "Verlorener Anker - die Pruefung darf nicht leise bestehen",
782
+ _32_anker_verlieren, "'def ereignis_lesen(' fehlt")
783
+
784
+ def _unteragent_ausnehmen(root: str) -> None:
785
+ """Ein Rueckfall, den nur der Unteragenten-Umschlag faengt (CR-2026-058 E3).
786
+
787
+ Simuliert die naheliegende Regression: Jemand nimmt Aufrufe aus einem Unteragenten
788
+ von der Pruefung aus - etwa weil sie "schon oben geprueft" seien. Keine der uebrigen
789
+ sechs Sonden zu 32 sieht das: Ohne agent_type im Umschlag greift die Ausnahme nicht,
790
+ und der Hook verhaelt sich in jedem anderen Fall unveraendert.
791
+ """
792
+ pfad = P(root, ".koolie/core/tests/scripts/hook-check-secrets.py".replace("/", os.sep))
793
+ t = lies(pfad)
794
+ marke = " tool_name = payload.get(\"tool_name\")"
795
+ i = t.index(marke)
796
+ schreib(pfad, t[:i] + " if payload.get(\"agent_type\"):\r\n"
797
+ " return \"read\", {}, PROJEKTWURZEL\r\n" + t[i:])
798
+
799
+
800
+ sonde("32g", "Unteragenten-Umschlag von der Pruefung ausgenommen - ein Rueckfall, den "
801
+ "keine der uebrigen Sonden sieht",
802
+ _unteragent_ausnehmen, "Operation aus einem Unteragenten anders als erwartet")
803
+
804
+ gegenprobe("32", "Zusaetzliches Pfadfeld im Manifest ist eine zulaessige Verschaerfung",
805
+ _zusaetzliches_pfadfeld, "Befund B06")
806
+
807
+
808
+ # --- 33: Die Abbildung von permissions.deny auf die Werkzeugsperre (CR-2026-057) -----
809
+ #
810
+ # GEGEN EINE ECHTE INSTALLATION, und das ist hier nicht Zierrat: Pruefung 33 laeuft nur
811
+ # fuer ein Pack, dessen Manifest skill_deny_field fuehrt. Die Testinstallation im
812
+ # Repositorium ist 'devin-desktop' und fuehrt es nicht - die Pruefung wird im Repo-Lauf
813
+ # also GAR NICHT ausgefuehrt. Genau das war Befund B02: nicht, dass eine Pruefung falsch
814
+ # prueft, sondern dass sie einen Client nicht sieht.
815
+ #
816
+ # Fuenf Sonden und eine Gegenprobe. Jede Sonde bricht genau einen Mechanismus.
817
+ def _p33(root: str, name: str) -> str:
818
+ return os.path.join(root, ".claude", "skills", name, "SKILL.md")
819
+
820
+
821
+ def sonden_skill_deny() -> None:
822
+ """Wirkungsnachweis der Abbildung und ihrer Grenzen (D-64 bis D-66)."""
823
+ root = installation("claude-code")
824
+ try:
825
+ plan = _p33(root, "fw-plan")
826
+ ausgang = lies(plan)
827
+
828
+ # --- Gegenprobe: die unveraenderte Installation laeuft durch ----------------
829
+ # Sie ist hier die wichtigere Haelfte. Ohne sie stuende nur fest, dass Pruefung 33
830
+ # irgendetwas meldet - und eine Pruefung, die jede Installation beanstandet,
831
+ # bestuende jede Sonde.
832
+ aus = validator_ausgabe(root)
833
+ melde("GEGENPROBE", "33", "disallowed-tools" not in aus,
834
+ "Die unveraenderte claude-code-Installation bleibt unbeanstandet")
835
+ if "disallowed-tools" in aus:
836
+ notiz(" Ausgabe:", " | ".join(
837
+ z for z in aus.splitlines() if "disallowed-tools" in z)[:400])
838
+
839
+ # --- 33a: die Sperre fehlt ganz - der Stand bis 0.34.0 ----------------------
840
+ schreib(plan, ersetzt(
841
+ ausgang,
842
+ ("disallowed-tools: Edit, Write, NotebookEdit, Bash, PowerShell\n", ""),
843
+ quelle="fw-plan/SKILL.md"))
844
+ aus = validator_ausgabe(root)
845
+ melde("SONDE", "33a", "aus permissions.deny der Quelle ergibt sich" in aus,
846
+ "Fehlende Werkzeugsperre - der Stand, den B01 beschrieb")
847
+
848
+ # --- 33b: die Sperre ist unvollstaendig - eine Luecke ist ausnutzbar --------
849
+ schreib(plan, ersetzt(
850
+ ausgang,
851
+ ("disallowed-tools: Edit, Write, NotebookEdit, Bash, PowerShell",
852
+ "disallowed-tools: Edit, Write"),
853
+ quelle="fw-plan/SKILL.md"))
854
+ aus = validator_ausgabe(root)
855
+ melde("SONDE", "33b", "aus permissions.deny der Quelle ergibt sich" in aus,
856
+ "Unvollstaendige Sperre - mit gesperrtem Write, Edit schrieb der Skill ueber Bash")
857
+
858
+ # --- 33c: ein Argumentmuster - gemessen wirkungslos, und zwar lautlos -------
859
+ schreib(plan, ersetzt(
860
+ ausgang,
861
+ ("disallowed-tools: Edit, Write, NotebookEdit, Bash, PowerShell",
862
+ "disallowed-tools: Edit, Write, NotebookEdit, Bash(git push:*), PowerShell"),
863
+ quelle="fw-plan/SKILL.md"))
864
+ aus = validator_ausgabe(root)
865
+ melde("SONDE", "33c", "Argumentmuster" in aus,
866
+ "Argumentmuster in der Sperre - es sieht aus wie eine Regel und ist keine")
867
+
868
+ # --- 33d: ein Werkzeug in beiden Listen - zwei Aussagen, eine davon falsch --
869
+ schreib(plan, ersetzt(
870
+ ausgang,
871
+ ("allowed-tools: Read, Grep, Glob",
872
+ "allowed-tools: Read, Grep, Glob, Bash"),
873
+ quelle="fw-plan/SKILL.md"))
874
+ aus = validator_ausgabe(root)
875
+ melde("SONDE", "33d", "steht zugleich in allowed-tools" in aus,
876
+ "Werkzeug zugleich vorabfreigegeben und gesperrt")
877
+ schreib(plan, ausgang)
878
+
879
+ # --- 33e: der verlorene Anker - die Pruefung darf nicht leise bestehen ------
880
+ inst = os.path.join(root, ".koolie/core", "install.py")
881
+ quelle = lies(inst)
882
+ schreib(inst, ersetzt(quelle,
883
+ ("def deny_abbilden(", "def deny_uebersetzen("),
884
+ quelle="install.py"))
885
+ aus = validator_ausgabe(root)
886
+ melde("SONDE", "33e", "'def deny_abbilden(' fehlt" in aus,
887
+ "Verlorener Anker - die Pruefung meldet ihr Fehlen selbst")
888
+ schreib(inst, quelle)
889
+ finally:
890
+ aufraeumen(os.path.dirname(root))
891
+
892
+
893
+ buendel(sonden_skill_deny,
894
+ "Die Abbildung von permissions.deny in das Frontmatter eines Skills und ihre "
895
+ "Grenzen - Argumentmuster, Doppelnennung in allowed-tools, verlorener Anker")
896
+
897
+
898
+
899
+ # --- 34: Das Startwerkzeug fuer Unteragenten ist genannt oder erklaert (D-70) -----
900
+ #
901
+ # Anlass ist ein gemessener Befund vom 2026-09-13: Ein Skill kann einen Unteragenten
902
+ # starten, die Skill-Sperre reicht in ihn hinein - und das Startwerkzeug stand in keiner
903
+ # Werkzeugliste eines Manifests. Bauform der Deklaration wie hook_tools_absent (D-47).
904
+ #
905
+ # Die letzte Sonde ist die interessanteste: Sie belegt die Verschaerfung, die diese
906
+ # Pruefung bei ihrem ERSTEN Lauf selbst gelernt hat. Ohne den Vorbehalt fiel
907
+ # devin-desktop durch, obwohl es ehrlich ist - seine Zeile A1 trug einen offenen
908
+ # Beleg, und die Praeambel des Packs sagt, die Einstufung nenne die VORGESEHENE
909
+ # Tiefe. Die Einstufung allein sagt nicht, ob eine Zusage schon gilt.
910
+ #
911
+ # MIT 0.87.0 STEHT DER VORBEHALT AUF DER NACHFOLGEFORM BELEG OFFEN (D-291); die
912
+ # Markerform ist abgeschafft. Die Sonde trifft davon nichts: Sie nimmt seit 0.86.0 das
913
+ # Startwerkzeug weg und nicht den Vorbehalt.
914
+ MANIFEST_CC_34 = ".koolie/core/clients/claude-code/manifest.json"
915
+ MANIFEST_DD_34 = ".koolie/core/clients/devin-desktop/manifest.json"
916
+ PACK_DD_34 = ".koolie/core/clients/devin-desktop/CLIENT_PACK.md"
917
+
918
+
919
+ def _34_feld_entfernen(root: str) -> None:
920
+ pfad = P(root, MANIFEST_CC_34.replace("/", os.sep))
921
+ t = lies(pfad)
922
+ i = t.index(' "agent_start_tools": ["Agent", "Task"],')
923
+ ende = t.index("\r\n", i) + 2
924
+ schreib(pfad, t[:i] + t[ende:])
925
+
926
+
927
+ def _34_leer_ohne_erklaerung(root: str) -> None:
928
+ pfad = P(root, MANIFEST_CC_34.replace("/", os.sep))
929
+ schreib(pfad, lies(pfad).replace('"agent_start_tools": ["Agent", "Task"],',
930
+ '"agent_start_tools": [],', 1))
931
+
932
+
933
+ def _34_erklaerung_ohne_notiz(root: str) -> None:
934
+ """Die Sonde BRINGT die Abwesenheitserklaerung mit, statt sie vorauszusetzen.
935
+
936
+ Bis 0.85.2 stand sie im Bestand (`agent_start_tools_absent: ["unerhoben"]`); mit
937
+ 0.86.0 ist sie aufgeloest - das Startwerkzeug heisst `run_subagent` (D-284). Eine
938
+ Sonde, die auf den Bestand zeigt, verliert damit ihren Gegenstand und bestuende
939
+ leise (D-23). Sie setzt ihn seither selbst.
940
+ """
941
+ pfad = P(root, MANIFEST_DD_34.replace("/", os.sep))
942
+ t = lies(pfad)
943
+ t = t.replace('"agent_start_tools": ["run_subagent"],',
944
+ '"agent_start_tools": [],', 1)
945
+ t = t.replace('"agent_start_tools_absent": [],',
946
+ '"agent_start_tools_absent": ["unerhoben"],', 1)
947
+ t = t.replace('"_agent_start_tools_absent_note"',
948
+ '"_agent_start_tools_absent_hinweis"', 1)
949
+ schreib(pfad, t)
950
+
951
+
952
+ def _34_beides_zugleich(root: str) -> None:
953
+ pfad = P(root, MANIFEST_CC_34.replace("/", os.sep))
954
+ schreib(pfad, lies(pfad).replace(
955
+ '"agent_start_tools": ["Agent", "Task"],',
956
+ '"agent_start_tools": ["Agent", "Task"],\r\n'
957
+ ' "agent_start_tools_absent": ["unerhoben"],\r\n'
958
+ ' "_agent_start_tools_absent_note": "Sonde.",', 1))
959
+
960
+
961
+ def _34_a1_ohne_vorbehalt(root: str) -> None:
962
+ """devin-desktop sagt A1 ohne VERIFY-Marker zu, kann das Werkzeug aber nicht nennen."""
963
+ # BIS 0.85.2 nahm diese Sonde der Zeile A1 ihren VERIFY-Marker. Den gibt es nicht
964
+ # mehr: Die Profilwirkung ist am 2026-09-22 gemessen (D-284), und die Zeile sagt A1
965
+ # seither OHNE Vorbehalt zu. Damit ist der Vorbehalt kein Praeparationsort mehr -
966
+ # die Sonde nimmt stattdessen das Startwerkzeug weg, das die Zusage traegt. Der
967
+ # gemessene Fall ist derselbe, und er ist in diesem Release LIVE eingetreten:
968
+ # Pruefung 34 hat ihn gemeldet, sobald A1 seinen Marker verlor und das Manifest noch
969
+ # ein leeres Feld fuehrte.
970
+ pfad = P(root, MANIFEST_DD_34.replace("/", os.sep))
971
+ t = lies(pfad)
972
+ t = t.replace('"agent_start_tools": ["run_subagent"],',
973
+ '"agent_start_tools": [],', 1)
974
+ t = t.replace('"agent_start_tools_absent": [],',
975
+ '"agent_start_tools_absent": ["unerhoben"],', 1)
976
+ schreib(pfad, t)
977
+
978
+
979
+ sonde("34a", "Manifest ohne Feld agent_start_tools - ein Kanal ohne Deklaration",
980
+ _34_feld_entfernen, "Feld 'agent_start_tools' fehlt")
981
+
982
+ sonde("34b", "Leere Liste ohne erklaerte Abwesenheit - unerhoben oder abwesend?",
983
+ _34_leer_ohne_erklaerung, "ohne dass 'agent_start_tools_absent' die Abwesenheit")
984
+
985
+ sonde("34c", "Erklaerte Abwesenheit ohne Begruendung - eine Behauptung",
986
+ _34_erklaerung_ohne_notiz, "'_agent_start_tools_absent_note' fehlt")
987
+
988
+ sonde("34d", "Genannt und zugleich fuer abwesend erklaert - zwei Aussagen, eine falsch",
989
+ _34_beides_zugleich, "Beides zugleich geht nicht")
990
+
991
+ sonde("34e", "Zeile A1 ohne Vorbehalt zugesagt, Startwerkzeug aber nur erklaert",
992
+ _34_a1_ohne_vorbehalt, "Wer Unteragenten zusagt, nennt das Werkzeug")
993
+
994
+ gegenprobe("34", "Die unveraenderten Packs bleiben unbeanstandet - eines nennt, eines "
995
+ "erklaert mit offenem Vorbehalt", None, "agent_start_tools")
996
+
997
+
998
+ # --- 35: Ein Agentenprofil bekommt kein Startwerkzeug (D-73) ---------------------
999
+ #
1000
+ # Diese Pruefung faengt heute nichts: agent_frontmatter.tool_names kennt gar kein
1001
+ # Startwerkzeug. Sie ist eine Verankerung - und genau deshalb braucht sie ihre Sonden
1002
+ # dringender als andere. Ohne sie liesse sich nicht zeigen, DASS sie etwas faengt,
1003
+ # sobald es den Fall gibt. Gemessen ist der Befund dahinter am 2026-09-13, Lauf
1004
+ # STARTLOS: Ein Profil mit tools: Read, Grep, Glob kann keine zweite Ebene oeffnen.
1005
+ MANIFEST_CC_35 = ".koolie/core/clients/claude-code/manifest.json"
1006
+ PROFIL_35 = ".koolie/core/framework/runtime/agents/fw-reviewer.md"
1007
+
1008
+
1009
+ def _35_abbildung_erweitern(root: str) -> None:
1010
+ """Der Fall, der die Zusage lautlos fallen liesse: tool_names lernt es.
1011
+
1012
+ Praepariert wird ueber das JSON, nicht ueber den Text: skill_frontmatter und
1013
+ agent_frontmatter fuehren ZEICHENGLEICHE tool_names-Bloecke, und ein Textanker
1014
+ traefe den falschen. Pruefung 35 liest nur den zweiten."""
1015
+ pfad = P(root, MANIFEST_CC_35.replace(chr(47), os.sep))
1016
+ daten = json.loads(lies(pfad))
1017
+ daten['agent_frontmatter']['tool_names']['delegate'] = ['Agent']
1018
+ schreib(pfad, json.dumps(daten, ensure_ascii=False, indent=2))
1019
+
1020
+
1021
+ def _35_profil_erweitern(root: str) -> None:
1022
+ """Der Fall an der Abbildung vorbei: das Profil nennt es selbst."""
1023
+ pfad = P(root, PROFIL_35.replace("/", os.sep))
1024
+ schreib(pfad, lies(pfad).replace(" - glob", " - glob\r\n - agent", 1))
1025
+
1026
+
1027
+ def _35_ablage_entfernen(root: str) -> None:
1028
+ """Die Sonde auf den verlorenen Anker: ohne Ablage darf sie nicht leise bestehen."""
1029
+ shutil.rmtree(P(root, ".koolie/core/framework/runtime/agents".replace("/", os.sep)))
1030
+
1031
+
1032
+ sonde("35a", "Die Abbildung lernt ein Startwerkzeug - der Fall, der die Zusage "
1033
+ "lautlos fallen liesse",
1034
+ _35_abbildung_erweitern, "ein Werkzeug, mit dem ein Unteragent GESTARTET")
1035
+
1036
+ sonde("35b", "Das Agentenprofil nennt ein Startwerkzeug selbst - an der Abbildung "
1037
+ "vorbei",
1038
+ _35_profil_erweitern, "Das Frontmatter nennt 'agent'")
1039
+
1040
+ sonde("35c", "Verlorener Anker - die Agentenablage fehlt",
1041
+ _35_ablage_entfernen, "Pruefung 35 misst die Agentenprofile des Kerns")
1042
+
1043
+ gegenprobe("35", "Die unveraenderte Ablage bleibt unbeanstandet", None,
1044
+ "GESTARTET wird")
1045
+
1046
+ # --- 36: Die Tabellen des Decision Logs sind nicht zerrissen (D-75) --------------
1047
+ #
1048
+ # Anlass: vier zerrissene Zeilen in 0.34.0, eine davon seit 0.10.x. Gefunden hat sie
1049
+ # jedes Mal ein Mensch beim Eintragen einer anderen.
1050
+ #
1051
+ # Die Gegenprobe ist hier die wichtigere Haelfte, und zwar aus einem gemessenen Grund:
1052
+ # Eine naive Zaehlung mit .split("|") meldet D-29 und D-69 als achtspaltig, obwohl beide
1053
+ # ihren Strich korrekt maskieren und sechsspaltig rendern. Ohne diese Gegenprobe waere
1054
+ # Pruefung 36 mit zwei Fehlalarmen auf richtigem Text entstanden - und Pruefung 30 haette
1055
+ # ihren eigenen, latenten Fehlalarm behalten (CR-2026-060 1.3).
1056
+ DECISION_LOG_36 = ".koolie/core/governance/DECISION_LOG.md"
1057
+
1058
+
1059
+ def _dl36(root: str) -> str:
1060
+ return P(root, DECISION_LOG_36.replace("/", os.sep))
1061
+
1062
+
1063
+ def _36_zelle_entfernen(root: str) -> None:
1064
+ """Eine Zeile verliert ihre letzte Zelle - der Fall D-61 bis D-63 aus 0.34.0."""
1065
+ pfad = _dl36(root)
1066
+ zeilen = lies(pfad).split("\r\n")
1067
+ treffer = [i for i, z in enumerate(zeilen) if z.startswith("| D-40 |")]
1068
+ if len(treffer) != 1:
1069
+ raise Praeparationsfehler(
1070
+ "DECISION_LOG.md: Anker '| D-40 |' steht %dx, erwartet genau einmal"
1071
+ % len(treffer))
1072
+ z = zeilen[treffer[0]].rstrip().rstrip("|").rstrip()
1073
+ zeilen[treffer[0]] = z[:z.rindex("|")] + "|"
1074
+ schreib(pfad, "\r\n".join(zeilen))
1075
+
1076
+
1077
+ def _36_strich_unmaskiert(root: str) -> None:
1078
+ """Ein unmaskierter Strich in einem Codespan - der Fall D-29 aus 0.10.x."""
1079
+ ersetze(_dl36(root),
1080
+ ("| D-40 | **Ein Befund \u00fcber einen Client ist keine Aussage "
1081
+ "\u00fcber alle.**",
1082
+ "| D-40 | **Ein Befund \u00fcber einen Client ist keine Aussage "
1083
+ "\u00fcber alle.** Matcher `a|b`."))
1084
+
1085
+
1086
+ def _36_anker_verlieren(root: str) -> None:
1087
+ """Keine Tabellenzeile mehr - die Pruefung darf nicht leise bestehen."""
1088
+ pfad = _dl36(root)
1089
+ zeilen = [z for z in lies(pfad).split("\r\n") if not z.startswith("|")]
1090
+ schreib(pfad, "\r\n".join(zeilen))
1091
+
1092
+
1093
+ def _36_strich_maskiert(root: str) -> None:
1094
+ """Gegenprobe: derselbe Strich, korrekt maskiert - so, wie D-69 ihn seit 0.36.0
1095
+ traegt. Eine Zaehlung ohne diese Unterscheidung beanstandet den richtigen Text."""
1096
+ ersetze(_dl36(root),
1097
+ ("| D-40 | **Ein Befund \u00fcber einen Client ist keine Aussage "
1098
+ "\u00fcber alle.**",
1099
+ "| D-40 | **Ein Befund \u00fcber einen Client ist keine Aussage "
1100
+ "\u00fcber alle.** Matcher `a\\|b`."))
1101
+
1102
+
1103
+ sonde("36a", "Zeile mit fehlender Zelle - der Fall D-61 bis D-63 aus 0.34.0",
1104
+ _36_zelle_entfernen, "Zellen, der Kopf ihrer Tabelle")
1105
+
1106
+ sonde("36b", "Unmaskierter Strich in einer Zelle - der Fall D-29 seit 0.10.x",
1107
+ _36_strich_unmaskiert, "Zellen, der Kopf ihrer Tabelle")
1108
+
1109
+ sonde("36c", "Verlorener Anker - keine Tabellenzeile mehr",
1110
+ _36_anker_verlieren, "keine Tabellenzeile gefunden")
1111
+
1112
+ gegenprobe("36", "Maskierter Strich bleibt unbeanstandet - die Schreibweise von D-69",
1113
+ _36_strich_maskiert, "Kopf ihrer Tabelle")
1114
+
1115
+
1116
+ # --- Selbstprobe: der Praeparationswaechter selbst (CR-2026-060, D-74) ----------
1117
+ #
1118
+ # Ohne sie waere der Waechter die erste ungepruefte Zusage dieses Skripts - und ein
1119
+ # Waechter, der still ausfaellt, ist genau der Befundtyp, gegen den er gebaut ist.
1120
+ # Er laeuft ohne Kopie und ohne Validator: Sein Gegenstand ist reine Textarithmetik.
1121
+ def selbstprobe_waechter() -> None:
1122
+ """Der Waechter meldet sich, wenn ein Suchtext nicht genau so oft trifft."""
1123
+ faelle = [
1124
+ ("W1", "Suchtext trifft gar nicht",
1125
+ lambda: ersetzt("abc", ("xyz", "1")), True),
1126
+ ("W2", "Suchtext trifft oefter als erwartet",
1127
+ lambda: ersetzt("aa", ("a", "b")), True),
1128
+ ("W3", "Suchtext trifft genau so oft wie erwartet",
1129
+ lambda: ersetzt("aa", ("a", "b", 2)), False),
1130
+ ("W4", "Die ZWEITE Ersetzung trifft nicht - der Fall der halben Praeparation",
1131
+ lambda: ersetzt("ab", ("a", "x"), ("zzz", "y")), True),
1132
+ ]
1133
+ for nummer, was, aufruf, erwartet_fehler in faelle:
1134
+ try:
1135
+ aufruf()
1136
+ geworfen = False
1137
+ except Praeparationsfehler:
1138
+ geworfen = True
1139
+ melde("SELBSTPROBE", nummer, geworfen == erwartet_fehler, was)
1140
+
1141
+ # W5: Der Waechter darf nichts geschrieben haben, wenn er abbricht. ersetzt()
1142
+ # arbeitet auf einem Text und gibt ihn erst am Ende zurueck - das ist die Zusage,
1143
+ # und sie wird hier gepruft, nicht behauptet.
1144
+ try:
1145
+ ersetzt("ab", ("a", "x"), ("zzz", "y"))
1146
+ ergebnis = "durchgelaufen"
1147
+ except Praeparationsfehler as exc:
1148
+ ergebnis = str(exc)
1149
+ melde("SELBSTPROBE", "W5", "zzz" in ergebnis and "trifft 0x" in ergebnis,
1150
+ "Die Meldung nennt den Suchtext, der nicht mehr passt")
1151
+
1152
+
1153
+ buendel(selbstprobe_waechter,
1154
+ "Der Praeparationswaechter selbst: Er meldet jeden Suchtext, der nicht genau so oft "
1155
+ "trifft wie erwartet, und schreibt bei Abbruch nichts")
1156
+
1157
+
1158
+ def selbstprobe_kennung() -> None:
1159
+ """Der Kennungswaechter - er ist genau so klug wie die Kennung, die man ihm gibt."""
1160
+ root = kopie()
1161
+ try:
1162
+ pfad = _p(root, EDGE_30)
1163
+ try:
1164
+ frei(pfad, "G-99")
1165
+ frei_ok = True
1166
+ except Praeparationsfehler:
1167
+ frei_ok = False
1168
+ melde("SELBSTPROBE", "K1", frei_ok,
1169
+ "G-99 ist im Repositorium nicht vergeben - die Gegenprobe 30 darf sie nutzen")
1170
+
1171
+ try:
1172
+ frei(pfad, "G-01")
1173
+ kollision = False
1174
+ except Praeparationsfehler:
1175
+ kollision = True
1176
+ melde("SELBSTPROBE", "K2", kollision,
1177
+ "Eine vergebene Kennung wird gemeldet - der Fall G-18 vom 2026-09-13")
1178
+ finally:
1179
+ aufraeumen(os.path.dirname(root))
1180
+
1181
+
1182
+ buendel(selbstprobe_kennung,
1183
+ "Der Kennungswaechter ist genau so klug wie die Kennung, die man ihm gibt - eine "
1184
+ "freie laeuft durch, eine vergebene wird gemeldet")