@renoxar/koolie 1.25.0 → 2.0.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 (232) hide show
  1. package/.github/workflows/publish.yml +177 -0
  2. package/.koolie/QUELLREPOSITORIUM.md +9 -14
  3. package/.koolie/core/CHANGELOG.md +59 -0
  4. package/.koolie/core/LICENSE-HINWEIS.md +5 -6
  5. package/.koolie/core/OWNERS.md +2 -2
  6. package/.koolie/core/VERSION +1 -1
  7. package/.koolie/core/build/doc/00-kopf.md +6 -6
  8. package/.koolie/core/build/doc/01-executive-summary.md +8 -8
  9. package/.koolie/core/build/doc/03-ziele-nichtziele.md +2 -2
  10. package/.koolie/core/build/doc/04-geltungsbereich.md +4 -4
  11. package/.koolie/core/build/doc/05-glossar.md +3 -3
  12. package/.koolie/core/build/doc/07-architektur.md +2 -2
  13. package/.koolie/core/build/doc/07a-abbildungsschicht.md +9 -9
  14. package/.koolie/core/build/doc/08-trennung.md +3 -3
  15. package/.koolie/core/build/doc/09-betriebsmodi.md +8 -8
  16. package/.koolie/core/build/doc/15-referenzstruktur.md +56 -27
  17. package/.koolie/core/build/doc/16-agentenanweisung.md +2 -2
  18. package/.koolie/core/build/doc/20-referenz-skills.md +46 -46
  19. package/.koolie/core/build/doc/25-governance.md +9 -1
  20. package/.koolie/core/build/doc/26-qs-test.md +32 -3
  21. package/.koolie/core/build/doc/27-pilot.md +2 -2
  22. package/.koolie/core/build/doc/28-uebernahme.md +9 -1
  23. package/.koolie/core/build/doc/30-roadmap.md +3 -1
  24. package/.koolie/core/build/doc/31-anhaenge.md +1 -1
  25. package/.koolie/core/checklists/01-preflight.md +3 -3
  26. package/.koolie/core/checklists/02-privacy-context.md +1 -1
  27. package/.koolie/core/checklists/03-before-code-change.md +2 -2
  28. package/.koolie/core/checklists/04-review-ai-code.md +1 -1
  29. package/.koolie/core/checklists/05-testing.md +1 -1
  30. package/.koolie/core/checklists/06-security.md +1 -1
  31. package/.koolie/core/checklists/08-merge-request.md +1 -1
  32. package/.koolie/core/checklists/09-onboarding.md +2 -2
  33. package/.koolie/core/checklists/10-project-adoption.md +8 -8
  34. package/.koolie/core/checklists/11-framework-release.md +14 -14
  35. package/.koolie/core/clientmap.py +2 -2
  36. package/.koolie/core/clients/README.md +54 -52
  37. package/.koolie/core/clients/_template/CLIENT_PACK.md +19 -19
  38. package/.koolie/core/clients/claude-code/CLIENT_PACK.md +108 -164
  39. package/.koolie/core/clients/claude-code/manifest.json +5 -5
  40. package/.koolie/core/clients/claude-code/root-template/.claude/README.md +9 -9
  41. package/.koolie/core/clients/cursor/CLIENT_PACK.md +66 -60
  42. package/.koolie/core/clients/cursor/manifest.json +3 -3
  43. package/.koolie/core/clients/cursor/root-template/.cursor/README.md +3 -3
  44. package/.koolie/core/clients/devin-desktop/CLIENT_PACK.md +62 -64
  45. package/.koolie/core/clients/devin-desktop/manifest.json +5 -5
  46. package/.koolie/core/clients/devin-desktop/root-template/.devin/README.md +9 -9
  47. package/.koolie/core/clients/kiro/CLIENT_PACK.md +55 -48
  48. package/.koolie/core/clients/kiro/manifest.json +4 -4
  49. package/.koolie/core/clients/kiro/root-template/.kiro/README.md +3 -3
  50. package/.koolie/core/clients/openai-codex/CLIENT_PACK.md +98 -103
  51. package/.koolie/core/clients/openai-codex/manifest.json +3 -3
  52. package/.koolie/core/clients/openai-codex/root-template/.codex/README.md +2 -2
  53. package/.koolie/core/decision-trees/02-may-ai-do-task.md +2 -2
  54. package/.koolie/core/decision-trees/03-analyze-or-modify.md +12 -12
  55. package/.koolie/core/decision-trees/04-required-review.md +1 -1
  56. package/.koolie/core/docs/ADOPTION_GUIDE.md +281 -385
  57. package/.koolie/core/docs/DOCUMENTATION_STANDARD.md +44 -36
  58. package/.koolie/core/docs/PLACEHOLDER_REGISTRY.md +8 -8
  59. package/.koolie/core/docs/ROADMAP.md +34 -17
  60. package/.koolie/core/docs/RUNTIME_GLOSSARY.md +34 -35
  61. package/.koolie/core/examples/example-ergebnisbericht.md +1 -1
  62. package/.koolie/core/examples/example-mr-description.md +2 -2
  63. package/.koolie/core/framework/core/00-principles.md +1 -1
  64. package/.koolie/core/framework/core/01-governance.md +8 -8
  65. package/.koolie/core/framework/core/02-privacy.md +12 -12
  66. package/.koolie/core/framework/core/03-security.md +13 -11
  67. package/.koolie/core/framework/core/05-working-model.md +22 -22
  68. package/.koolie/core/framework/core/06-prompting-rules.md +5 -5
  69. package/.koolie/core/framework/core/07-review-rules.md +1 -1
  70. package/.koolie/core/framework/core/08-skill-conventions.md +11 -11
  71. package/.koolie/core/framework/core/09-risk-model.md +6 -6
  72. package/.koolie/core/framework/core/10-error-escalation.md +1 -1
  73. package/.koolie/core/framework/org-policies/MAPPING_CLASSIFICATION.md +1 -1
  74. package/.koolie/core/framework/overlay-patterns/general.md +63 -75
  75. package/.koolie/core/framework/role-packs/README.md +16 -28
  76. package/.koolie/core/framework/role-packs/_template/ROLE_PACK.md +3 -3
  77. package/.koolie/core/framework/role-packs/requirements-engineering/ROLE_PACK.md +23 -22
  78. package/.koolie/core/framework/role-packs/requirements-engineering/runtime/30-role-requirements-engineering.md +5 -5
  79. package/.koolie/core/framework/role-packs/requirements-engineering/skills/{role-re-ticket → koolie-ticket}/CHANGELOG.md +2 -1
  80. package/.koolie/core/framework/role-packs/requirements-engineering/skills/{role-re-ticket → koolie-ticket}/EXAMPLES.md +5 -5
  81. package/.koolie/core/framework/role-packs/requirements-engineering/skills/{role-re-ticket → koolie-ticket}/SKILL.md +9 -9
  82. package/.koolie/core/framework/role-packs/requirements-engineering/skills/koolie-ticket/TESTS.md +22 -0
  83. package/.koolie/core/framework/role-packs/software-development/ROLE_PACK.md +16 -16
  84. package/.koolie/core/framework/role-packs/software-development/runtime/30-role-software-development.md +1 -1
  85. package/.koolie/core/framework/runtime/agents/{fw-reviewer.md → koolie-reviewer.md} +2 -2
  86. package/.koolie/core/framework/runtime/permissions.json +13 -13
  87. package/.koolie/core/framework/runtime/root-instruction.md +5 -5
  88. package/.koolie/core/framework/runtime/rules/10-privacy-security.md +2 -2
  89. package/.koolie/core/framework/runtime/rules/15-development-rules.md +1 -1
  90. package/.koolie/core/framework/runtime/rules/16-plan-spezifikation.md +1 -1
  91. package/.koolie/core/framework/runtime/rules/20-project-overlay.md +2 -2
  92. package/.koolie/core/framework/skills/{fw-bugfix-prepare → koolie-bugfix-prepare}/CHANGELOG.md +2 -1
  93. package/.koolie/core/framework/skills/{fw-bugfix-prepare → koolie-bugfix-prepare}/EXAMPLES.md +8 -8
  94. package/.koolie/core/framework/skills/{fw-bugfix-prepare → koolie-bugfix-prepare}/SKILL.md +21 -21
  95. package/.koolie/core/framework/skills/koolie-bugfix-prepare/TESTS.md +15 -0
  96. package/.koolie/core/framework/skills/{fw-change-analyze → koolie-change-analyze}/CHANGELOG.md +2 -1
  97. package/.koolie/core/framework/skills/{fw-change-analyze → koolie-change-analyze}/EXAMPLES.md +6 -6
  98. package/.koolie/core/framework/skills/{fw-change-analyze → koolie-change-analyze}/SKILL.md +12 -12
  99. package/.koolie/core/framework/skills/koolie-change-analyze/TESTS.md +16 -0
  100. package/.koolie/core/framework/skills/{fw-change-small → koolie-change-small}/CHANGELOG.md +2 -1
  101. package/.koolie/core/framework/skills/{fw-change-small → koolie-change-small}/EXAMPLES.md +4 -4
  102. package/.koolie/core/framework/skills/{fw-change-small → koolie-change-small}/SKILL.md +15 -15
  103. package/.koolie/core/framework/skills/koolie-change-small/TESTS.md +13 -0
  104. package/.koolie/core/framework/skills/{fw-code-explain → koolie-code-explain}/CHANGELOG.md +2 -1
  105. package/.koolie/core/framework/skills/{fw-code-explain → koolie-code-explain}/EXAMPLES.md +4 -4
  106. package/.koolie/core/framework/skills/{fw-code-explain → koolie-code-explain}/SKILL.md +10 -10
  107. package/.koolie/core/framework/skills/koolie-code-explain/TESTS.md +11 -0
  108. package/.koolie/core/framework/skills/{fw-docs-update → koolie-docs-update}/CHANGELOG.md +2 -1
  109. package/.koolie/core/framework/skills/{fw-docs-update → koolie-docs-update}/EXAMPLES.md +3 -3
  110. package/.koolie/core/framework/skills/{fw-docs-update → koolie-docs-update}/SKILL.md +8 -8
  111. package/.koolie/core/framework/skills/koolie-docs-update/TESTS.md +12 -0
  112. package/.koolie/core/framework/skills/{fw-error-analyze → koolie-error-analyze}/CHANGELOG.md +2 -1
  113. package/.koolie/core/framework/skills/{fw-error-analyze → koolie-error-analyze}/EXAMPLES.md +6 -6
  114. package/.koolie/core/framework/skills/{fw-error-analyze → koolie-error-analyze}/SKILL.md +15 -15
  115. package/.koolie/core/framework/skills/koolie-error-analyze/TESTS.md +12 -0
  116. package/.koolie/core/framework/skills/{fw-mr-description → koolie-mr-description}/CHANGELOG.md +2 -1
  117. package/.koolie/core/framework/skills/{fw-mr-description → koolie-mr-description}/EXAMPLES.md +6 -6
  118. package/.koolie/core/framework/skills/{fw-mr-description → koolie-mr-description}/SKILL.md +8 -8
  119. package/.koolie/core/framework/skills/koolie-mr-description/TESTS.md +12 -0
  120. package/.koolie/core/framework/skills/{fw-overlay-pflege → koolie-overlay-pflege}/CHANGELOG.md +2 -1
  121. package/.koolie/core/framework/skills/{fw-overlay-pflege → koolie-overlay-pflege}/EXAMPLES.md +4 -4
  122. package/.koolie/core/framework/skills/{fw-overlay-pflege → koolie-overlay-pflege}/SKILL.md +8 -8
  123. package/.koolie/core/framework/skills/koolie-overlay-pflege/TESTS.md +13 -0
  124. package/.koolie/core/framework/skills/{fw-plan → koolie-plan}/CHANGELOG.md +2 -1
  125. package/.koolie/core/framework/skills/{fw-plan → koolie-plan}/EXAMPLES.md +7 -7
  126. package/.koolie/core/framework/skills/{fw-plan → koolie-plan}/SKILL.md +14 -14
  127. package/.koolie/core/framework/skills/koolie-plan/TESTS.md +14 -0
  128. package/.koolie/core/framework/skills/{fw-refactor → koolie-refactor}/CHANGELOG.md +2 -1
  129. package/.koolie/core/framework/skills/{fw-refactor → koolie-refactor}/EXAMPLES.md +4 -4
  130. package/.koolie/core/framework/skills/{fw-refactor → koolie-refactor}/SKILL.md +12 -12
  131. package/.koolie/core/framework/skills/koolie-refactor/TESTS.md +14 -0
  132. package/.koolie/core/framework/skills/{fw-repo-analyze → koolie-repo-analyze}/CHANGELOG.md +2 -1
  133. package/.koolie/core/framework/skills/{fw-repo-analyze → koolie-repo-analyze}/EXAMPLES.md +4 -4
  134. package/.koolie/core/framework/skills/{fw-repo-analyze → koolie-repo-analyze}/SKILL.md +8 -8
  135. package/.koolie/core/framework/skills/koolie-repo-analyze/TESTS.md +11 -0
  136. package/.koolie/core/framework/skills/{fw-review-support → koolie-review-support}/CHANGELOG.md +2 -1
  137. package/.koolie/core/framework/skills/{fw-review-support → koolie-review-support}/EXAMPLES.md +3 -3
  138. package/.koolie/core/framework/skills/{fw-review-support → koolie-review-support}/SKILL.md +7 -7
  139. package/.koolie/core/framework/skills/koolie-review-support/TESTS.md +13 -0
  140. package/.koolie/core/framework/skills/{fw-tests → koolie-tests}/CHANGELOG.md +2 -1
  141. package/.koolie/core/framework/skills/{fw-tests → koolie-tests}/EXAMPLES.md +5 -5
  142. package/.koolie/core/framework/skills/{fw-tests → koolie-tests}/SKILL.md +11 -11
  143. package/.koolie/core/framework/skills/koolie-tests/TESTS.md +12 -0
  144. package/.koolie/core/framework/tech-packs/README.md +2 -2
  145. package/.koolie/core/framework/tech-packs/_template/TECH_PACK.md +2 -2
  146. package/.koolie/core/governance/ADOPTION_REGISTRY.md +22 -58
  147. package/.koolie/core/governance/CHANGE_REQUEST_TEMPLATE.md +1 -1
  148. package/.koolie/core/governance/DECISION_LOG.md +7 -1
  149. package/.koolie/core/governance/EXCEPTION_PROCESS.md +1 -1
  150. package/.koolie/core/governance/FEEDBACK_PROCESS.md +1 -1
  151. package/.koolie/core/governance/FRAMEWORK_DEV_PROFILE.md +64 -66
  152. package/.koolie/core/governance/PRIORITY_HIERARCHY.md +13 -13
  153. package/.koolie/core/governance/RACI.md +3 -3
  154. package/.koolie/core/governance/RELEASE_PROCESS.md +101 -108
  155. package/.koolie/core/governance/change-requests/CR-2026-173-oeffentlicher-auftritt-koolie-praefix.md +67 -0
  156. package/.koolie/core/install.py +99 -0
  157. package/.koolie/core/koexistenz.py +2 -2
  158. package/.koolie/core/onboarding/GUIDE.md +7 -7
  159. package/.koolie/core/onboarding/KNOWLEDGE_CHECK.md +1 -1
  160. package/.koolie/core/onboarding/MENTOR_CHECKLIST.md +3 -3
  161. package/.koolie/core/onboarding/QUICKSTART.md +2 -2
  162. package/.koolie/core/onboarding/REFERENCE.md +14 -14
  163. package/.koolie/core/onboarding/exercises/EXERCISES.md +8 -8
  164. package/.koolie/core/onboarding/exercises/README.md +47 -65
  165. package/.koolie/core/pilot/PILOT_CONCEPT.md +1 -1
  166. package/.koolie/core/prompts/01-understand-codebase.md +11 -7
  167. package/.koolie/core/prompts/02-impact-analysis.md +17 -7
  168. package/.koolie/core/prompts/03-implementation-planning.md +10 -6
  169. package/.koolie/core/prompts/04-code-generation.md +11 -5
  170. package/.koolie/core/prompts/05-test-generation.md +13 -7
  171. package/.koolie/core/prompts/06-refactoring.md +14 -8
  172. package/.koolie/core/prompts/07-debugging.md +13 -11
  173. package/.koolie/core/prompts/08-security-review.md +2 -2
  174. package/.koolie/core/prompts/09-performance-analysis.md +2 -2
  175. package/.koolie/core/prompts/10-documentation.md +6 -4
  176. package/.koolie/core/prompts/11-merge-request-review.md +7 -5
  177. package/.koolie/core/prompts/12-developer-training.md +5 -3
  178. package/.koolie/core/prompts/README.md +17 -15
  179. package/.koolie/core/templates/MR_AI_DISCLOSURE.md +2 -2
  180. package/.koolie/core/templates/PLAN_TEMPLATE.md +2 -2
  181. package/.koolie/core/templates/SKILL_TEMPLATE.md +3 -3
  182. package/.koolie/core/templates/project-overlay/OVERLAY.md +28 -22
  183. package/.koolie/core/templates/project-overlay/documents/architecture/decisions/README.md +1 -1
  184. package/.koolie/core/tests/EDGE_CASES.md +4 -7
  185. package/.koolie/core/tests/TEST_CATALOG.md +33 -33
  186. package/.koolie/core/tests/protocols/2026-10-02-oeffentlicher-auftritt-2.0.0.md +42 -0
  187. package/.koolie/core/tests/scripts/hook-check-secrets.py +2 -2
  188. package/.koolie/core/tests/scripts/hook-overlay-status.py +1 -1
  189. package/.koolie/core/tests/scripts/probe-pruefungen.py +4 -2
  190. package/.koolie/core/tests/scripts/pruefungen/berechtigungen.py +7 -7
  191. package/.koolie/core/tests/scripts/pruefungen/bestand.py +20 -3
  192. package/.koolie/core/tests/scripts/pruefungen/dokumente.py +88 -0
  193. package/.koolie/core/tests/scripts/pruefungen/gemeinsam.py +1 -1
  194. package/.koolie/core/tests/scripts/pruefungen/hooks.py +1 -1
  195. package/.koolie/core/tests/scripts/pruefungen/overlay.py +5 -5
  196. package/.koolie/core/tests/scripts/pruefungen/testkatalog.py +5 -5
  197. package/.koolie/core/tests/scripts/pruefungen/werkzeuge.py +81 -2
  198. package/.koolie/core/tests/scripts/sonden/teil02_packs_mandat_mcp.py +6 -6
  199. package/.koolie/core/tests/scripts/sonden/teil03_pruefungen_26_bis_36.py +11 -11
  200. package/.koolie/core/tests/scripts/sonden/teil04_pruefungen_37_bis_45.py +11 -11
  201. package/.koolie/core/tests/scripts/sonden/teil05_pruefungen_46_bis_55.py +4 -4
  202. package/.koolie/core/tests/scripts/sonden/teil06_pruefungen_57_bis_65.py +33 -33
  203. package/.koolie/core/tests/scripts/sonden/teil07_overlay_und_lieferung.py +3 -3
  204. package/.koolie/core/tests/scripts/sonden/teil08_pruefungen_66_bis_80.py +3 -3
  205. package/.koolie/core/tests/scripts/sonden/teil10_pruefungen_83_bis_95.py +3 -3
  206. package/.koolie/core/tests/scripts/sonden/teil11_pruefungen_104_und_105.py +2 -2
  207. package/.koolie/core/tests/scripts/sonden/teil14_modi_ausnahmen_skills.py +1 -1
  208. package/.koolie/core/tests/scripts/sonden/teil16_koexistenz.py +5 -5
  209. package/.koolie/core/tests/scripts/sonden/teil17_paketquellen.py +33 -0
  210. package/.koolie/core/tests/scripts/sonden/teil19_skillnamen.py +97 -0
  211. package/.koolie/core/tests/scripts/sonden/teil20_kennungen.py +70 -0
  212. package/.koolie/core/tests/scripts/validate-framework.py +15 -6
  213. package/.koolie/core/tests/scripts/validate-output.py +1 -1
  214. package/CONTRIBUTING.md +16 -10
  215. package/QUICKSTART.en.md +44 -51
  216. package/QUICKSTART.md +44 -50
  217. package/package.json +2 -2
  218. package/paketquellen/README.md +11 -11
  219. package/.koolie/core/framework/role-packs/requirements-engineering/skills/role-re-ticket/TESTS.md +0 -22
  220. package/.koolie/core/framework/skills/fw-bugfix-prepare/TESTS.md +0 -15
  221. package/.koolie/core/framework/skills/fw-change-analyze/TESTS.md +0 -16
  222. package/.koolie/core/framework/skills/fw-change-small/TESTS.md +0 -13
  223. package/.koolie/core/framework/skills/fw-code-explain/TESTS.md +0 -11
  224. package/.koolie/core/framework/skills/fw-docs-update/TESTS.md +0 -12
  225. package/.koolie/core/framework/skills/fw-error-analyze/TESTS.md +0 -12
  226. package/.koolie/core/framework/skills/fw-mr-description/TESTS.md +0 -12
  227. package/.koolie/core/framework/skills/fw-overlay-pflege/TESTS.md +0 -13
  228. package/.koolie/core/framework/skills/fw-plan/TESTS.md +0 -14
  229. package/.koolie/core/framework/skills/fw-refactor/TESTS.md +0 -14
  230. package/.koolie/core/framework/skills/fw-repo-analyze/TESTS.md +0 -11
  231. package/.koolie/core/framework/skills/fw-review-support/TESTS.md +0 -13
  232. package/.koolie/core/framework/skills/fw-tests/TESTS.md +0 -12
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Wirkungsnachweis nach D-23 fuer die Pruefungen 4, 6, 8, 14, 18 bis 66 und 68 bis 112, dazu fuer
2
+ """Wirkungsnachweis nach D-23 fuer die Pruefungen 4, 6, 8, 14, 18 bis 66 und 68 bis 113, dazu fuer
3
3
  install.py (Clientwahl, Aktivierungspruefung, --list-skills, Schutz vorhandener
4
4
  Projektdateien bei der Erstinstallation, Auskunft ueber ignorierte Kerndateien,
5
5
  Overlay-Muster) und fuer den Praeparationswaechter dieses
@@ -73,7 +73,9 @@ from sonden import ( # noqa: E402,F401 - laden heisst anmelden
73
73
  teil15_banner_und_nachlauf,
74
74
  teil16_koexistenz,
75
75
  teil17_paketquellen,
76
- teil18_modusbindung_m3_m5)
76
+ teil18_modusbindung_m3_m5,
77
+ teil19_skillnamen,
78
+ teil20_kennungen)
77
79
 
78
80
 
79
81
  if LISTE:
@@ -40,7 +40,7 @@ def skillfreigaben(root: str, man: dict) -> set:
40
40
  `0.81.0` zu jedem Skill der Installation einen Eintrag der Berechtigungsdatei -
41
41
  das ist der dritte Teil der Aktivierung eines Packs (D-238). Pruefung 37 hielt
42
42
  denselben Eintrag fuer eine AUSWEITUNG, weil die Kernquelle ihn nicht erzeugt:
43
- Am Messbaum von Buendel 5 meldete sie `Skill(role-re-ticket)` als eine Regel zu
43
+ Am Messbaum von Buendel 5 meldete sie `Skill(koolie-ticket)` als eine Regel zu
44
44
  viel im allow-Korb.
45
45
 
46
46
  Damit war die Abhilfe von D-238 in keinem Projekt umsetzbar, ohne den eigenen
@@ -471,7 +471,7 @@ def check_agent_startwerkzeug(root: str) -> None:
471
471
  #
472
472
  # Gemessen am 2026-09-13 (tests/protocols/2026-09-13-erhebung-unteragent-tiefe.md,
473
473
  # Lauf STARTLOS): Ein Profil mit tools: Read, Grep, Glob - genau die Form, die
474
- # fw-reviewer nach der Abbildung traegt - hat KEIN Startwerkzeug und konnte deshalb
474
+ # koolie-reviewer nach der Abbildung traegt - hat KEIN Startwerkzeug und konnte deshalb
475
475
  # keinen weiteren Unteragenten starten, dessen Profil weniger beschraenkt waere. Ohne
476
476
  # diesen Befund waere die Zusage A1 ueber eine zweite Ebene aushebelbar.
477
477
  #
@@ -751,8 +751,8 @@ def check_werkzeugabbildung(root: str) -> None:
751
751
  # Pruefung waere das die zweite Liste fuer dieselbe Sache, also der Befundtyp von
752
752
  # CR-2026-062.
753
753
  # 3. Kein Musterzeichen. Gemessen am 2026-09-14 (D-82): Der Vergleich ist woertlich.
754
- # Skill(fw-*) weist den Aufruf ab, Skill(fw-code-explain) laesst ihn durch,
755
- # Skill(fw-plan) weist fw-code-explain ab (Kontrolllauf). Eine Regel mit * oder ?
754
+ # Skill(koolie-*) weist den Aufruf ab, Skill(koolie-code-explain) laesst ihn durch,
755
+ # Skill(koolie-plan) weist koolie-code-explain ab (Kontrolllauf). Eine Regel mit * oder ?
756
756
  # saehe richtig aus und gaebe LAUTLOS NICHTS frei - die Bauform von D-66 mit
757
757
  # umgekehrtem Vorzeichen.
758
758
  # 4. Die vier Regeltraeger. Die Skillwahl stand vor 0.41.0 an fuenf Stellen und
@@ -842,7 +842,7 @@ def check_skillfreigabe(root: str) -> None:
842
842
  if any(z in name for z in "*?["):
843
843
  err(f"{KERN}/framework/runtime/permissions.json: die skill-Regel '{name}' "
844
844
  f"traegt ein Musterzeichen. Der Vergleich ist woertlich - gemessen am "
845
- f"2026-09-14 (D-82): Skill(fw-*) weist den Aufruf ab. Eine Regel mit "
845
+ f"2026-09-14 (D-82): Skill(koolie-*) weist den Aufruf ab. Eine Regel mit "
846
846
  f"Muster saehe richtig aus und gaebe lautlos nichts frei")
847
847
 
848
848
  # Gegenstand 4: die vier Regeltraeger.
@@ -860,14 +860,14 @@ def check_skillfreigabe(root: str) -> None:
860
860
  # --- Pruefung 72: Ein aktiviertes Pack steht auch im Berechtigungskorb -------------
861
861
  #
862
862
  # ANLASS, UND ER IST GEMESSEN (2026-09-21, Vorbedingungsdurchgang von Buendel 5,
863
- # D-238). Bundel 5 misst `role-re-ticket`, den einzigen Skill dieses Frameworks, der
863
+ # D-238). Bundel 5 misst `koolie-ticket`, den einzigen Skill dieses Frameworks, der
864
864
  # nicht im Kern liegt. Nach der Aktivierung WORTGETREU nach
865
865
  # `framework/role-packs/README.md` - Laufzeitfassung kopiert, Skillverzeichnis kopiert -
866
866
  # und nach `install.py --update` stand im Messbaum:
867
867
  #
868
868
  # Skillverzeichnisse in .claude/skills/ 13
869
869
  # Skill(...)-Eintraege im allow-Korb 12
870
- # Skill(role-re-ticket) fehlt
870
+ # Skill(koolie-ticket) fehlt
871
871
  # validate-framework.py --strict-overlay 0 Fehler, 0 Warnungen
872
872
  #
873
873
  # DIE REGELSCHICHT DES PACKS WAR VOLLSTAENDIG, DIE TECHNISCHE KANNTE ES NICHT. Und
@@ -91,7 +91,10 @@ URL_ALLOWLIST = ("docs.devin.ai", "devin.ai", "cli.devin.ai", "docs.windsurf.com
91
91
  # die Paketseiten und die Badges der README, ebenso eng (D-535)
92
92
  "pypi.org/project/koolie", "npmjs.com/package/@renoxar/koolie",
93
93
  "img.shields.io/pypi/v/koolie", "img.shields.io/npm/v/@renoxar/koolie",
94
- "img.shields.io/badge/Lizenz-GPL", "img.shields.io/badge/license-GPL")
94
+ "img.shields.io/badge/Lizenz-GPL", "img.shields.io/badge/license-GPL",
95
+ # die Adressen der Veroeffentlichung ueber Trusted Publishing, ebenso eng (2.0.0)
96
+ "test.pypi.org/legacy/", "test.pypi.org/simple/", "pypi.org/pypi/koolie/json",
97
+ "registry.npmjs.org")
95
98
  FENCE4_RE = re.compile(r"^`{4,}", re.M)
96
99
  MERMAID_RE = re.compile(r"```mermaid\n(.*?)```", re.S)
97
100
 
@@ -456,6 +459,20 @@ def check_skills(root: str, man: dict) -> None:
456
459
  # und werden nicht nach dessen Regeln geprueft - nur in der Laufzeitablage, nie in den
457
460
  # Quellen des Kerns (1.21.0, K-31). Den Korb verlangt Pruefung 72 weiter (D-238).
458
461
  fremd = fremde_praefixe(root)
462
+ # Mitgelieferte Skills teilen sich eine Skill-Ablage: Ein Name aus dem Kern und einer aus
463
+ # einem Pack duerfen nicht gleich lauten, sonst ueberschreibt die Aktivierung den anderen.
464
+ herkunft: dict[str, str] = {}
465
+ for skills_dir, prefix in skill_dirs(root, man):
466
+ if prefix == runtime:
467
+ continue
468
+ for name in sorted(os.listdir(skills_dir)):
469
+ if not os.path.isdir(os.path.join(skills_dir, name)):
470
+ continue
471
+ if name in herkunft:
472
+ err(f"{prefix}/{name}: Skillname schon vergeben in {herkunft[name]} - "
473
+ f"mitgelieferte Skills brauchen einen eindeutigen Namen")
474
+ else:
475
+ herkunft[name] = prefix
459
476
  for skills_dir, prefix in skill_dirs(root, man):
460
477
  # Die Modellwahl-Sperre wird nur in der *installierten* Fassung geprueft: In der
461
478
  # Quelle steht die Aussage als `triggers`, erst die Abbildung uebersetzt sie.
@@ -475,8 +492,8 @@ def check_skills_in(skills_dir: str, prefix: str, ids: dict[str, str],
475
492
  rel = f"{prefix}/{name}"
476
493
  if not re.fullmatch(r"[a-z0-9-]+", name):
477
494
  err(f"{rel}: Verzeichnisname muss aus Kleinbuchstaben, Ziffern, Bindestrichen bestehen")
478
- if not re.match(r"^(fw|prj|role-[a-z0-9]+|tech-[a-z0-9]+)-", name):
479
- warn(f"{rel}: Präfix entspricht nicht fw-/prj-/role-<pack>-/tech-<pack>-")
495
+ if not re.match(r"^(koolie|prj)-", name):
496
+ warn(f"{rel}: Präfix entspricht nicht koolie-/prj-")
480
497
  for req in ("SKILL.md", "EXAMPLES.md", "TESTS.md", "CHANGELOG.md"):
481
498
  if not os.path.exists(os.path.join(sdir, req)):
482
499
  err(f"{rel}: {req} fehlt")
@@ -1260,3 +1260,91 @@ def check_steckbrief(root: str) -> None:
1260
1260
  f"vor dem ersten Abschnitt. Klasse {klasse} trägt eine Tabelle "
1261
1261
  f"'{P94_KOPF}' mit Kennung, Version und Status – sonst unterscheidet das "
1262
1262
  f"Dokument keine zwei Stände (D-375)")
1263
+
1264
+
1265
+ # --- Pruefung 113: keine Kennung in der Produktdokumentation (CR-2026-173, D-540) -------
1266
+ # Die Produktdokumentation spricht zu Menschen, die Koolie benutzen. Woher eine Regel
1267
+ # kommt, steht in der Nachweisschicht: Decision Log, Aenderungsantraege, CHANGELOG,
1268
+ # Protokolle, Erhebungen, Roadmap. Ausgenommen sind ausserdem die Stellen der
1269
+ # Produktdokumentation, die selbst Nachweis sind: die Ergebnis- und Belegspalten der
1270
+ # Testblaetter und der Grenzfaelle, die Belegspalte der Faehigkeitsmatrix und die Zeilen eines
1271
+ # Versionsverlaufs. Vom Hauptdokument sind drei Kapitel Nachweis: die Grenzen und offenen
1272
+ # Entscheidungen, die Anhaenge mit der Quellenliste und der Abschluss (Owner 2026-10-02,
1273
+ # analog den vier Ausnahmen des Laufzeitglossars). Der Rest von build/ - Skripte, README,
1274
+ # Erzeugnisse - ist kein Produkttext.
1275
+ P113_RE = re.compile(r"(?<![A-Za-z0-9])(CR-\d{4}-\d{3}|D-\d{1,4}|K-\d{1,4})(?![0-9])")
1276
+ P113_NACHWEIS = (KERN + "/CHANGELOG.md", KERN + "/governance/DECISION_LOG.md",
1277
+ KERN + "/docs/ROADMAP.md")
1278
+ P113_NACHWEIS_ORDNER = (KERN + "/governance/change-requests/", KERN + "/tests/protocols/",
1279
+ KERN + "/tests/erhebungen/")
1280
+ P113_HAUPTDOKUMENT = KERN + "/build/doc/"
1281
+ P113_HAUPTDOKUMENT_NACHWEIS = ("29-grenzen.md", "31-anhaenge.md", "32-abschluss.md")
1282
+ P113_VERLAUF_RE = re.compile(r"^\|\s*\d+\.\d+\.\d+\s*\|")
1283
+ P113_BELEGKOPF_RE = re.compile(r"Ergebnis|Status|Beleg|Befund|Protokoll|Grundlage")
1284
+
1285
+
1286
+ def _p113_nachweis(rel: str) -> bool:
1287
+ if rel.startswith(KERN + "/build/"):
1288
+ return (not rel.startswith(P113_HAUPTDOKUMENT)
1289
+ or rel[len(P113_HAUPTDOKUMENT):] in P113_HAUPTDOKUMENT_NACHWEIS)
1290
+ return (rel in P113_NACHWEIS or rel.startswith(P113_NACHWEIS_ORDNER)
1291
+ or rel.endswith("/CHANGELOG.md"))
1292
+
1293
+
1294
+ def p113_fundstellen(rel: str, text: str) -> list:
1295
+ """[(Zeile, Kennung)] ausserhalb der Nachweisstellen eines Produkttraegers."""
1296
+ testblatt = rel.endswith(("/TESTS.md", "/TEST_CATALOG.md", "/EDGE_CASES.md"))
1297
+ pack = rel.startswith(KERN + "/clients/") and rel.endswith("/CLIENT_PACK.md")
1298
+ aus, kopf, matrix = [], None, False
1299
+ for nr, zeile in enumerate(text.replace("\r\n", "\n").split("\n"), 1):
1300
+ if zeile.startswith("## "):
1301
+ matrix = zeile.startswith("## 2. ")
1302
+ tabelle = zeile.startswith("|")
1303
+ if not tabelle:
1304
+ kopf = None
1305
+ elif not re.match(r"^\|[\s:|-]+\|?\s*$", zeile) and kopf is None:
1306
+ kopf = tabellenzellen(zeile)
1307
+ treffer = P113_RE.findall(zeile)
1308
+ if not treffer or P113_VERLAUF_RE.match(zeile):
1309
+ continue
1310
+ if tabelle and (testblatt or (pack and matrix)):
1311
+ zellen = tabellenzellen(zeile)
1312
+ if pack and matrix:
1313
+ frei = zellen[-1:] if zellen else []
1314
+ else:
1315
+ spalten = [i for i, k in enumerate(kopf or []) if P113_BELEGKOPF_RE.search(k)]
1316
+ frei = [zellen[i] for i in spalten if i < len(zellen)]
1317
+ erlaubt = [k for z in frei for k in P113_RE.findall(z)]
1318
+ for k in erlaubt:
1319
+ if k in treffer:
1320
+ treffer.remove(k)
1321
+ aus += [(nr, k) for k in treffer]
1322
+ return aus
1323
+
1324
+
1325
+ def check_kennungen_in_produktdoku(root: str) -> None:
1326
+ """Pruefung 113 (D-540): Keine CR-, D- oder K-Kennung ausserhalb der Nachweisschicht."""
1327
+ if not ist_quellrepositorium(root):
1328
+ return
1329
+ # SYNTHETISCH: K-99 ist eine belegte synthetische Kennung (Decision Log)
1330
+ gut = p113_fundstellen(KERN + "/docs/X.md", "Siehe K-99 und `CR-2026-001`.\n| 1.0.0 | K-99 |\n")
1331
+ if [k for _, k in gut] != ["K-99", "CR-2026-001"]:
1332
+ err("Pruefung 113: die eigene Selbstprobe traegt nicht mehr - die Pruefung haette "
1333
+ "ihren Gegenstand verloren und bestuende leise (D-23)")
1334
+ return
1335
+ for path in iter_text_files(root):
1336
+ if not path.endswith(".md"):
1337
+ continue
1338
+ rel = os.path.relpath(path, root).replace(os.sep, "/")
1339
+ # Das Overlay gehoert dem Projekt; im Quellrepositorium ist es eine lokale Saat.
1340
+ if rel.startswith(".koolie/project-overlay/"):
1341
+ continue
1342
+ if _p113_nachweis(rel) or not (rel.startswith(".koolie/") or "/" not in rel
1343
+ or rel.startswith("paketquellen/")):
1344
+ continue
1345
+ funde = p113_fundstellen(rel, read(path))
1346
+ if funde:
1347
+ erste = ", ".join(f"Z. {nr} {k}" for nr, k in funde[:3])
1348
+ err(f"{rel}: {len(funde)} Kennung(en) in der Produktdokumentation ({erste}"
1349
+ f"{' …' if len(funde) > 3 else ''}). Kennungen gehören in die Nachweisschicht "
1350
+ f"(Decision Log, Änderungsanträge, CHANGELOG); hier steht die Aussage selbst")
@@ -552,7 +552,7 @@ def _hook_lauf(interpreter: str, skript: str, eingabe: str) -> int:
552
552
  # Gemessen am 2026-09-13 (tests/protocols/2026-09-13-gegenpruefung-werkzeugabbildung.md):
553
553
  # DREI der vier Abbildungen brechen ab, wenn ihnen ein Verb fehlt - die vierte reichte
554
554
  # es woertlich durch, und sie kommt zweimal vor. Eine geleerte tool_names-Abbildung
555
- # lieferte 'tools: read, grep, glob' im Agentenprofil fw-reviewer, also drei Namen, die
555
+ # lieferte 'tools: read, grep, glob' im Agentenprofil koolie-reviewer, also drei Namen, die
556
556
  # dieser Client nicht kennt (M16); ein 'permissions.deny: glob' erzeugte lautlos keine
557
557
  # Sperre, und der Validator meldete 0 Fehler (M6).
558
558
  #
@@ -496,7 +496,7 @@ HOOK_UMSCHLAEGE = {
496
496
  # ist ein anderer - eine Pruefung, die ihre Grundlage benennt, darf sie nicht ueberholt
497
497
  # tragen. Und der Grundsatz aus D-62 gilt hier woertlich: Ein zusaetzliches Umschlagfeld
498
498
  # ist kein Pruefmaterial. Genau daran ist B06 gescheitert, mit transcript_path.
499
- HOOK_UMSCHLAG_UNTERAGENT = {"agent_id": "a1cae648c0189377c", "agent_type": "fw-reviewer"}
499
+ HOOK_UMSCHLAG_UNTERAGENT = {"agent_id": "a1cae648c0189377c", "agent_type": "koolie-reviewer"}
500
500
  KEIN_EREIGNIS = ("", " ", "[]", "null", '"x"', "42", '{"tool_input": {}}',
501
501
  '{"tool_name": "", "tool_input": {}}', '{"tool_name": "Write"}',
502
502
  '{"tool_name": "Write", "tool_input": "x"}')
@@ -758,7 +758,7 @@ def check_ungebundene_vorbedingung(root: str) -> None:
758
758
  #
759
759
  # ANLASS. Gemessen am 2026-09-18 im fuenften Sitzungstest (CR-2026-091). `FW-SC-01`
760
760
  # ist zum dritten Mal gefahren worden und zum dritten Mal nicht abnehmbar gewesen -
761
- # diesmal aus einem neuen Grund: Der Lauf hat NICHTS geaendert. `fw-change-small`
761
+ # diesmal aus einem neuen Grund: Der Lauf hat NICHTS geaendert. `koolie-change-small`
762
762
  # verlangt in Schritt 4, den Testbefehl VOR dem ersten Schreibzugriff auszufuehren;
763
763
  # im Messbaum stand `<TEST_COMMAND>` im `ask`-Korb, und `ask` ist im
764
764
  # nicht-interaktiven Betrieb eine Abweisung (D-134). Der Lauf hat angehalten und
@@ -775,7 +775,7 @@ def check_ungebundene_vorbedingung(root: str) -> None:
775
775
  # dessen Frontmatter einen Befehlsschlitz AUSFUEHRT (`Exec(<..._COMMAND>)` unter
776
776
  # `permissions`), muss diesen Schlitz in ihrer VORBEDINGUNG nennen.
777
777
  #
778
- # WARUM DAS FRONTMATTER UND NICHT DER FLIESSTEXT. `fw-plan` nennt `<TEST_COMMAND>`
778
+ # WARUM DAS FRONTMATTER UND NICHT DER FLIESSTEXT. `koolie-plan` nennt `<TEST_COMMAND>`
779
779
  # in seinen Vorbedingungen und in seiner Teststrategie - es fuehrt den Befehl aber
780
780
  # nicht aus, sondern plant ihn. Ein Zuschnitt ueber den Fliesstext haette `FW-FI-02`
781
781
  # mitgemeldet, dessen Lauf am 2026-09-18 keinen einzigen Befehl gebraucht hat. Das
@@ -868,7 +868,7 @@ def check_befehlsschlitz_in_vorbedingung(root: str) -> None:
868
868
  #
869
869
  # ANLASS. Gemessen am 2026-09-18 am Uebungsrepositorium (CR-2026-090, Befund 3): 0.63.0
870
870
  # hat die Sperre von .github/** auf .github/workflows/** EINGEENGT, weil sie sonst die
871
- # Merge-Request-Vorlage mitsperrt - einen Traeger, den fw-mr-description ausdruecklich
871
+ # Merge-Request-Vorlage mitsperrt - einen Traeger, den koolie-mr-description ausdruecklich
872
872
  # als zulaessige Kontextquelle fuehrt (D-161). Die Einengung steht in
873
873
  # .koolie/project-overlay/OVERLAY.md. Die beiden Traeger, die den Client WIRKLICH binden - die
874
874
  # Laufzeitfassung des Overlays und der deny-Korb der Berechtigungsdatei - tragen
@@ -1203,7 +1203,7 @@ def check_aktivierte_packs(root: str, man: dict) -> None:
1203
1203
  # Datei aendern. Seither deklariert das Projekt sie im Overlay-Manifest
1204
1204
  # ('fremde_skills: openspec-, speckit-'), und Pruefung 5 nimmt sie aus.
1205
1205
  #
1206
- # GEPRUEFT: FEHLER, wenn ein deklariertes Praefix einen Koolie-Skill treffen koennte (fw-,
1206
+ # GEPRUEFT: FEHLER, wenn ein deklariertes Praefix einen Koolie-Skill treffen koennte (koolie-,
1207
1207
  # prj-, role-, tech-, oder kuerzer als drei Zeichen) - die Deklaration waere sonst ein Weg,
1208
1208
  # die eigenen Skills der Pruefung zu entziehen; ein solches Praefix nimmt nichts aus.
1209
1209
  # WARNUNG, wenn ein Praefix keinen Skill der Laufzeitablage trifft (Deklaration ohne
@@ -1238,7 +1238,7 @@ def check_fremde_skills(root: str, man: dict) -> None:
1238
1238
  for p in deklariert:
1239
1239
  if not koexistenz.zulaessig(p):
1240
1240
  err(f"{rel}: fremde_skills nennt '{p}' - das Praefix koennte einen Koolie-Skill "
1241
- f"treffen (fw-, prj-, role-, tech-) und nimmt deshalb nichts aus (D-514)")
1241
+ f"treffen (koolie-, prj-) und nimmt deshalb nichts aus (D-514)")
1242
1242
  elif not any(s.startswith(p) for s in skills):
1243
1243
  warn(f"{rel}: fremde_skills nennt '{p}', aber kein Skill in {man['skills_dir']}/ "
1244
1244
  f"beginnt damit - eine Deklaration ohne Gegenstand (D-514)")
@@ -405,7 +405,7 @@ def _uebungsskills(root: str) -> dict:
405
405
  continue
406
406
  if aktuell is None:
407
407
  continue
408
- for treffer in re.findall(r"/(fw-[a-z0-9-]+)", zeile):
408
+ for treffer in re.findall(r"/(koolie-[a-z0-9-]+)", zeile):
409
409
  if treffer not in raus[aktuell]:
410
410
  raus[aktuell].append(treffer)
411
411
  if not raus:
@@ -562,7 +562,7 @@ def check_ergebnisstand(root: str) -> None:
562
562
  # dreizehn Blaetter und filtern auf `sitzung`: Pruefung 49 (D-146, seit 0.60.0) und
563
563
  # Pruefung 60 (D-178, seit 0.66.0). Beide hatten dort NULL Gegenstand. Nach der
564
564
  # Umstellung meldete Pruefung 60 beim ersten Lauf ZWANZIG Zellen - in genau den drei
565
- # Blaettern, deren Skill einen Befehl ausfuehrt (fw-change-small, fw-refactor, fw-tests).
565
+ # Blaettern, deren Skill einen Befehl ausfuehrt (koolie-change-small, koolie-refactor, koolie-tests).
566
566
  # Das ist die Bauform "Die Regel als Ausfuellschlitz" (0.61.0) eine Ebene hoeher: Nicht
567
567
  # die Regel stand in zwei Ausdrucksformen, sondern ihr GEGENSTAND.
568
568
  #
@@ -759,12 +759,12 @@ def check_nummernverweis(root: str) -> None:
759
759
  # zwoelf Skills. Sie ist durchgehend HANDLUNGSMARKE - "Fall X | [RUECKFRAGE]"
760
760
  # heisst `frage zurueck`, nicht `schreibe die Zeichenfolge`.
761
761
  #
762
- # `[HALT]` ist beides, je nach Skill: Ausgabemarke in `fw-plan`, `fw-bugfix-prepare`
763
- # und `fw-change-small` (Abschnitt 5 UND 6), Handlungsmarke in den uebrigen neun.
762
+ # `[HALT]` ist beides, je nach Skill: Ausgabemarke in `koolie-plan`, `koolie-bugfix-prepare`
763
+ # und `koolie-change-small` (Abschnitt 5 UND 6), Handlungsmarke in den uebrigen neun.
764
764
  # Und wo sie Abnahmekriterium ist, sagt Abschnitt 6 "ist ERKENNBAR", nicht "woertlich".
765
765
  #
766
766
  # GEMESSEN HAT ES EIN LAUF. `sk004n01` (Buendel 2, 2026-09-19) schrieb `[HALT]`
767
- # woertlich - Abschnitt 6 von `fw-plan` sagt "der Skill endet mit [HALT]" - und
767
+ # woertlich - Abschnitt 6 von `koolie-plan` sagt "der Skill endet mit [HALT]" - und
768
768
  # `[RUECKFRAGE]` nicht. Der Lauf hat sich richtig verhalten; die Zelle verlangte mehr,
769
769
  # als ihr Skill vorschreibt. Ueber alle dreizehn Blaetter: 18 Nennungen in 17 Zellen
770
770
  # ungedeckt, 10 gedeckt.
@@ -18,7 +18,7 @@ import sys
18
18
 
19
19
  from .gemeinsam import (
20
20
  _clientmap, _verfolgte_dateien, err, hinweis, ist_quellrepositorium,
21
- iter_text_files, KERN, nicht_geliefert, PAKET_JE_SKRIPT, read, warn)
21
+ iter_text_files, KERN, nicht_geliefert, PAKET_JE_SKRIPT, read, warn, yaml)
22
22
 
23
23
 
24
24
  # --- 45: Der Bytecode des Kerns gehoert nicht in die Versionierung (D-97) -----------
@@ -868,7 +868,12 @@ def check_wirksamkeitsprobe(root: str) -> None:
868
868
  # paketquellen/ ohne Befund - seine Nachpruefung haelt Dateimenge, Version, RECORD,
869
869
  # die Ziele der Befehle, das Fehlen eines npm-Installationsskripts und die
870
870
  # Pruefsumme in beiden Manifesten; seit 1.24.0 auch die Beschreibung fuer PyPI und
871
- # npm ohne relativen Link (D-528) - und dasselbe fuer die Vorabversion --vorab 1 (D-529).
871
+ # npm ohne relativen Link (D-528) - und dasselbe fuer die Vorabversion --vorab 1 (D-529);
872
+ # (d) die Veroeffentlichung ueber Trusted Publishing (2.0.0, K-210): .github/workflows/
873
+ # publish.yml laeuft nur an einer Marke v*, gibt dem Workflow nur Leserecht, heftet jede
874
+ # Action an einen Commit, prueft Signatur und VERSION der Marke im ersten Job, gibt
875
+ # id-token nur Jobs mit Umgebung und laesst PyPI und npm (Umgebung release) erst nach
876
+ # TestPyPI (Umgebung testpypi) laufen.
872
877
  # GRENZE: Ob eine Paketquelle dem Befehl ein Terminal gibt, prueft keine Pruefung - das ist
873
878
  # gemessen (Protokoll 2026-09-30-paketquellen: pip, uv, npm, Scoop). Die Homebrew-Formel ist
874
879
  # gebaut, nicht gemessen. Die Veroeffentlichung erreicht keine Pruefung (D-521); ob die
@@ -877,6 +882,79 @@ P112_DATEIEN = ("paketquellen/bauen.py", "paketquellen/koolie_befehl.py",
877
882
  "paketquellen/koolie.cmd", "paketquellen/npm/koolie.js")
878
883
 
879
884
 
885
+ P112_WORKFLOW = ".github/workflows/publish.yml"
886
+ P112_ACTION_RE = re.compile(r"^[\w.-]+/[\w./-]+@[0-9a-f]{40}$")
887
+
888
+
889
+ def _p112_workflow(root: str) -> None:
890
+ """Gegenstand (d): Die Workflow-Datei veroeffentlicht nur eine signierte Marke, nach TestPyPI."""
891
+ pfad = os.path.join(root, *P112_WORKFLOW.split("/"))
892
+ if not os.path.isfile(pfad):
893
+ err(f"{P112_WORKFLOW}: fehlt - ohne sie veroeffentlicht keine Marke auf PyPI und npm "
894
+ f"(Pruefung 112)")
895
+ return
896
+ if yaml is None:
897
+ hinweis(f"{P112_WORKFLOW}: PyYAML fehlt, Gegenstand (d) der Pruefung 112 nicht geprueft")
898
+ return
899
+ try:
900
+ wf = yaml.safe_load(read(pfad)) or {}
901
+ except yaml.YAMLError as fehler:
902
+ err(f"{P112_WORKFLOW}: kein gueltiges YAML ({type(fehler).__name__}) (Pruefung 112)")
903
+ return
904
+ # YAML 1.1 liest den Schluessel 'on' als True.
905
+ ausloeser = wf.get("on", wf.get(True))
906
+ if ausloeser != {"push": {"tags": ["v*"]}}:
907
+ err(f"{P112_WORKFLOW}: laeuft nicht nur an einer Marke v* ({ausloeser!r}) - jeder andere "
908
+ f"Ausloeser veroeffentlichte ohne signierte Marke (Pruefung 112)")
909
+ if wf.get("permissions") != {"contents": "read"}:
910
+ err(f"{P112_WORKFLOW}: die Rechte des Workflows sind nicht auf 'contents: read' "
911
+ f"beschraenkt (Pruefung 112)")
912
+ jobs = wf.get("jobs") or {}
913
+ umgebung = {}
914
+ for name, job in jobs.items():
915
+ u = job.get("environment")
916
+ umgebung[name] = u.get("name") if isinstance(u, dict) else u
917
+ for schritt in job.get("steps") or []:
918
+ uses = schritt.get("uses")
919
+ if uses and not P112_ACTION_RE.match(uses):
920
+ err(f"{P112_WORKFLOW}: Job '{name}' nutzt '{uses}' ohne festen Commit - ein "
921
+ f"bewegliches Tag kann den Code der Veroeffentlichung aendern (Pruefung 112)")
922
+ if (job.get("permissions") or {}).get("id-token") and not umgebung[name]:
923
+ err(f"{P112_WORKFLOW}: Job '{name}' darf ein id-token holen, hat aber keine Umgebung "
924
+ f"(Pruefung 112)")
925
+
926
+ def vorgaenger(name: str, gesehen: set) -> set:
927
+ needs = jobs.get(name, {}).get("needs") or []
928
+ for n in [needs] if isinstance(needs, str) else needs:
929
+ if n not in gesehen:
930
+ gesehen.add(n)
931
+ vorgaenger(n, gesehen)
932
+ return gesehen
933
+
934
+ def skript(name: str) -> str:
935
+ return "\n".join(s.get("run", "") for s in jobs[name].get("steps") or [])
936
+
937
+ pruef = [n for n in jobs if "git tag -v" in skript(n) and "KOOLIE_ALLOWED_SIGNERS"
938
+ in str(jobs[n]) and ".koolie/core/VERSION" in skript(n)]
939
+ test = [n for n, u in umgebung.items() if u == "testpypi"]
940
+ frei = [n for n, u in umgebung.items() if u == "release"]
941
+ if not pruef:
942
+ err(f"{P112_WORKFLOW}: kein Job prueft Signatur und VERSION der Marke ('git tag -v' gegen "
943
+ f"KOOLIE_ALLOWED_SIGNERS) (Pruefung 112)")
944
+ if not test or not frei:
945
+ err(f"{P112_WORKFLOW}: es fehlt ein Job mit Umgebung 'testpypi' oder 'release' "
946
+ f"(Pruefung 112)")
947
+ return
948
+ for n in test:
949
+ if pruef and not set(pruef) & vorgaenger(n, set()):
950
+ err(f"{P112_WORKFLOW}: Job '{n}' (TestPyPI) haengt nicht an der Pruefung der Marke "
951
+ f"(Pruefung 112)")
952
+ for n in frei:
953
+ if not set(test) & vorgaenger(n, set()):
954
+ err(f"{P112_WORKFLOW}: Job '{n}' (PyPI und npm) laeuft nicht erst nach TestPyPI - "
955
+ f"die Probe muss vor der Veroeffentlichung abbrechen koennen (Pruefung 112)")
956
+
957
+
880
958
  def _p112_befehl(root: str, *argv: str, ohne_banner: bool = False, cwd: str | None = None,
881
959
  eingabe: str | None = None) -> str:
882
960
  import subprocess
@@ -900,6 +978,7 @@ def check_paketquellen(root: str) -> None:
900
978
  err(f"{fehlend[0]}: fehlt - ohne diese Datei baut keine Paketquelle den Befehl "
901
979
  f"'koolie' (Pruefung 112, D-520)")
902
980
  return
981
+ _p112_workflow(root)
903
982
  version = read(os.path.join(root, *KERN.split("/"), "VERSION")).strip()
904
983
  try:
905
984
  aus = _p112_befehl(root, "--version")
@@ -53,7 +53,7 @@ def lade(name, pfad):
53
53
  sys.path.insert(0, sys.argv[2])
54
54
  vo = lade("_vo407", sys.argv[1])
55
55
  mw = lade("_mw407", sys.argv[3])
56
- pfad, grund = vo.skill_pfad(sys.argv[4], "fw-code-explain")
56
+ pfad, grund = vo.skill_pfad(sys.argv[4], "koolie-code-explain")
57
57
  pack, _ = mw._manifest(sys.argv[4])
58
58
  print(json.dumps({"pfad": pfad, "grund": grund, "pack": pack}))
59
59
  """
