@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,1014 @@
1
+ """Sonden zum Wert- und Pfadabgleich des Overlays (Pruefungen 59 und 89), zu den Overlay-
2
+ Mustern, zum Kopierweg, zum Lieferumfang (Pruefung 90) und zum Lauf ohne PyYAML.
3
+
4
+ Teil des Sondenskripts probe-pruefungen.py, seit 1.19.1 in Module geteilt (K-174). Die
5
+ Einheiten melden sich beim Laden dieses Moduls an; der Einstieg laedt die Module in der
6
+ Reihenfolge ihrer Nummer, und das ist die Reihenfolge der Ausgabe (D-49). Ein Modul
7
+ liest nur aus dem Apparat und aus frueheren Teilen."""
8
+ from __future__ import annotations
9
+
10
+ import glob
11
+ import json
12
+ import os
13
+ import re
14
+ import shutil
15
+ import subprocess
16
+ import sys
17
+ import tempfile
18
+
19
+ from .apparat import (
20
+ aufraeumen, baumhash, buendel, ersetzt, installation, kopie, lies, melde, notiz, P,
21
+ Praeparationsfehler, QUELLE, schreib, sonde, strict_ausgabe, unterprozess,
22
+ VALIDATOR, validator_ausgabe)
23
+
24
+
25
+ # --- Pruefung 59: der Overlay-Wert in der Schicht, die ihn durchsetzt (D-171) ------
26
+ #
27
+ # Sie braucht eine GEFUELLTE Installation: Im Framework-Repositorium traegt das
28
+ # Beispiel-Overlay Ausfuellschlitze, und die Pruefung enthaelt sich dort - richtigerweise,
29
+ # denn ein offener Schlitz ist Sache von --check-overlay-ready. Die drei Sonden treffen
30
+ # die drei Gegenstaende; die Gegenprobe belegt den vollstaendig nachgezogenen Zustand,
31
+ # und sie ist der eigentliche Nachweis: Ohne sie stuende nur fest, dass die Pruefung
32
+ # etwas meldet, nicht dass ein richtiger Baum sie schweigen laesst.
33
+ M59_BINDUNG = "nennt <EXCLUDED_PATHS> nicht"
34
+ M59_WERT = "weichen vom Quell-Overlay ab"
35
+ M59_KORB = "keine Regel"
36
+ P59_QUELLGLOBS = ["deploy/**", "infra/**"]
37
+ P59_SCHLITZ = ("`<TBD: z. B. deploy/**, infra/**, config/prod/**, "
38
+ "**/fixtures/real/**>`")
39
+ _59_KORBSTAND: dict = {}
40
+
41
+
42
+ def _59_pfade(root: str) -> tuple:
43
+ return (os.path.join(root, ".koolie/project-overlay", "OVERLAY.md"),
44
+ os.path.join(root, ".claude", "rules", "20-project-overlay.md"),
45
+ os.path.join(root, ".claude", "settings.json"))
46
+
47
+
48
+ def _59_quelle_fuellen(root: str) -> None:
49
+ """Den Ausfuellschlitz des Quell-Overlays einmal durch die Globmenge ersetzen."""
50
+ quelle, _, _ = _59_pfade(root)
51
+ schreib(quelle, ersetzt(lies(quelle),
52
+ (P59_SCHLITZ, ", ".join("`%s`" % g for g in P59_QUELLGLOBS)),
53
+ quelle=".koolie/project-overlay/OVERLAY.md"))
54
+
55
+
56
+ def _59_fuellen(root: str, globs: list, im_korb: list = None) -> None:
57
+ """Laufzeitfassung und deny-Korb auf eine Globmenge stellen - mehrfach aufrufbar.
58
+
59
+ Die Quelle bleibt unberuehrt: Ihr Ausfuellschlitz gibt es nur einmal, und eine
60
+ Praeparation, die ihn ein zweites Mal sucht, bricht ab. Das ist am 2026-09-18
61
+ zugeschnappt.
62
+ """
63
+ _, laufzeit, korb = _59_pfade(root)
64
+ text = lies(laufzeit)
65
+ treffer = [z for z in text.split("\n") if "<EXCLUDED_PATHS>" in z]
66
+ if len(treffer) != 1:
67
+ raise Praeparationsfehler(
68
+ "Die Laufzeitfassung nennt <EXCLUDED_PATHS> %dx statt 1x - die Sonden zu 59 "
69
+ "haetten keinen Anker" % len(treffer))
70
+ neu = treffer[0].split(":")[0] + ": " + ", ".join("`%s`" % g for g in globs)
71
+ schreib(laufzeit, text.replace(treffer[0], neu))
72
+ cfg = json.loads(lies(korb))
73
+ # Der Korb wird aus dem UNBERUEHRTEN Stand neu aufgebaut, nicht aus dem der
74
+ # vorigen Sonde: Ein Baum, der mehrere Laeufe traegt, ist nach dem ersten
75
+ # Schreiblauf nicht mehr der Ausgangszustand. Ohne diesen Merker stand ein Glob
76
+ # der vorigen Sonde noch im Korb, und 59c mass nichts - zugeschnappt am 2026-09-18.
77
+ urstand = _59_KORBSTAND.setdefault(
78
+ korb, [r for r in cfg["permissions"]["deny"] if "<EXCLUDED_PATHS>" not in r])
79
+ deny = list(urstand)
80
+ for g in (P59_QUELLGLOBS if im_korb is None else im_korb):
81
+ deny += ["Read(%s)" % g, "Edit(%s)" % g]
82
+ cfg["permissions"]["deny"] = deny
83
+ schreib(korb, json.dumps(cfg, ensure_ascii=False, indent=2))
84
+
85
+
86
+ def sonden_overlay_wertabgleich() -> None:
87
+ """Wirkungsnachweis fuer Pruefung 59 an einer gefuellten claude-code-Installation."""
88
+ root = installation("claude-code")
89
+ try:
90
+ # --- Gegenprobe: alle drei Schichten tragen denselben Wert ------------------
91
+ _59_quelle_fuellen(root)
92
+ _59_fuellen(root, P59_QUELLGLOBS)
93
+ aus = strict_ausgabe(root)
94
+ for nummer, marke, satz in (
95
+ ("59a", M59_BINDUNG, "Die Laufzeitfassung bindet den Platzhalter"),
96
+ ("59b", M59_WERT, "Ihre Globmenge ist die der Quelle"),
97
+ ("59c", M59_KORB, "Der deny-Korb fuehrt jeden Glob zweimal")):
98
+ melde("GEGENPROBE", nummer, marke not in aus,
99
+ "Ein vollstaendig nachgezogener Baum bleibt unbeanstandet - %s" % satz)
100
+
101
+ # --- Sonde 59b: derselbe Platzhalter, ein anderer Wert ---------------------
102
+ # Vor 59a, weil 59a den Platzhalter aus der Laufzeitfassung entfernt und
103
+ # _59_fuellen ihn danach als Anker nicht mehr faende.
104
+ _59_fuellen(root, ["deploy/**", "infra/gen/**"])
105
+ melde("SONDE", "59b", M59_WERT in strict_ausgabe(root),
106
+ "Die Laufzeitfassung traegt einen Glob, den die Quelle nicht kennt - genau "
107
+ "die Drift, die eine Einengung aus 0.63.0 nie erreicht hat")
108
+
109
+ # --- Sonde 59c: der deny-Korb fuehrt einen Glob der Quelle nicht ------------
110
+ _59_fuellen(root, P59_QUELLGLOBS, im_korb=["deploy/**"])
111
+ melde("SONDE", "59c", M59_KORB in strict_ausgabe(root),
112
+ "Ein ausgeschlossener Pfad der Quelle hat keine Regel im deny-Korb - die "
113
+ "Schicht, die technisch sperrt, kennt ihn nicht")
114
+
115
+ # --- Sonde 59a: die Laufzeitfassung ERSETZT statt zu BINDEN -----------------
116
+ _59_fuellen(root, P59_QUELLGLOBS)
117
+ _, laufzeit, _ = _59_pfade(root)
118
+ schreib(laufzeit, lies(laufzeit).replace("(`<EXCLUDED_PATHS>`)", "").replace(
119
+ "<EXCLUDED_PATHS>", "die Liste unten"))
120
+ melde("SONDE", "59a", M59_BINDUNG in strict_ausgabe(root),
121
+ "Die Laufzeitfassung setzt den Wert ein, statt den Platzhalter zu binden - "
122
+ "niemand sieht dann, ob ihr Wert noch der der Quelle ist")
123
+ finally:
124
+ aufraeumen(os.path.dirname(root))
125
+
126
+
127
+ buendel(sonden_overlay_wertabgleich,
128
+ "Pruefung 59 an einer gefuellten claude-code-Installation: Bindung, Wert und "
129
+ "deny-Korb je eigens gemessen, dazu die Gegenprobe des nachgezogenen Baums")
130
+
131
+
132
+ # --- Pruefung 89: die uebrigen Pfadplatzhalter (K-69, D-357) ----------------------
133
+ #
134
+ # Dieselbe Bauform wie das Buendel zu 59: eine GEFUELLTE claude-code-Installation, je
135
+ # Gegenstand eine Sonde, und die Gegenprobe des vollstaendig nachgezogenen Baums ist der
136
+ # eigentliche Nachweis. Jede Einheit baut die drei Traeger aus dem UNBERUEHRTEN Stand
137
+ # neu auf (_89_URSTAND) - ein Baum, der mehrere Laeufe traegt, ist nach dem ersten
138
+ # Schreiblauf nicht mehr der Ausgangszustand (dieselbe Falle wie 59c am 2026-09-18).
139
+ # 89 (Gegenprobe) - alle vier Werte in Quelle, Laufzeitfassung und Korb gleich
140
+ # 89k (Gegenprobe) - "kein Wert" in zwei Schreibweisen: `nicht vorhanden` in der
141
+ # Quelle, `keine` in der Laufzeitfassung - gemessen am Piloten
142
+ # 89a (Sonde) - die Laufzeitfassung ersetzt <ALLOWED_PATHS>, statt zu binden
143
+ # 89b (Sonde) - <TEST_PATHS> traegt in der Laufzeitfassung einen anderen Wert
144
+ # 89c (Sonde) - ein Nur-Lese-Pfad fehlt im deny-Korb
145
+ # 89d (Sonde) - die Quelle bindet <DOC_PATHS> nicht in der dreispaltigen Zeile
146
+ M89_BINDUNG = "nennt <ALLOWED_PATHS> nicht"
147
+ M89_WERT = "der Wert von <TEST_PATHS> weicht vom Quell-Overlay ab"
148
+ M89_KORB = "hat keine Regel Edit(api-contracts/**)"
149
+ M89_QUELLE = "keine Zeile mit der Platzhalterzelle `<DOC_PATHS>`"
150
+ M89_ALLE = ("nennt <", "weicht vom Quell-Overlay ab", "Nur-Lese-Pfad",
151
+ "keine Zeile mit der Platzhalterzelle")
152
+ P89_WERTE = {"<ALLOWED_PATHS>": ["src/**", "test/**", "docs/**"],
153
+ "<TEST_PATHS>": ["test/**"],
154
+ "<DOC_PATHS>": ["docs/**"],
155
+ "<READ_ONLY_PATHS>": ["api-contracts/**", "db/migrations/**"]}
156
+ _89_URSTAND: dict = {}
157
+
158
+
159
+ def _89_pfade(root: str) -> tuple:
160
+ return (os.path.join(root, ".koolie/project-overlay", "OVERLAY.md"),
161
+ os.path.join(root, ".claude", "rules", "20-project-overlay.md"),
162
+ os.path.join(root, ".claude", "settings.json"))
163
+
164
+
165
+ def _89_fuellen(root: str, quelle: dict, laufzeit: dict, korb: list) -> None:
166
+ """Quelle, Laufzeitfassung und deny-Korb aus dem Urstand auf die Werte stellen.
167
+
168
+ quelle und laufzeit bilden den Platzhalter auf den eingesetzten TEXT ab (fertig mit
169
+ Codespannen); korb nennt die Nur-Lese-Globs, die eine Schreibsperre bekommen. Jeder
170
+ Ausfuellschlitz muss genau einmal getroffen werden, sonst bricht die Praeparation ab.
171
+ """
172
+ for pfad in _89_pfade(root):
173
+ _89_URSTAND.setdefault(pfad, lies(pfad))
174
+ q_pfad, l_pfad, k_pfad = _89_pfade(root)
175
+ text = _89_URSTAND[q_pfad]
176
+ for platzhalter, ersatz in quelle.items():
177
+ text, n = re.subn(r"(\| `%s` \| )`<TBD[^`]*>`" % re.escape(platzhalter),
178
+ lambda m: m.group(1) + ersatz, text)
179
+ if n != 1:
180
+ raise Praeparationsfehler("OVERLAY.md: Wertzeile von %s %dx statt 1x"
181
+ % (platzhalter, n))
182
+ schreib(q_pfad, text)
183
+ text = _89_URSTAND[l_pfad]
184
+ for platzhalter, ersatz in laufzeit.items():
185
+ text, n = re.subn(r"(\(`%s`\): )`<TBD[^`]*>`" % re.escape(platzhalter),
186
+ lambda m: m.group(1) + ersatz, text)
187
+ if n != 1:
188
+ raise Praeparationsfehler("20-project-overlay.md: Schlitz von %s %dx statt 1x"
189
+ % (platzhalter, n))
190
+ schreib(l_pfad, text)
191
+ cfg = json.loads(_89_URSTAND[k_pfad])
192
+ deny = [r for r in cfg["permissions"]["deny"] if "<READ_ONLY_PATHS>" not in r]
193
+ if len(deny) != len(cfg["permissions"]["deny"]) - 1:
194
+ raise Praeparationsfehler("settings.json: der Schlitz Edit(<READ_ONLY_PATHS>) steht "
195
+ "nicht genau einmal im deny-Korb (D-356)")
196
+ cfg["permissions"]["deny"] = deny + ["Edit(%s)" % g for g in korb]
197
+ schreib(k_pfad, json.dumps(cfg, ensure_ascii=False, indent=2))
198
+
199
+
200
+ def _89_spannen(werte: list) -> str:
201
+ return ", ".join("`%s`" % w for w in werte)
202
+
203
+
204
+ def _89_voll() -> tuple:
205
+ werte = {p: _89_spannen(w) for p, w in P89_WERTE.items()}
206
+ return werte, dict(werte), list(P89_WERTE["<READ_ONLY_PATHS>"])
207
+
208
+
209
+ def sonden_overlay_pfadabgleich() -> None:
210
+ """Wirkungsnachweis fuer Pruefung 89 an einer gefuellten claude-code-Installation."""
211
+ root = installation("claude-code")
212
+ try:
213
+ # --- Gegenprobe 89: alle drei Schichten tragen dieselben vier Werte ---------
214
+ _89_fuellen(root, *_89_voll())
215
+ aus = strict_ausgabe(root)
216
+ treffer = [m for m in M89_ALLE if m in aus]
217
+ melde("GEGENPROBE", "89", not treffer,
218
+ "Ein vollstaendig nachgezogener Baum bleibt unbeanstandet - vier Werte in "
219
+ "Quelle, Laufzeitfassung und deny-Korb gleich")
220
+ if treffer:
221
+ notiz(" gemeldet: %s" % ", ".join(treffer))
222
+
223
+ # --- Gegenprobe 89k: zwei Schreibweisen fuer "kein Wert" -------------------
224
+ quelle, laufzeit, korb = _89_voll()
225
+ quelle["<DOC_PATHS>"] = "`nicht vorhanden`"
226
+ laufzeit["<DOC_PATHS>"] = "keine"
227
+ _89_fuellen(root, quelle, laufzeit, korb)
228
+ melde("GEGENPROBE", "89k", "<DOC_PATHS>" not in strict_ausgabe(root),
229
+ "Kein Wert in zwei Schreibweisen - nicht vorhanden in der Quelle, keine in "
230
+ "der Laufzeitfassung - ist dieselbe leere Menge")
231
+
232
+ # --- Sonde 89a: die Laufzeitfassung ersetzt statt zu binden -----------------
233
+ _89_fuellen(root, *_89_voll())
234
+ _, l_pfad, _ = _89_pfade(root)
235
+ schreib(l_pfad, ersetzt(lies(l_pfad), (" (`<ALLOWED_PATHS>`)", ""),
236
+ quelle="20-project-overlay.md"))
237
+ melde("SONDE", "89a", M89_BINDUNG in strict_ausgabe(root),
238
+ "Die Laufzeitfassung setzt die erlaubten Pfade ein, statt den Platzhalter zu "
239
+ "binden - ihr Wert ist dann gegen nichts mehr gehalten")
240
+
241
+ # --- Sonde 89b: ein anderer Wert in der Laufzeitfassung --------------------
242
+ quelle, laufzeit, korb = _89_voll()
243
+ laufzeit["<TEST_PATHS>"] = "`test/**`, `src/**`"
244
+ _89_fuellen(root, quelle, laufzeit, korb)
245
+ melde("SONDE", "89b", M89_WERT in strict_ausgabe(root),
246
+ "Die Laufzeitfassung erlaubt Schreiben in M4 auf einem Pfad, den die Quelle "
247
+ "nicht nennt - genau die Drift aus K-69")
248
+
249
+ # --- Sonde 89c: ein Nur-Lese-Pfad ohne Schreibsperre -----------------------
250
+ quelle, laufzeit, _ = _89_voll()
251
+ _89_fuellen(root, quelle, laufzeit, ["db/migrations/**"])
252
+ melde("SONDE", "89c", M89_KORB in strict_ausgabe(root),
253
+ "Ein Nur-Lese-Pfad der Quelle hat keine Schreibsperre im deny-Korb - der "
254
+ "Integritaetsschutz steht nur im Overlay")
255
+
256
+ # --- Sonde 89d: die Quelle bindet anders ------------------------------------
257
+ _89_fuellen(root, *_89_voll())
258
+ q_pfad, _, _ = _89_pfade(root)
259
+ schreib(q_pfad, ersetzt(lies(q_pfad), ("| `<DOC_PATHS>` |", "| DOC_PATHS |"),
260
+ quelle="OVERLAY.md"))
261
+ melde("SONDE", "89d", M89_QUELLE in strict_ausgabe(root),
262
+ "Ein Overlay, das einen Pfadplatzhalter nicht in der dreispaltigen Zeile "
263
+ "bindet, wird gemeldet und nicht still uebergangen")
264
+ finally:
265
+ aufraeumen(os.path.dirname(root))
266
+
267
+
268
+ buendel(sonden_overlay_pfadabgleich,
269
+ "Pruefung 89 an einer gefuellten claude-code-Installation: Bindung, Wert, deny-Korb "
270
+ "und Lesbarkeit der Quelle, dazu zwei Gegenproben")
271
+
272
+
273
+ # --- D-355: das Overlay-Muster und der Fuellschritt --------------------------------
274
+ #
275
+ # ANLASS (CR-2026-136, 2.3; CR-2026-138). Ein Muster, das nur OVERLAY.md vorbefuellt,
276
+ # sperrt nichts: Read(<EXCLUDED_PATHS>) stand danach woertlich im deny-Korb. Diese
277
+ # Einheiten messen den Fuellschritt an einer echten Erstinstallation - und die vier
278
+ # Stellen, an denen er sich verweigern MUSS.
279
+ # M355 (Sonde) - --overlay general fuellt Overlay, Laufzeitfassung und deny-Korb
280
+ # aus derselben Tabelle; Pruefung 59 schweigt. Gegen install.py
281
+ # aus 1.4.4 faellt sie (die Option gibt es dort nicht)
282
+ # M355a (Gegenprobe) - ohne --overlay bleibt alles wie vorher: der Schlitz steht
283
+ # woertlich im Korb, dazu seit D-356 der Nur-Lese-Schlitz
284
+ # M355b (Sonde) - ein Overlay aus dem Muster ist NICHT aktivierungsreif (D-57)
285
+ # M355c (Sonde) - vorhandene Saat: Abbruch, nichts ueberschrieben
286
+ # M355d (Sonde) - ein Muster, das einen freigebenden Platzhalter fuellt: Abbruch
287
+ # vor dem ersten Schreibvorgang
288
+ # M355e (Sonde) - --overlay mit --update und ein unbekannter Name: Abbruch
289
+ M355_MUSTER = os.path.join(".koolie", "core", "framework", "overlay-patterns", "general.md")
290
+ M355_59 = ("nennt <EXCLUDED_PATHS> nicht", "weichen vom Quell-Overlay ab",
291
+ "der ausgeschlossene Pfad")
292
+
293
+
294
+ def _355_install(ziel: str, *argumente) -> subprocess.CompletedProcess:
295
+ return unterprozess([sys.executable, os.path.join(QUELLE, ".koolie/core", "install.py"),
296
+ "--client", "claude-code", "--root", ziel] + list(argumente))
297
+
298
+
299
+ # M359 (Sonde) - die Dokumente des Musters: angelegt, mit Vermerk, im Manifest
300
+ # als K1/entwurf/on-demand registriert, die Beispiele der Vorlage
301
+ # ersetzt, die K1-Liste der Laufzeitfassung offen (D-359, D-360)
302
+ # M359a (Sonde) - Ablage und Beschreibung laufen auseinander: Abbruch vor dem
303
+ # ersten Schreibvorgang
304
+ # M359b (Sonde) - ein Dokument ohne Vorschlagsvermerk: Abbruch
305
+ # M359c (Gegenprobe) - ohne --overlay bleibt die Manifestvorlage mit ihren drei
306
+ # Beispielen, und kein Musterdokument liegt im Projekt
307
+ M359_VERMERK = "Muster – vom Overlay Owner zu prüfen und anzupassen."
308
+
309
+
310
+ def _359_dokumente() -> list:
311
+ """Die Dokumente des Musters, gelesen mit dem Werkzeug selbst - nicht nachgepflegt."""
312
+ sys.path.insert(0, os.path.join(QUELLE, ".koolie", "core"))
313
+ try:
314
+ import install as _install # noqa: E402
315
+ return _install.muster_laden("general")["dokumente"]
316
+ finally:
317
+ sys.path.pop(0)
318
+
319
+
320
+ def _359_kern(basis: str, name: str) -> str:
321
+ """Eine Kopie des Kerns, deren install.py das Muster aus IHREM Kern liest."""
322
+ kern = os.path.join(basis, name, ".koolie", "core")
323
+ shutil.copytree(os.path.join(QUELLE, ".koolie/core"), kern,
324
+ ignore=shutil.ignore_patterns(".git", "__pycache__", "out"))
325
+ return kern
326
+
327
+
328
+ def _355_werte() -> dict:
329
+ """Die Werte des Musters, gelesen mit dem Werkzeug selbst - nicht nachgepflegt."""
330
+ sys.path.insert(0, os.path.join(QUELLE, ".koolie", "core"))
331
+ try:
332
+ import install as _install # noqa: E402
333
+ return _install.muster_laden("general")["werte"]
334
+ finally:
335
+ sys.path.pop(0)
336
+
337
+
338
+ def sonden_overlay_muster() -> None:
339
+ """Wirkungsnachweis fuer --overlay general, seine Dokumente und seine sechs Verweigerungen."""
340
+ basis = tempfile.mkdtemp(prefix="lw-muster-")
341
+ try:
342
+ werte = _355_werte()
343
+ # --- M355: die Fuellung ---------------------------------------------------
344
+ root = os.path.join(basis, "mit")
345
+ os.makedirs(root)
346
+ p = _355_install(root, "--overlay", "general")
347
+ deny = json.loads(lies(os.path.join(root, ".claude", "settings.json")))[
348
+ "permissions"]["deny"]
349
+ fehlt = []
350
+ for platzhalter, liste in werte.items():
351
+ if any(platzhalter in r for r in deny):
352
+ fehlt.append("%s noch als Schlitz" % platzhalter)
353
+ for w in liste:
354
+ if not any(r in deny for r in ("Edit(%s)" % w, "Edit(./%s)" % w)):
355
+ fehlt.append("Edit(%s)" % w)
356
+ for w in werte["<EXCLUDED_PATHS>"]:
357
+ if "Read(%s)" % w not in deny and "Read(./%s)" % w not in deny:
358
+ fehlt.append("Read(%s)" % w)
359
+ laufzeit = lies(os.path.join(root, ".claude", "rules", "20-project-overlay.md"))
360
+ if "(`<EXCLUDED_PATHS>`): " + ", ".join(
361
+ "`%s`" % w for w in werte["<EXCLUDED_PATHS>"]) not in laufzeit:
362
+ fehlt.append("Laufzeitfassung")
363
+ overlay = lies(os.path.join(root, ".koolie", "project-overlay", "OVERLAY.md"))
364
+ for platzhalter, liste in werte.items():
365
+ if "| `%s` | %s |" % (platzhalter, ", ".join("`%s`" % w for w in liste)) \
366
+ not in overlay:
367
+ fehlt.append("OVERLAY.md %s" % platzhalter)
368
+ if "Overlay angelegt aus dem Muster `general`" not in overlay:
369
+ fehlt.append("Aenderungsverlauf")
370
+ shutil.copytree(os.path.join(QUELLE, ".koolie/core"),
371
+ os.path.join(root, ".koolie/core"),
372
+ ignore=shutil.ignore_patterns(".git", "__pycache__", "out"))
373
+ aus59 = [m for m in M355_59 if m in strict_ausgabe(root)]
374
+ melde("SONDE", "M355", p.returncode == 0 and not fehlt and not aus59,
375
+ "Das Muster fuellt Overlay, Laufzeitfassung und deny-Korb aus einer Tabelle, "
376
+ "und Pruefung 59 findet keine Abweichung")
377
+ if p.returncode != 0 or fehlt or aus59:
378
+ notiz(" Exit %d; fehlt: %s; Pruefung 59: %s"
379
+ % (p.returncode, ", ".join(fehlt) or "nichts", ", ".join(aus59) or "still"))
380
+
381
+ # --- M359: die Dokumente des Musters (D-359, D-360) ---------------------------
382
+ dokumente = _359_dokumente()
383
+ fehlt = []
384
+ manifest = lies(os.path.join(root, ".koolie", "project-overlay",
385
+ "overlay-manifest.yaml"))
386
+ for dok in dokumente:
387
+ ziel = os.path.join(root, ".koolie", "project-overlay", "documents",
388
+ dok["typ"], dok["datei"])
389
+ if not os.path.isfile(ziel):
390
+ fehlt.append("%s/%s fehlt" % (dok["typ"], dok["datei"]))
391
+ elif M359_VERMERK not in lies(ziel):
392
+ fehlt.append("%s ohne Vermerk" % dok["typ"])
393
+ eintrag = 'path: ".koolie/project-overlay/documents/%s/%s"' % (
394
+ dok["typ"], dok["datei"])
395
+ if eintrag not in manifest:
396
+ fehlt.append("%s nicht registriert" % dok["typ"])
397
+ for erwartet in ('status: "entwurf"', 'load: "on-demand"', 'context_class: "K1"'):
398
+ if manifest.count(erwartet) != len(dokumente):
399
+ fehlt.append("%s %dx statt %dx" % (erwartet, manifest.count(erwartet),
400
+ len(dokumente)))
401
+ if manifest.count('- id: "DOC-') != len(dokumente):
402
+ fehlt.append("%d Eintraege statt %d - ein Beispiel der Vorlage steht noch"
403
+ % (manifest.count('- id: "DOC-'), len(dokumente)))
404
+ if "- Dokumente der Klasse K1 (frei nutzbar): `<TBD" not in laufzeit:
405
+ fehlt.append("K1-Liste der Laufzeitfassung gefuellt")
406
+ if "Musterdokumente unter `documents/`" not in overlay:
407
+ fehlt.append("Aenderungsverlauf ohne Dokumente")
408
+ aus8 = [z for z in validator_ausgabe(root).splitlines()
409
+ if z.startswith("FEHLER") and "overlay-manifest.yaml" in z]
410
+ melde("SONDE", "M359", p.returncode == 0 and len(dokumente) == 6 and not fehlt
411
+ and not aus8,
412
+ "Das Muster legt seine sechs Dokumente an, registriert sie als Entwurf und "
413
+ "gibt keines frei; Pruefung 8 bleibt still")
414
+ if fehlt or aus8 or len(dokumente) != 6:
415
+ notiz(" %d Dokumente; fehlt: %s; Pruefung 8: %s"
416
+ % (len(dokumente), ", ".join(fehlt) or "nichts",
417
+ " | ".join(aus8) or "still"))
418
+
419
+ # --- M355b: nicht aktivierungsreif -----------------------------------------
420
+ q = unterprozess([sys.executable, os.path.join(root, *VALIDATOR.split("/")),
421
+ "--root", root, "--check-overlay-ready"])
422
+ reif = (q.stdout or "") + (q.stderr or "")
423
+ melde("SONDE", "M355b", q.returncode != 0 and "offene <TBD>-Werte" in reif,
424
+ "Ein Overlay aus dem Muster besteht die Pruefung der Aktivierungsreife nicht - "
425
+ "es laesst die Pflichtwerte offen (D-57)")
426
+
427
+ # --- M355c: vorhandene Saat -------------------------------------------------
428
+ vorher = lies(os.path.join(root, ".claude", "settings.json"))
429
+ c = _355_install(root, "--overlay", "general")
430
+ melde("SONDE", "M355c", c.returncode == 1 and "hier liegt sie schon" in
431
+ (c.stderr or "") and lies(os.path.join(root, ".claude", "settings.json"))
432
+ == vorher,
433
+ "Liegt die Saat schon, bricht das Muster ab und ueberschreibt nichts - "
434
+ "vorhandene Saat gehoert dem Projekt")
435
+
436
+ # --- M355e: --update und unbekannter Name ----------------------------------
437
+ u = _355_install(root, "--overlay", "general", "--update")
438
+ leer = os.path.join(basis, "unbekannt")
439
+ os.makedirs(leer)
440
+ n = _355_install(leer, "--overlay", "gibt-es-nicht")
441
+ melde("SONDE", "M355e", u.returncode == 1 and "nur bei der Erstinstallation"
442
+ in (u.stderr or "") and n.returncode == 1 and not os.listdir(leer),
443
+ "Das Muster verweigert sich bei --update und bei einem unbekannten Namen, "
444
+ "ohne eine Datei zu schreiben")
445
+
446
+ # --- M355a: ohne --overlay unveraendert -------------------------------------
447
+ ohne = os.path.join(basis, "ohne")
448
+ os.makedirs(ohne)
449
+ o = _355_install(ohne)
450
+ deny = json.loads(lies(os.path.join(ohne, ".claude", "settings.json")))[
451
+ "permissions"]["deny"]
452
+ erwartet = ["Read(<EXCLUDED_PATHS>)", "Edit(<CI_CONFIG_PATHS>)",
453
+ "Edit(<QUALITY_GATE_CONFIG_PATHS>)", "Edit(<READ_ONLY_PATHS>)"]
454
+ melde("GEGENPROBE", "M355a", o.returncode == 0 and all(r in deny for r in erwartet),
455
+ "Ohne Muster bleibt jeder Pfadschlitz woertlich stehen, dazu der Schlitz fuer "
456
+ "die Nur-Lese-Pfade aus D-356")
457
+
458
+ # --- M355d: ein Muster, das freigibt ----------------------------------------
459
+ # Gemessen am eigenen Werkzeug einer Kopie: Deren install.py liest das Muster
460
+ # aus IHREM Kern - die Quelle bleibt unberuehrt.
461
+ kopie_kern = os.path.join(basis, "kern", ".koolie", "core")
462
+ shutil.copytree(os.path.join(QUELLE, ".koolie/core"), kopie_kern,
463
+ ignore=shutil.ignore_patterns(".git", "__pycache__", "out"))
464
+ muster = os.path.join(basis, "kern", M355_MUSTER)
465
+ text = lies(muster)
466
+ anker = "| `<EXCLUDED_PATHS>` |"
467
+ if text.count(anker) != 1:
468
+ raise Praeparationsfehler("general.md: Zeile %s %dx statt 1x"
469
+ % (anker, text.count(anker)))
470
+ schreib(muster, text.replace(anker, "| `<ALLOWED_PATHS>` | `**` | Sonde |\r\n"
471
+ + anker, 1))
472
+ frei = os.path.join(basis, "frei")
473
+ os.makedirs(frei)
474
+ d = unterprozess([sys.executable, os.path.join(kopie_kern, "install.py"),
475
+ "--client", "claude-code", "--root", frei,
476
+ "--overlay", "general"])
477
+ melde("SONDE", "M355d", d.returncode == 1 and "darf nur sperren" in (d.stderr or "")
478
+ and not os.listdir(frei),
479
+ "Ein Muster, das erlaubte Pfade fuellen will, bricht die Installation ab, "
480
+ "bevor die erste Datei geschrieben ist")
481
+
482
+ # --- M359a: Ablage und Beschreibung laufen auseinander -----------------------
483
+ kern_a = _359_kern(basis, "kern-a")
484
+ weg = os.path.join(kern_a, "framework", "overlay-patterns", "general", "documents",
485
+ "security")
486
+ if not os.path.isdir(weg):
487
+ raise Praeparationsfehler("general/documents/security fehlt - M359a haette "
488
+ "nichts zu entfernen")
489
+ shutil.rmtree(weg)
490
+ ziel_a = os.path.join(basis, "ziel-a")
491
+ os.makedirs(ziel_a)
492
+ a = unterprozess([sys.executable, os.path.join(kern_a, "install.py"),
493
+ "--client", "claude-code", "--root", ziel_a, "--overlay", "general"])
494
+ melde("SONDE", "M359a", a.returncode == 1 and "stimmen nicht ueberein" in
495
+ (a.stderr or "") and not os.listdir(ziel_a),
496
+ "Fehlt ein beschriebenes Musterdokument in der Ablage, bricht die Installation "
497
+ "ab, bevor die erste Datei geschrieben ist")
498
+
499
+ # --- M359b: ein Dokument ohne Vorschlagsvermerk ------------------------------
500
+ kern_b = _359_kern(basis, "kern-b")
501
+ dok = os.path.join(kern_b, "framework", "overlay-patterns", "general", "documents",
502
+ "quality", "muster-general.md")
503
+ text = lies(dok)
504
+ if text.count(M359_VERMERK) != 1:
505
+ raise Praeparationsfehler("quality/muster-general.md fuehrt den Vermerk %dx "
506
+ "statt 1x" % text.count(M359_VERMERK))
507
+ schreib(dok, text.replace(M359_VERMERK, "Allgemeine Grundsaetze.", 1))
508
+ ziel_b = os.path.join(basis, "ziel-b")
509
+ os.makedirs(ziel_b)
510
+ b = unterprozess([sys.executable, os.path.join(kern_b, "install.py"),
511
+ "--client", "claude-code", "--root", ziel_b, "--overlay", "general"])
512
+ melde("SONDE", "M359b", b.returncode == 1 and "nicht den Vermerk" in (b.stderr or "")
513
+ and not os.listdir(ziel_b),
514
+ "Ein Musterdokument ohne Vorschlagsvermerk bricht die Installation ab - ein "
515
+ "ungeprueft mitgelieferter Text darf nicht wie eine Projektvorgabe aussehen")
516
+
517
+ # --- M359c: ohne --overlay ---------------------------------------------------
518
+ manifest_ohne = lies(os.path.join(ohne, ".koolie", "project-overlay",
519
+ "overlay-manifest.yaml"))
520
+ musterdoks = glob.glob(os.path.join(ohne, ".koolie", "project-overlay", "documents",
521
+ "*", "muster-general.md"))
522
+ melde("GEGENPROBE", "M359c", manifest_ohne.count('- id: "DOC-') == 3
523
+ and not musterdoks,
524
+ "Ohne Muster bleibt die Manifestvorlage mit ihren drei Beispielen, und kein "
525
+ "Musterdokument liegt im Projekt")
526
+ finally:
527
+ aufraeumen(basis)
528
+
529
+
530
+ buendel(sonden_overlay_muster,
531
+ "Der Fuellschritt aus --overlay general an echten Erstinstallationen, dazu seine "
532
+ "Dokumente, sechs Verweigerungen und der unveraenderte Weg ohne Muster")
533
+
534
+
535
+ # --- D-362: der Kopierweg in ein Projekt, der Dialog und die Starter (CR-2026-140) ---
536
+ #
537
+ # `install.py --target` kopiert NUR den Kern in ein Projekt und ruft danach das kopierte
538
+ # install.py dort auf. Die Sonden fahren es an echten Verzeichnissen, aus BEIDEN
539
+ # Quellformen: einer Kopie ohne Git (so liegt ein entpacktes Release-Archiv da) und
540
+ # einem Klon, aus dem nur Verfolgtes kommen darf (D-333).
541
+ # T362 (Sonde) - Erstinstallation aus der Archivform: der Kern vollstaendig, ohne
542
+ # Bytecode und build/out, ohne Kennzeichen und ohne das Overlay der
543
+ # Quelle (D-354), Wurzeldateien angelegt
544
+ # T362a (Sonde) - ein zweiter Aufruf ohne --update haelt an und veraendert nichts
545
+ # T362b (Sonde) - --update hebt: Stand der Quelle, Altlast weg, Overlay unberuehrt,
546
+ # keine Zwischenverzeichnisse
547
+ # T362c (Sonde) - scheitert die Installation im Projekt (Kollision), ist der kopierte
548
+ # Kern wieder weg und die Projektdatei unveraendert
549
+ # T362d (Sonde) - --update ohne vorhandenen Kern haelt an, ohne zu schreiben
550
+ # T362e (Sonde) - Quelle und Ziel dasselbe Verzeichnis: Abbruch
551
+ # T362f (Sonde) - aus einem Klon kommt eine unverfolgte Datei des Kerns NICHT mit
552
+ # T362g (Sonde) - der Dialog sammelt die Angaben ein und installiert
553
+ # T362h (Sonde) - der Dialog bricht mit q ab und schreibt nichts
554
+ # T363 (Sonde) - die Mindestversion steht in install.py und beiden Startern gleich
555
+ # T365 (Sonde) - install.cmd traegt keine Sprungmarke (LF im Archiv), und
556
+ # install.command ist im Repositorium ausfuehrbar (100755)
557
+ T362_ANTWORTEN = "%s\n1\n1\n1\nj\n"
558
+
559
+
560
+ def _362_lauf(kern: str, *argv: str, eingabe=None, werkzeug: str = "install.py"):
561
+ return unterprozess([sys.executable, os.path.join(kern, werkzeug), *argv],
562
+ input=eingabe)
563
+
564
+
565
+ def _362_kerndateien(kern: str) -> set:
566
+ out = set()
567
+ for dirpath, dirnames, filenames in os.walk(kern):
568
+ dirnames[:] = [d for d in dirnames if d != "__pycache__"]
569
+ for fn in filenames:
570
+ out.add(os.path.relpath(os.path.join(dirpath, fn), kern).replace(os.sep, "/"))
571
+ return out
572
+
573
+
574
+ def sonden_kopierweg() -> None:
575
+ """Wirkungsnachweis fuer install.py --target, den Dialog und die Starter (D-362)."""
576
+ basis = tempfile.mkdtemp(prefix="lw-kopierweg-")
577
+ quelle = kopie()
578
+ try:
579
+ qkern = os.path.join(quelle, ".koolie", "core")
580
+ # Erzeugnisse, die ein Lauf in einem entpackten Archiv hinterlaesst - sie
581
+ # duerfen nicht mitkommen.
582
+ os.makedirs(os.path.join(qkern, "__pycache__"), exist_ok=True)
583
+ schreib(os.path.join(qkern, "__pycache__", "sonde.cpython-38.pyc"), "x")
584
+ os.makedirs(os.path.join(qkern, "build", "out"), exist_ok=True)
585
+ schreib(os.path.join(qkern, "build", "out", "sonde.docx"), "x")
586
+ # Seit 1.8.0 schreibt --target die Wahl des Lieferumfangs in den Kern (D-367).
587
+ erwartet = {r for r in _362_kerndateien(qkern) if not r.startswith("build/out/")}
588
+ erwartet.add("LIEFERUMFANG")
589
+
590
+ # --- T362: Erstinstallation aus der Archivform -------------------------------
591
+ erst = os.path.join(basis, "erst")
592
+ os.makedirs(erst)
593
+ p = _362_lauf(qkern, "--target", erst, "--client", "claude-code")
594
+ zkern = os.path.join(erst, ".koolie", "core")
595
+ ist = _362_kerndateien(zkern)
596
+ qoverlay = os.path.join(quelle, ".koolie", "project-overlay", "OVERLAY.md")
597
+ zoverlay = os.path.join(erst, ".koolie", "project-overlay", "OVERLAY.md")
598
+ fehlt = []
599
+ if ist != erwartet:
600
+ fehlt.append("Kern: %d zu viel, %d fehlen"
601
+ % (len(ist - erwartet), len(erwartet - ist)))
602
+ if os.path.exists(os.path.join(erst, ".koolie", "QUELLREPOSITORIUM.md")):
603
+ fehlt.append("Kennzeichen mitkopiert")
604
+ if _367_umfang(erst) != "voll":
605
+ fehlt.append("LIEFERUMFANG " + _367_umfang(erst))
606
+ if not os.path.isfile(zoverlay):
607
+ fehlt.append("kein Overlay")
608
+ elif os.path.isfile(qoverlay) and lies(qoverlay) == lies(zoverlay):
609
+ fehlt.append("Overlay der Quelle mitkopiert")
610
+ if not os.path.isfile(os.path.join(erst, "CLAUDE.md")):
611
+ fehlt.append("keine Wurzel-Anweisungsdatei")
612
+ melde("SONDE", "T362", p.returncode == 0 and not fehlt,
613
+ "Aus der Archivform kommt der ganze Kern ohne Erzeugnisse, ohne Kennzeichen "
614
+ "und ohne das Overlay der Quelle, und das Projekt ist installiert")
615
+ if p.returncode != 0 or fehlt:
616
+ notiz(" Exit %d; %s" % (p.returncode, "; ".join(fehlt) or "-"))
617
+
618
+ # --- T362a: zweiter Aufruf ohne --update --------------------------------------
619
+ vorher = baumhash(erst)
620
+ p = _362_lauf(qkern, "--target", erst)
621
+ ok = (p.returncode == 1 and "Heben auf diesen Stand: --update" in p.stderr
622
+ and baumhash(erst) == vorher)
623
+ melde("SONDE", "T362a", ok,
624
+ "Ein vorhandener Kern wird ohne --update nicht ersetzt")
625
+ if not ok:
626
+ notiz(" Exit %d, Baum %s" % (p.returncode,
627
+ "unveraendert" if baumhash(erst) == vorher else "VERAENDERT"))
628
+
629
+ # --- T362b: Heben ----------------------------------------------------------
630
+ schreib(os.path.join(zkern, "VERSION"), "0.0.0\n")
631
+ schreib(os.path.join(zkern, "ALTLAST.md"), "# Altlast\n")
632
+ schreib(zoverlay, lies(zoverlay) + "\nPROJEKTZEILE-T362b\n")
633
+ p = _362_lauf(qkern, "--target", erst, "--update")
634
+ fehlt = []
635
+ if lies(os.path.join(zkern, "VERSION")).strip() != \
636
+ lies(os.path.join(qkern, "VERSION")).strip():
637
+ fehlt.append("VERSION nicht gehoben")
638
+ if os.path.exists(os.path.join(zkern, "ALTLAST.md")):
639
+ fehlt.append("Altlast liegt noch")
640
+ if "PROJEKTZEILE-T362b" not in lies(zoverlay):
641
+ fehlt.append("Overlay veraendert")
642
+ for rest in ("core.koolie-neu", "core.koolie-alt"):
643
+ if os.path.exists(os.path.join(erst, ".koolie", rest)):
644
+ fehlt.append(rest + " liegt")
645
+ melde("SONDE", "T362b", p.returncode == 0 and not fehlt,
646
+ "--update ersetzt den Kern als Verzeichnis und laesst das Overlay stehen")
647
+ if p.returncode != 0 or fehlt:
648
+ notiz(" Exit %d; %s" % (p.returncode, "; ".join(fehlt) or "-"))
649
+
650
+ # --- T362c: Rueckbau nach gescheiterter Installation ---------------------------
651
+ kol = os.path.join(basis, "kollision")
652
+ os.makedirs(kol)
653
+ schreib(os.path.join(kol, "CLAUDE.md"), "# Projektdatei\n")
654
+ p = _362_lauf(qkern, "--target", kol, "--client", "claude-code")
655
+ ok = (p.returncode != 0 and not os.path.exists(os.path.join(kol, ".koolie", "core"))
656
+ and lies(os.path.join(kol, "CLAUDE.md")) == "# Projektdatei\n")
657
+ melde("SONDE", "T362c", ok,
658
+ "Scheitert die Installation im Projekt, wird der kopierte Kern wieder entfernt")
659
+ if not ok:
660
+ notiz(" Exit %d, Kern %s" % (p.returncode, "liegt" if os.path.exists(
661
+ os.path.join(kol, ".koolie", "core")) else "entfernt"))
662
+
663
+ # --- T362d: --update ohne Kern ------------------------------------------------
664
+ leer = os.path.join(basis, "leer")
665
+ os.makedirs(leer)
666
+ p = _362_lauf(qkern, "--target", leer, "--update")
667
+ ok = p.returncode == 1 and not os.listdir(leer)
668
+ melde("SONDE", "T362d", ok, "--update ohne vorhandenen Kern haelt an, ohne zu schreiben")
669
+
670
+ # --- T362e: Quelle gleich Ziel ------------------------------------------------
671
+ p = _362_lauf(qkern, "--target", quelle)
672
+ ok = p.returncode == 1 and "Quelle und Ziel sind dasselbe" in p.stderr
673
+ melde("SONDE", "T362e", ok, "Quelle und Ziel duerfen nicht dasselbe Verzeichnis sein")
674
+
675
+ # --- T362f: aus einem Klon nur Verfolgtes --------------------------------------
676
+ klon = kopie()
677
+ try:
678
+ g = unterprozess(["git", "-C", klon, "init", "-q"])
679
+ if g.returncode == 0:
680
+ g = unterprozess(["git", "-C", klon, "add", "-A"])
681
+ if g.returncode != 0:
682
+ raise Praeparationsfehler("git init/add im Klon: " + (g.stderr or "")[:200])
683
+ schreib(os.path.join(klon, ".koolie", "core", "UNVERFOLGT-T362f.md"), "# x\n")
684
+ ziel = os.path.join(basis, "ausklon")
685
+ os.makedirs(ziel)
686
+ p = _362_lauf(os.path.join(klon, ".koolie", "core"), "--target", ziel,
687
+ "--client", "claude-code")
688
+ unverfolgt = os.path.exists(os.path.join(ziel, ".koolie", "core",
689
+ "UNVERFOLGT-T362f.md"))
690
+ ok = p.returncode == 0 and "Klon - nur Verfolgtes" in p.stdout and not unverfolgt
691
+ melde("SONDE", "T362f", ok,
692
+ "Aus einem Klon kommt nur Verfolgtes - eine unverfolgte Datei bleibt draussen")
693
+ if not ok:
694
+ notiz(" Exit %d, Klonweg %s, unverfolgt kopiert %s"
695
+ % (p.returncode, "Klon - nur Verfolgtes" in p.stdout, unverfolgt))
696
+ finally:
697
+ aufraeumen(os.path.dirname(klon))
698
+
699
+ # --- T362g/h: der Dialog --------------------------------------------------------
700
+ dlg = os.path.join(basis, "dialog")
701
+ os.makedirs(dlg)
702
+ p = _362_lauf(qkern, eingabe=T362_ANTWORTEN % dlg, werkzeug="install_dialog.py")
703
+ ok = p.returncode == 0 and os.path.isfile(os.path.join(dlg, ".koolie", "core",
704
+ "install.py"))
705
+ melde("SONDE", "T362g", ok,
706
+ "Der Dialog sammelt Projekt, Client und Muster ein und installiert")
707
+ if not ok:
708
+ notiz(" Exit %d: %s" % (p.returncode, " | ".join(
709
+ (p.stdout + p.stderr).splitlines()[-4:])))
710
+ abb = os.path.join(basis, "abbruch")
711
+ os.makedirs(abb)
712
+ p = _362_lauf(qkern, eingabe="q\n", werkzeug="install_dialog.py")
713
+ ok = p.returncode == 1 and "Nichts installiert" in p.stdout and not os.listdir(abb)
714
+ melde("SONDE", "T362h", ok, "Der Dialog bricht mit q ab und schreibt nichts")
715
+
716
+ # --- T363: die Mindestversion an drei Stellen -----------------------------------
717
+ m = re.search(r"^PYTHON_MINDEST = \((\d+), (\d+)\)",
718
+ lies(os.path.join(QUELLE, ".koolie", "core", "install.py")), re.M)
719
+ if not m:
720
+ raise Praeparationsfehler("PYTHON_MINDEST in install.py nicht gefunden")
721
+ zahl = "sys.version_info >= (%s, %s)" % m.groups()
722
+ text = "Python %s.%s oder neuer" % m.groups()
723
+ abweichend = [s for s in ("install.cmd", "install.command")
724
+ if zahl not in lies(os.path.join(QUELLE, s))
725
+ or text not in lies(os.path.join(QUELLE, s))]
726
+ melde("SONDE", "T363", not abweichend,
727
+ "install.py und beide Starter nennen dieselbe Mindestversion")
728
+ if abweichend:
729
+ notiz(" abweichend: %s (erwartet '%s')" % (", ".join(abweichend), zahl))
730
+
731
+ # --- T365: die Bauform der Starter ------------------------------------------------
732
+ fehlt = []
733
+ for zeile in lies(os.path.join(QUELLE, "install.cmd")).splitlines():
734
+ z = zeile.strip().lower()
735
+ if z.startswith(":") or re.search(r"\bgoto\b|\bcall\s+:", z):
736
+ if not z.startswith("rem"):
737
+ fehlt.append("install.cmd: " + zeile.strip()[:40])
738
+ g = unterprozess(["git", "-C", QUELLE, "ls-files", "-s", "install.command"])
739
+ if g.returncode != 0 or not g.stdout.strip():
740
+ fehlt.append("Modus von install.command nicht lesbar (kein Git-Bestand)")
741
+ elif not g.stdout.startswith("100755"):
742
+ fehlt.append("install.command traegt " + g.stdout.split()[0])
743
+ melde("SONDE", "T365", not fehlt,
744
+ "install.cmd kommt ohne Sprungmarke aus, install.command ist ausfuehrbar")
745
+ if fehlt:
746
+ notiz(" " + "; ".join(fehlt))
747
+ finally:
748
+ aufraeumen(os.path.dirname(quelle))
749
+ aufraeumen(basis)
750
+
751
+
752
+ buendel(sonden_kopierweg,
753
+ "install.py --target aus Archivform und Klon, Heben, Rueckbau und Verweigerungen, "
754
+ "dazu der Dialog und die Bauform der Starter")
755
+
756
+
757
+
758
+ # --- D-367: der Lieferumfang einer Installation (CR-2026-141) ------------------------
759
+ #
760
+ # `install.py --target --lieferumfang nutzung` laesst die Nachweisschicht weg
761
+ # (clientmap.NACHWEIS_ABLAGEN). OB die Nutzung ohne sie auskommt, belegt keine
762
+ # Einzelpruefung, sondern der Vergleich: Eine reduzierte Installation muss je Pack
763
+ # dieselbe Validatorausgabe liefern wie eine volle - bis auf die HINWEIS-Zeilen, die
764
+ # genau das Weggelassene nennen. Ein Traeger, den ein Werkzeug zur Laufzeit aus der
765
+ # Nachweisschicht liest, faellt genau hier auf.
766
+ # L367 (Sonde) - je Pack: reduziert und voll zeilengleich unter --strict-overlay, bis
767
+ # auf die HINWEIS-Zeilen; reduziert ohne Nachweisschicht, mit
768
+ # LIEFERUMFANG 'nutzung', voll mit 'voll' und ohne HINWEIS
769
+ # L367a (Sonde) - --update ohne Angabe hebt und bleibt reduziert
770
+ # 90b (Sonde) - LIEFERUMFANG mit unbekanntem Wert wird gemeldet
771
+ # 90c (Sonde) - 'nutzung', obwohl eine Ablage der Nachweisschicht daliegt, wird
772
+ # gemeldet
773
+ # L367c (Sonde) - eine reduzierte Quelle verweigert den vollen Kern, ohne zu schreiben
774
+ # L367b (Sonde) - --update --lieferumfang voll waechst auf den ganzen Kern
775
+ # L367d (Sonde) - --lieferumfang ohne --target haelt an
776
+ # L367e (Sonde) - der Dialog fragt den Umfang und installiert reduziert
777
+ # T368 (Sonde) - unter Windows: ein Projektpfad, der die Pfadgrenze reisst, haelt vor
778
+ # der ersten Kopie an und laesst das Projekt leer (D-368); auf den
779
+ # anderen Systemen die Gegenprobe: derselbe Pfad wird installiert
780
+ # Dazu zwei Einzelsonden am Quellrepositorium (90, 90a).
781
+ L367_PACKS = ("claude-code", "devin-desktop", "openai-codex")
782
+ L367_ANTWORTEN = "%s\n1\n1\n2\nj\n"
783
+
784
+
785
+ def _367_ausgabe(root: str) -> list:
786
+ """Validatorausgabe unter --strict-overlay, der Projektpfad durch <ROOT> ersetzt."""
787
+ p = unterprozess([sys.executable, os.path.join(root, *VALIDATOR.split("/")),
788
+ "--root", root, "--strict-overlay"])
789
+ text = ((p.stdout or "") + (p.stderr or "")).replace(os.path.normpath(root), "<ROOT>")
790
+ return text.splitlines()
791
+
792
+
793
+ def _367_umfang(root: str) -> str:
794
+ pfad = os.path.join(root, ".koolie", "core", "LIEFERUMFANG")
795
+ return lies(pfad).strip() if os.path.isfile(pfad) else "-"
796
+
797
+
798
+ def _367_nachweis_da(root: str) -> list:
799
+ kern = os.path.join(root, ".koolie", "core")
800
+ return [a for a in ("governance/change-requests", "tests/protocols", "tests/erhebungen",
801
+ "build") if os.path.exists(os.path.join(kern, *a.split("/")))]
802
+
803
+
804
+ def sonden_lieferumfang() -> None:
805
+ """Wirkungsnachweis fuer den waehlbaren Lieferumfang (D-367) und die Pfadgrenze (D-368)."""
806
+ basis = tempfile.mkdtemp(prefix="lw-umfang-")
807
+ quelle = kopie()
808
+ try:
809
+ qkern = os.path.join(quelle, ".koolie", "core")
810
+
811
+ # --- L367: reduziert gegen voll, je Pack -------------------------------------
812
+ abweichend = []
813
+ for pack in L367_PACKS:
814
+ voll = os.path.join(basis, "voll-" + pack)
815
+ nutz = os.path.join(basis, "nutzung-" + pack)
816
+ os.makedirs(voll)
817
+ os.makedirs(nutz)
818
+ a = _362_lauf(qkern, "--target", voll, "--client", pack)
819
+ b = _362_lauf(qkern, "--target", nutz, "--client", pack,
820
+ "--lieferumfang", "nutzung")
821
+ if a.returncode or b.returncode:
822
+ abweichend.append("%s: Installation Exit %d/%d" % (pack, a.returncode,
823
+ b.returncode))
824
+ continue
825
+ aus_voll = _367_ausgabe(voll)
826
+ aus_nutz = _367_ausgabe(nutz)
827
+ ohne = [z for z in aus_nutz if not z.startswith("HINWEIS")]
828
+ hinweise = [z for z in aus_nutz if z.startswith("HINWEIS")]
829
+ if ohne != aus_voll:
830
+ nur_nutz = [z for z in ohne if z not in aus_voll]
831
+ nur_voll = [z for z in aus_voll if z not in ohne]
832
+ abweichend.append("%s: %d Zeilen nur reduziert, %d nur voll; erste: %s"
833
+ % (pack, len(nur_nutz), len(nur_voll),
834
+ ((nur_nutz or nur_voll or ["Reihenfolge"])[0])[:160]))
835
+ if any(z.startswith("HINWEIS") for z in aus_voll):
836
+ abweichend.append(pack + ": die volle Installation traegt HINWEIS-Zeilen")
837
+ if not any("Lieferumfang 'nutzung'" in z for z in hinweise):
838
+ abweichend.append(pack + ": reduziert ohne HINWEIS zum Lieferumfang")
839
+ if _367_nachweis_da(nutz):
840
+ abweichend.append(pack + ": reduziert liegt " + ", ".join(_367_nachweis_da(nutz)))
841
+ if (_367_umfang(voll), _367_umfang(nutz)) != ("voll", "nutzung"):
842
+ abweichend.append("%s: LIEFERUMFANG %s/%s" % (pack, _367_umfang(voll),
843
+ _367_umfang(nutz)))
844
+ melde("SONDE", "L367", not abweichend,
845
+ "Eine reduzierte Installation meldet in jedem Pack dasselbe wie eine volle, "
846
+ "bis auf die HINWEIS-Zeilen zum Weggelassenen")
847
+ for z in abweichend:
848
+ notiz(" " + z)
849
+
850
+ nutz = os.path.join(basis, "nutzung-claude-code")
851
+ nkern = os.path.join(nutz, ".koolie", "core")
852
+
853
+ # --- L367a: Heben ohne Angabe bleibt reduziert -------------------------------
854
+ schreib(os.path.join(nkern, "VERSION"), "0.0.0\n")
855
+ p = _362_lauf(qkern, "--target", nutz, "--update")
856
+ ok = (p.returncode == 0 and _367_umfang(nutz) == "nutzung"
857
+ and not _367_nachweis_da(nutz)
858
+ and lies(os.path.join(nkern, "VERSION")).strip()
859
+ == lies(os.path.join(qkern, "VERSION")).strip())
860
+ melde("SONDE", "L367a", ok,
861
+ "--update ohne Angabe hebt ein reduziertes Projekt und laesst es reduziert")
862
+ if not ok:
863
+ notiz(" Exit %d, Umfang %s, Nachweis %s" % (
864
+ p.returncode, _367_umfang(nutz), _367_nachweis_da(nutz)))
865
+
866
+ # --- 90b, 90c: Pruefung 90 an der reduzierten Installation --------------------
867
+ schreib(os.path.join(nkern, "LIEFERUMFANG"), "teilweise\n")
868
+ melde("SONDE", "90b", "trägt 'teilweise'" in "\n".join(_367_ausgabe(nutz)),
869
+ "Ein unbekannter Wert in LIEFERUMFANG wird gemeldet - das naechste Heben "
870
+ "hielte daran an")
871
+ schreib(os.path.join(nkern, "LIEFERUMFANG"), "nutzung\n")
872
+ os.makedirs(os.path.join(nkern, "tests", "protocols"))
873
+ schreib(os.path.join(nkern, "tests", "protocols", "liegengeblieben.md"), "# x\n")
874
+ melde("SONDE", "90c", "sagt 'nutzung', aber" in "\n".join(_367_ausgabe(nutz)),
875
+ "LIEFERUMFANG nutzung neben einer Ablage der Nachweisschicht wird gemeldet - "
876
+ "das naechste Heben loeschte sie")
877
+
878
+ # --- L367c: aus der reduzierten Quelle kein voller Kern ------------------------
879
+ leer = os.path.join(basis, "aus-reduziert")
880
+ os.makedirs(leer)
881
+ p = _362_lauf(nkern, "--target", leer, "--client", "claude-code")
882
+ ok = p.returncode == 1 and "einen vollen Kern kann" in p.stderr and not os.listdir(leer)
883
+ melde("SONDE", "L367c", ok,
884
+ "Eine reduzierte Quelle verweigert den vollen Kern und schreibt nichts")
885
+
886
+ # --- L367b: ausdruecklich zurueck auf voll --------------------------------------
887
+ shutil.rmtree(os.path.join(nkern, "tests", "protocols"))
888
+ p = _362_lauf(qkern, "--target", nutz, "--update", "--lieferumfang", "voll")
889
+ ok = (p.returncode == 0 and _367_umfang(nutz) == "voll"
890
+ and len(_367_nachweis_da(nutz)) == 4 and "(bisher nutzung)" in p.stdout)
891
+ melde("SONDE", "L367b", ok,
892
+ "--update --lieferumfang voll bringt die Nachweisschicht zurueck und nennt "
893
+ "den Wechsel")
894
+ if not ok:
895
+ notiz(" Exit %d, Umfang %s, Nachweis %s" % (
896
+ p.returncode, _367_umfang(nutz), _367_nachweis_da(nutz)))
897
+
898
+ # --- L367d: ohne --target ------------------------------------------------------
899
+ ohne_ziel = os.path.join(basis, "ohne-target")
900
+ os.makedirs(ohne_ziel)
901
+ p = _362_lauf(qkern, "--root", ohne_ziel, "--lieferumfang", "nutzung")
902
+ ok = (p.returncode == 1 and "gehoert zu --target" in p.stderr
903
+ and not os.listdir(ohne_ziel))
904
+ melde("SONDE", "L367d", ok, "--lieferumfang ohne --target haelt an, ohne zu schreiben")
905
+
906
+ # --- L367e: der Dialog ---------------------------------------------------------
907
+ dlg = os.path.join(basis, "dialog")
908
+ os.makedirs(dlg)
909
+ p = _362_lauf(qkern, eingabe=L367_ANTWORTEN % dlg, werkzeug="install_dialog.py")
910
+ ok = p.returncode == 0 and _367_umfang(dlg) == "nutzung" and not _367_nachweis_da(dlg)
911
+ melde("SONDE", "L367e", ok,
912
+ "Der Dialog fragt den Lieferumfang ab und installiert reduziert")
913
+ if not ok:
914
+ notiz(" Exit %d, Umfang %s: %s" % (p.returncode, _367_umfang(dlg), " | ".join(
915
+ (p.stdout + p.stderr).splitlines()[-4:])))
916
+
917
+ # --- T368: die Pfadgrenze ------------------------------------------------------
918
+ tief = basis
919
+ while len(tief) < 190:
920
+ tief = os.path.join(tief, "t" * min(40, 200 - len(tief)))
921
+ os.makedirs(tief)
922
+ p = _362_lauf(qkern, "--target", tief, "--client", "claude-code")
923
+ if os.name == "nt":
924
+ ok = (p.returncode == 1 and "fuer Windows zu lang" in p.stderr
925
+ and not os.listdir(tief))
926
+ melde("SONDE", "T368", ok,
927
+ "Ein Projektpfad, der die Windows-Pfadgrenze reisst, haelt vor der ersten "
928
+ "Kopie an und laesst das Projekt leer")
929
+ else:
930
+ ok = p.returncode == 0
931
+ melde("GEGENPROBE", "T368", ok,
932
+ "Ausserhalb von Windows gilt keine Pfadgrenze - derselbe tiefe "
933
+ "Projektpfad wird installiert")
934
+ if not ok:
935
+ notiz(" Exit %d: %s" % (p.returncode, (p.stderr or "")[:200]))
936
+ finally:
937
+ aufraeumen(os.path.dirname(quelle))
938
+ aufraeumen(basis)
939
+
940
+
941
+ buendel(sonden_lieferumfang,
942
+ "Reduzierte gegen volle Installation je Pack, Heben mit und ohne Wechsel, "
943
+ "Verweigerungen, der Dialog, Pruefung 90 und die Windows-Pfadgrenze")
944
+
945
+
946
+ # Pruefung 90 am Quellrepositorium: Es ist keine Installation, und die Lockerung von
947
+ # Pruefung 12 gilt dort nie - was immer eine Datei LIEFERUMFANG behauptet.
948
+ P90_DATEI = os.path.join(".koolie", "core", "LIEFERUMFANG")
949
+ P90_PROTOKOLL = os.path.join(".koolie", "core", "tests", "protocols",
950
+ "2026-09-19-testblaetter-buendel-2.md")
951
+
952
+
953
+ def _90a(root: str) -> None:
954
+ schreib(P(root, P90_DATEI), "nutzung\n")
955
+ if not os.path.isfile(P(root, P90_PROTOKOLL)):
956
+ raise Praeparationsfehler("Das zitierte Protokoll fehlt schon: " + P90_PROTOKOLL)
957
+ os.remove(P(root, P90_PROTOKOLL))
958
+
959
+
960
+ sonde("90", "Eine Datei LIEFERUMFANG im Quellrepositorium wird gemeldet - sie behauptete dort eine Installation",
961
+ lambda r: schreib(P(r, P90_DATEI), "nutzung\n"), "liegt im Quellrepositorium")
962
+
963
+ sonde("90a", "Im Quellrepositorium bleibt ein Verweis in die Nachweisschicht ein Fehler, auch wenn LIEFERUMFANG nutzung behauptet",
964
+ _90a, "Pfadangabe existiert nicht: .koolie/core/tests/protocols/2026-09-19-testblaetter-buendel-2.md")
965
+
966
+
967
+ # --- D-364: Pruefung 33 ohne PyYAML (CR-2026-140) --------------------------------------
968
+ #
969
+ # Ohne PyYAML las Pruefung 33 aus dem Rohtext des Frontmatters nichts und meldete an
970
+ # jeder claude-code-Installation neun Skills mit leerem disallowed-tools. Der Starter
971
+ # installiert kein PyYAML nach (D-362) - auf einem frischen Zielrechner fehlt es also
972
+ # oft. Die Sonde sperrt den Import ueber ein Stellvertretermodul im Suchpfad.
973
+ # S364 (Sonde) - eine verkuerzte Liste wird auch ohne PyYAML gemeldet
974
+ # S364a (Gegenprobe) - die richtige Installation bleibt ohne PyYAML still
975
+ T364_SPERRE = "raise ImportError('PyYAML gesperrt durch die Sonde S364')\n"
976
+
977
+
978
+ def sonden_ohne_pyyaml() -> None:
979
+ """Pruefung 33 misst ohne PyYAML dasselbe wie mit (D-364)."""
980
+ root = installation("claude-code")
981
+ sperre = tempfile.mkdtemp(prefix="lw-ohne-yaml-")
982
+ try:
983
+ schreib(os.path.join(sperre, "yaml.py"), T364_SPERRE)
984
+ umgebung = dict(os.environ, PYTHONPATH=sperre)
985
+
986
+ def lauf_ohne() -> str:
987
+ p = unterprozess([sys.executable, os.path.join(root, *VALIDATOR.split("/")),
988
+ "--root", root], env=umgebung)
989
+ return (p.stdout or "") + (p.stderr or "")
990
+
991
+ aus = lauf_ohne()
992
+ gesperrt = "PyYAML nicht installiert" in aus
993
+ still = "disallowed-tools traegt" not in aus
994
+ melde("GEGENPROBE", "S364a", gesperrt and still,
995
+ "Ohne PyYAML meldet Pruefung 33 an einer richtigen Installation nichts")
996
+ if not (gesperrt and still):
997
+ notiz(" PyYAML gesperrt %s, still %s" % (gesperrt, still))
998
+ skill = os.path.join(root, ".claude", "skills", "fw-plan", "SKILL.md")
999
+ text = lies(skill)
1000
+ neu = re.sub(r"(?m)^disallowed-tools: .*$", "disallowed-tools: Edit", text)
1001
+ if neu == text:
1002
+ raise Praeparationsfehler("disallowed-tools in fw-plan/SKILL.md nicht gefunden")
1003
+ schreib(skill, neu)
1004
+ aus = lauf_ohne()
1005
+ ok = "fw-plan/SKILL.md: disallowed-tools traegt ['Edit']" in aus
1006
+ melde("SONDE", "S364", ok,
1007
+ "Ohne PyYAML wird eine verkuerzte disallowed-tools-Liste weiter gemeldet")
1008
+ finally:
1009
+ aufraeumen(sperre)
1010
+ aufraeumen(os.path.dirname(root))
1011
+
1012
+
1013
+ buendel(sonden_ohne_pyyaml,
1014
+ "Pruefung 33 liest disallowed-tools auch ohne PyYAML und meldet nur, was fehlt")