@@ -95,7 +95,7 @@ def sonden_messapparat() -> None:
95
95
  ist = json.loads((q.stdout or "").strip().splitlines()[-1])
96
96
  except (ValueError, IndexError):
97
97
  ist = {}
98
- erwartet = os.path.join(root, ".claude", "skills", "fw-code-explain", "SKILL.md")
98
+ erwartet = os.path.join(root, ".claude", "skills", "koolie-code-explain", "SKILL.md")
99
99
  ok = (p.returncode == 0 and q.returncode == 0 and ist.get("pack") == "claude-code"
100
100
  and os.path.normcase(ist.get("pfad") or "") == os.path.normcase(erwartet))
101
101
  melde("SONDE", "D407", ok,
@@ -207,7 +207,7 @@ buendel(sonden_importkanaele,
207
207
  # bricht die Installation ab, statt eine halb gekuerzte Zelle weiterzugeben.
208
208
  M471_ERSATZ = "(D-471)"
209
209
  M471_ABBRUCH = "nicht sicher kuerzbar"
210
- P471_BLATT = ("framework", "skills", "fw-refactor", "TESTS.md")
210
+ P471_BLATT = ("framework", "skills", "koolie-refactor", "TESTS.md")
211
211
  P471_BELEG = "tests/protocols/2026-09-26-testblaetter-modellwechsel.md"
212
212
 
213
213
 
@@ -493,7 +493,7 @@ def sonden_kiro() -> None:
493
493
  for x in d["permissions"]["rules"]
494
494
  if x.get("exclude")])),
495
495
  ("D416", "Pruefung 72: Skill ohne Freigaberegel", M416_SKILL,
496
- lambda r: _414_profil(r, lambda d: _414_regeln_ohne(d, "skill", "allow", "fw-plan"))),
496
+ lambda r: _414_profil(r, lambda d: _414_regeln_ohne(d, "skill", "allow", "koolie-plan"))),
497
497
  )
498
498
  # Die Kennungen stehen unten WOERTLICH: Pruefung 40 liest die Sondenmenge aus dem
499
499
  # Quelltext (melde("SONDE", "<nr>")), und eine Kennung in einer Variablen ist fuer
@@ -590,7 +590,7 @@ def sonden_cursor() -> None:
590
590
  hooks = json.loads(lies(os.path.join(root, ".cursor", "hooks.json")))
591
591
  kern = lies(os.path.join(root, ".cursor", "rules", "00-framework-core.mdc"))
592
592
  vorlage = lies(os.path.join(root, ".cursor", "rules", "40-tech-TEMPLATE.mdc.template"))
593
- agent = lies(os.path.join(root, ".cursor", "agents", "fw-reviewer.md"))
593
+ agent = lies(os.path.join(root, ".cursor", "agents", "koolie-reviewer.md"))
594
594
  ignore = lies(os.path.join(root, ".cursorignore")).splitlines()
595
595
  deny = cli.get("permissions", {}).get("deny", [])
596
596
  pre = hooks.get("hooks", {}).get("preToolUse", [])
@@ -717,7 +717,7 @@ buendel(sonden_cursor,
717
717
  P98_HOOK = ".koolie/core/tests/scripts/hook-check-secrets.py".replace("/", os.sep)
718
718
  P99_MANDAT = ".koolie/core/mandat.py".replace("/", os.sep)
719
719
  P99_RECHTE = ".koolie/core/framework/runtime/permissions.json".replace("/", os.sep)
720
- P100_SKILL = ".koolie/core/framework/skills/fw-docs-update/SKILL.md".replace("/", os.sep)
720
+ P100_SKILL = ".koolie/core/framework/skills/koolie-docs-update/SKILL.md".replace("/", os.sep)
721
721
  M98_INHALT = "weil sein Inhalt geschuetzte Pfade NENNT"
722
722
  M98_ANKER = "Pruefung 98 misst"
723
723
  M99_WERTE = "fuehren verschiedene Werte fuer"
@@ -84,9 +84,9 @@ gegenprobe("102b", "Pruefung 102: ein neuer Punkt mit Markierung und Ziel in der
84
84
  # einer, die sich selbst bestaetigt.
85
85
  M103_VERALTET = "Belegstand veraltet"
86
86
  M103_LEER = "ein Stand ohne Gegenstand belegt nichts"
87
- P103_BLATT = ".koolie/core/framework/skills/fw-refactor/TESTS.md".replace("/", os.sep)
88
- P103_ANKER = "`validate-output.py --skill fw-refactor`: **bestanden**."
89
- P103_GEGENSTAND = "framework/skills/fw-refactor/SKILL.md"
87
+ P103_BLATT = ".koolie/core/framework/skills/koolie-refactor/TESTS.md".replace("/", os.sep)
88
+ P103_ANKER = "`validate-output.py --skill koolie-refactor`: **bestanden**."
89
+ P103_GEGENSTAND = "framework/skills/koolie-refactor/SKILL.md"
90
90
 
91
91
 
92
92
  def _103_stand(root: str, pfade: list) -> str:
@@ -108,7 +108,7 @@ def _103_veraltet(root: str) -> None:
108
108
 
109
109
 
110
110
  def _103_ohne_gegenstand(root: str) -> None:
111
- _103_marke(root, "0123456789ab", "framework/skills/fw-refactor/GIBTESNICHT.md")
111
+ _103_marke(root, "0123456789ab", "framework/skills/koolie-refactor/GIBTESNICHT.md")
112
112
 
113
113
 
114
114
  def _103_passend(root: str) -> None:
@@ -648,7 +648,7 @@ def _zeile_mit_summe(root: str) -> None:
648
648
  ersetze(pfad,
649
649
  ("| `[TECHNISCH]` | 22 von 32 |", "| `[TECHNISCH]` | 23 von 33 |"),
650
650
  ("| 8 von 32 (", "| 8 von 33 ("),
651
- ("| **2 von 32** (", "| **2 von 33** ("),
651
+ ("| 2 von 32 (", "| 2 von 33 ("),
652
652
  ("| 0 von 32 |", "| 0 von 33 |"))
653
653
  # Seit 0.36.0 rechnet Pruefung 31 dieselbe Zahl auch in der Uebersicht der Ablage nach
654
654
  # (D-71). Eine Gegenprobe, die nur das Pack nachzieht, faellt seither an der zweiten
@@ -822,7 +822,7 @@ def sonden_skill_deny() -> None:
822
822
  """Wirkungsnachweis der Abbildung und ihrer Grenzen (D-64 bis D-66)."""
823
823
  root = installation("claude-code")
824
824
  try:
825
- plan = _p33(root, "fw-plan")
825
+ plan = _p33(root, "koolie-plan")
826
826
  ausgang = lies(plan)
827
827
 
828
828
  # --- Gegenprobe: die unveraenderte Installation laeuft durch ----------------
@@ -840,7 +840,7 @@ def sonden_skill_deny() -> None:
840
840
  schreib(plan, ersetzt(
841
841
  ausgang,
842
842
  ("disallowed-tools: Edit, Write, NotebookEdit, Bash, PowerShell\n", ""),
843
- quelle="fw-plan/SKILL.md"))
843
+ quelle="koolie-plan/SKILL.md"))
844
844
  aus = validator_ausgabe(root)
845
845
  melde("SONDE", "33a", "aus permissions.deny der Quelle ergibt sich" in aus,
846
846
  "Fehlende Werkzeugsperre - der Stand, den B01 beschrieb")
@@ -850,7 +850,7 @@ def sonden_skill_deny() -> None:
850
850
  ausgang,
851
851
  ("disallowed-tools: Edit, Write, NotebookEdit, Bash, PowerShell",
852
852
  "disallowed-tools: Edit, Write"),
853
- quelle="fw-plan/SKILL.md"))
853
+ quelle="koolie-plan/SKILL.md"))
854
854
  aus = validator_ausgabe(root)
855
855
  melde("SONDE", "33b", "aus permissions.deny der Quelle ergibt sich" in aus,
856
856
  "Unvollstaendige Sperre - mit gesperrtem Write, Edit schrieb der Skill ueber Bash")
@@ -860,7 +860,7 @@ def sonden_skill_deny() -> None:
860
860
  ausgang,
861
861
  ("disallowed-tools: Edit, Write, NotebookEdit, Bash, PowerShell",
862
862
  "disallowed-tools: Edit, Write, NotebookEdit, Bash(git push:*), PowerShell"),
863
- quelle="fw-plan/SKILL.md"))
863
+ quelle="koolie-plan/SKILL.md"))
864
864
  aus = validator_ausgabe(root)
865
865
  melde("SONDE", "33c", "Argumentmuster" in aus,
866
866
  "Argumentmuster in der Sperre - es sieht aus wie eine Regel und ist keine")
@@ -870,7 +870,7 @@ def sonden_skill_deny() -> None:
870
870
  ausgang,
871
871
  ("allowed-tools: Read, Grep, Glob",
872
872
  "allowed-tools: Read, Grep, Glob, Bash"),
873
- quelle="fw-plan/SKILL.md"))
873
+ quelle="koolie-plan/SKILL.md"))
874
874
  aus = validator_ausgabe(root)
875
875
  melde("SONDE", "33d", "steht zugleich in allowed-tools" in aus,
876
876
  "Werkzeug zugleich vorabfreigegeben und gesperrt")
@@ -1003,7 +1003,7 @@ gegenprobe("34", "Die unveraenderten Packs bleiben unbeanstandet - eines nennt,
1003
1003
  # sobald es den Fall gibt. Gemessen ist der Befund dahinter am 2026-09-13, Lauf
1004
1004
  # STARTLOS: Ein Profil mit tools: Read, Grep, Glob kann keine zweite Ebene oeffnen.
1005
1005
  MANIFEST_CC_35 = ".koolie/core/clients/claude-code/manifest.json"
1006
- PROFIL_35 = ".koolie/core/framework/runtime/agents/fw-reviewer.md"
1006
+ PROFIL_35 = ".koolie/core/framework/runtime/agents/koolie-reviewer.md"
1007
1007
 
1008
1008
 
1009
1009
  def _35_abbildung_erweitern(root: str) -> None:
@@ -305,9 +305,9 @@ def sonden_berechtigungskoerbe() -> None:
305
305
  # Skill bleibt einer.
306
306
  skillablage = os.path.join(root, ".claude", "skills")
307
307
  quelle = os.path.join(root, ".koolie/core", "framework", "role-packs",
308
- "requirements-engineering", "skills", "role-re-ticket")
309
- shutil.copytree(quelle, os.path.join(skillablage, "role-re-ticket"))
310
- _37_schreiben(root, lambda d: _37_dazu(d, "allow", "Skill(role-re-ticket)"))
308
+ "requirements-engineering", "skills", "koolie-ticket")
309
+ shutil.copytree(quelle, os.path.join(skillablage, "koolie-ticket"))
310
+ _37_schreiben(root, lambda d: _37_dazu(d, "allow", "Skill(koolie-ticket)"))
311
311
  aus = validator_ausgabe(root)
312
312
  melde("GEGENPROBE", "37c", MELDUNG_ZUVIEL not in aus,
313
313
  "Vollstaendig aktiviertes Role Pack - Skill in der Ablage UND im Korb, "
@@ -323,7 +323,7 @@ def sonden_berechtigungskoerbe() -> None:
323
323
  "Dieselbe Schreibweise auf einen Namen ohne Skill in der Ablage bleibt "
324
324
  "eine Ausweitung - der Zuschnitt haengt an der Ablage, nicht am Wort")
325
325
  schreib(pfad, ausgang)
326
- shutil.rmtree(os.path.join(skillablage, "role-re-ticket"))
326
+ shutil.rmtree(os.path.join(skillablage, "koolie-ticket"))
327
327
 
328
328
  # --- 37g: der verlorene Anker ----------------------------------------------
329
329
  cm = os.path.join(root, ".koolie/core", "clientmap.py")
@@ -354,7 +354,7 @@ buendel(sonden_berechtigungskoerbe,
354
354
  # woertlich als Werkzeugname durchgereicht, in permissions.deny fiel es lautlos aus.
355
355
  MANIFEST_CC_38 = ".koolie/core/clients/claude-code/manifest.json"
356
356
  MANIFEST_DD_38 = ".koolie/core/clients/devin-desktop/manifest.json"
357
- SKILL_38 = ".koolie/core/framework/skills/fw-plan/SKILL.md"
357
+ SKILL_38 = ".koolie/core/framework/skills/koolie-plan/SKILL.md"
358
358
  CLIENTMAP_38 = ".koolie/core/clientmap.py"
359
359
 
360
360
 
@@ -504,19 +504,19 @@ def _p39(root: str) -> str:
504
504
  def _39_regel_fehlt(root: str) -> None:
505
505
  """Ein ausgelieferter Skill verliert seine Freigabe - der Zustand vor 0.41.0."""
506
506
  ersetze(_p39(root),
507
- (' { "tool": "skill", "pattern": "fw-code-explain" },\r\n', ""))
507
+ (' { "tool": "skill", "pattern": "koolie-code-explain" },\r\n', ""))
508
508
 
509
509
 
510
510
  def _39_regel_ohne_skill(root: str) -> None:
511
511
  """Eine Freigabe fuer einen Skill, den es nicht gibt."""
512
512
  ersetze(_p39(root),
513
- ('"pattern": "fw-code-explain" }', '"pattern": "fw-code-erklaeren" }'))
513
+ ('"pattern": "koolie-code-explain" }', '"pattern": "koolie-code-erklaeren" }'))
514
514
 
515
515
 
516
516
  def _39_muster(root: str) -> None:
517
517
  """Das Praefixmuster, das gemessen nichts freigibt (D-82)."""
518
518
  ersetze(_p39(root),
519
- ('"pattern": "fw-code-explain" }', '"pattern": "fw-*" }'))
519
+ ('"pattern": "koolie-code-explain" }', '"pattern": "koolie-*" }'))
520
520
 
521
521
 
522
522
  def _39_anker_weg(root: str) -> None:
@@ -541,9 +541,9 @@ def _39_traeger_weg(root: str) -> None:
541
541
 
542
542
  def _39_skill_ohne_regel(root: str) -> None:
543
543
  """Ein neuer Skill im Verzeichnis, ohne dass jemand die Freigabe nachtraegt."""
544
- quelle = P(root, ".koolie/core/framework/skills/fw-code-explain"
544
+ quelle = P(root, ".koolie/core/framework/skills/koolie-code-explain"
545
545
  .replace("/", os.sep))
546
- ziel = P(root, ".koolie/core/framework/skills/fw-zwischenstand"
546
+ ziel = P(root, ".koolie/core/framework/skills/koolie-zwischenstand"
547
547
  .replace("/", os.sep))
548
548
  shutil.copytree(quelle, ziel)
549
549
 
@@ -572,7 +572,7 @@ sonde("39e", "Ein Regeltraeger verliert die Skillwahl",
572
572
  _39_traeger_weg, "die Skillwahl fehlt")
573
573
 
574
574
  sonde("39f", "Ein neuer Skill, dessen Freigabe niemand nachtraegt",
575
- _39_skill_ohne_regel, "'fw-zwischenstand' hat keine allow-Regel")
575
+ _39_skill_ohne_regel, "'koolie-zwischenstand' hat keine allow-Regel")
576
576
 
577
577
  gegenprobe("39a", "Die unveraenderte Datei bleibt unbeanstandet - zwoelf Regeln, zwoelf "
578
578
  "Skills", None, "allow-Regel")