kingmadoc 0.3.0.dev9__tar.gz → 0.3.0.dev10__tar.gz

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 (198) hide show
  1. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/.featuredoc.yml +16 -7
  2. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/CHANGELOG.md +71 -0
  3. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/CLAUDE.md +23 -1
  4. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/PKG-INFO +27 -6
  5. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/README.md +24 -5
  6. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/docs/index.md +6 -1
  7. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/README.md +11 -0
  8. kingmadoc-0.3.0.dev10/evals/results/2026-09-28T064505Z.json +159 -0
  9. kingmadoc-0.3.0.dev10/evals/results/2026-09-28T092643Z.json +173 -0
  10. kingmadoc-0.3.0.dev10/evals/results/2026-09-28T093046Z.json +61 -0
  11. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/scenarios/explain-branch.yml +1 -0
  12. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/scenarios/explain-feature.yml +1 -0
  13. kingmadoc-0.3.0.dev10/evals/scenarios/explain-fo-to.yml +26 -0
  14. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/examples/verify-mode-plan.md +88 -9
  15. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/pyproject.toml +12 -2
  16. kingmadoc-0.3.0.dev10/scripts/build_threat_reference.py +16 -0
  17. kingmadoc-0.3.0.dev10/scripts/import_tmt_knowledge_base.py +120 -0
  18. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/scripts/run_evals.py +23 -2
  19. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/SKILL.md +17 -2
  20. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/codex.md +123 -17
  21. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/copilot.md +123 -17
  22. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/cursor.md +123 -17
  23. kingmadoc-0.3.0.dev10/skill/explaining-code/SKILL.md +203 -0
  24. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/explaining-code/reference/arc42.md +90 -19
  25. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/explaining-code/reference/c4-model.md +1 -5
  26. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/explaining-code/reference/c4.md +15 -4
  27. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/explaining-code/reference/models.md +15 -13
  28. kingmadoc-0.3.0.dev10/skill/explaining-code/reference/split.md +249 -0
  29. kingmadoc-0.3.0.dev10/skill/explaining-code/reference/stories.md +73 -0
  30. kingmadoc-0.3.0.dev10/skill/explaining-code/reference/threat-model.md +122 -0
  31. kingmadoc-0.3.0.dev10/skill/explaining-code/reference/threats.md +104 -0
  32. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/reference/formats.md +106 -15
  33. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/cli.py +259 -32
  34. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/config.py +105 -12
  35. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/exceptions.py +8 -0
  36. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/explain.py +52 -0
  37. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/plan/generator.py +5 -2
  38. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/plan/models.py +93 -29
  39. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/raster.py +9 -3
  40. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/render.py +21 -10
  41. kingmadoc-0.3.0.dev10/src/kingmadoc/scaffold.py +353 -0
  42. kingmadoc-0.3.0.dev10/src/kingmadoc/screenshots.py +124 -0
  43. kingmadoc-0.3.0.dev10/src/kingmadoc/templates/functional_design.md.j2 +190 -0
  44. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/templates/technical_design.md.j2 +41 -1
  45. kingmadoc-0.3.0.dev10/src/kingmadoc/threats/__init__.py +8 -0
  46. kingmadoc-0.3.0.dev10/src/kingmadoc/threats/filters.py +123 -0
  47. kingmadoc-0.3.0.dev10/src/kingmadoc/threats/knowledge_base.py +122 -0
  48. kingmadoc-0.3.0.dev10/src/kingmadoc/threats/model.py +194 -0
  49. kingmadoc-0.3.0.dev10/src/kingmadoc/threats/report.py +273 -0
  50. kingmadoc-0.3.0.dev10/src/kingmadoc/threats/sdl_knowledge_base.json +1574 -0
  51. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_config_shape.py +10 -0
  52. kingmadoc-0.3.0.dev10/tests/test_design_diagrams_compile.py +69 -0
  53. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_diagram_backends.py +3 -2
  54. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_evals.py +3 -1
  55. kingmadoc-0.3.0.dev10/tests/test_explain_check.py +76 -0
  56. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_explain_config.py +30 -1
  57. kingmadoc-0.3.0.dev10/tests/test_functional_design.py +297 -0
  58. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_render.py +70 -3
  59. kingmadoc-0.3.0.dev10/tests/test_scaffold.py +159 -0
  60. kingmadoc-0.3.0.dev10/tests/test_screenshots.py +110 -0
  61. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_security_domain_designs.py +7 -6
  62. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_skill.py +1 -1
  63. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_skill_explaining_code.py +149 -0
  64. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_technical_design.py +4 -0
  65. kingmadoc-0.3.0.dev10/tests/test_threats.py +218 -0
  66. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/uv.lock +113 -1
  67. kingmadoc-0.3.0.dev9/skill/explaining-code/SKILL.md +0 -254
  68. kingmadoc-0.3.0.dev9/skill/explaining-code/reference/split.md +0 -142
  69. kingmadoc-0.3.0.dev9/src/kingmadoc/templates/functional_design.md.j2 +0 -86
  70. kingmadoc-0.3.0.dev9/tests/test_functional_design.py +0 -120
  71. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  72. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  73. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/.github/workflows/ci.yml +0 -0
  74. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/.github/workflows/release.yml +0 -0
  75. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/.gitignore +0 -0
  76. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/CONTRIBUTING.md +0 -0
  77. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/LICENSE +0 -0
  78. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/docs/conventions.md +0 -0
  79. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/docs/releasing.md +0 -0
  80. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/docs/roadmap.md +0 -0
  81. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/docs/test-plan.md +0 -0
  82. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop/manage.py +0 -0
  83. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop/requirements.txt +0 -0
  84. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop/shop/__init__.py +0 -0
  85. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop/shop/models.py +0 -0
  86. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop/shop/services.py +0 -0
  87. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop/shop/settings.py +0 -0
  88. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop/shop/urls.py +0 -0
  89. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop/shop/views.py +0 -0
  90. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop-discount/shop/discounts.py +0 -0
  91. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/fixtures/shop-discount/shop/services.py +0 -0
  92. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/results/2026-09-27T111837Z.json +0 -0
  93. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/results/2026-09-27T112600Z.json +0 -0
  94. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/results/2026-09-27T162715Z.json +0 -0
  95. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/evals/scenarios/plan-feature.yml +0 -0
  96. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/scripts/build_skill_variants.py +0 -0
  97. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/skill/reference/diagram-rules.md +0 -0
  98. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/__init__.py +0 -0
  99. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/about.py +0 -0
  100. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/adr.py +0 -0
  101. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/d2_binary.py +0 -0
  102. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/diagrams/__init__.py +0 -0
  103. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/diagrams/base.py +0 -0
  104. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/diagrams/d2.py +0 -0
  105. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/diagrams/mermaid.py +0 -0
  106. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/diagrams/plantuml.py +0 -0
  107. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/documents.py +0 -0
  108. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/__init__.py +0 -0
  109. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/branch.py +0 -0
  110. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/collect.py +0 -0
  111. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/data_model.py +0 -0
  112. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/dominators.py +0 -0
  113. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/js_modules.py +0 -0
  114. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/projects.py +0 -0
  115. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/routes.py +0 -0
  116. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/facts/services.py +0 -0
  117. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/git.py +0 -0
  118. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/naming.py +0 -0
  119. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/plan/__init__.py +0 -0
  120. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/plan/analyzer.py +0 -0
  121. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/plan/dependencies.py +0 -0
  122. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/plandoc.py +0 -0
  123. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/skills.py +0 -0
  124. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/templates/adr.md.j2 +0 -0
  125. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/templates/domain_design.md.j2 +0 -0
  126. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/templates/plan_default.md.j2 +0 -0
  127. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/templates/security_design.md.j2 +0 -0
  128. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/templating.py +0 -0
  129. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/verify/__init__.py +0 -0
  130. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/verify/changes.py +0 -0
  131. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/verify/commands.py +0 -0
  132. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/verify/deviations.py +0 -0
  133. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/verify/locate.py +0 -0
  134. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/verify/report.py +0 -0
  135. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/src/kingmadoc/vscode.py +0 -0
  136. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/conftest.py +0 -0
  137. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/data/d2-sample.svg +0 -0
  138. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/d2/class.d2 +0 -0
  139. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/d2/component.d2 +0 -0
  140. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/d2/container.d2 +0 -0
  141. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/d2/context.d2 +0 -0
  142. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/d2/sequence.d2 +0 -0
  143. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/mermaid/class.mmd +0 -0
  144. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/mermaid/component.mmd +0 -0
  145. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/mermaid/container.mmd +0 -0
  146. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/mermaid/context.mmd +0 -0
  147. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/mermaid/sequence.mmd +0 -0
  148. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/plantuml/class.puml +0 -0
  149. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/plantuml/component.puml +0 -0
  150. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/plantuml/container.puml +0 -0
  151. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/plantuml/context.puml +0 -0
  152. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/backends/plantuml/sequence.puml +0 -0
  153. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/mermaid/component.mmd +0 -0
  154. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/mermaid/container.mmd +0 -0
  155. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/fixtures/mermaid/context.mmd +0 -0
  156. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_adr.py +0 -0
  157. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_adr_numbering.py +0 -0
  158. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_analyzer.py +0 -0
  159. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_cli.py +0 -0
  160. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_cli_encoding.py +0 -0
  161. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_cli_init.py +0 -0
  162. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_cli_plan_custom_template.py +0 -0
  163. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_cli_sigint.py +0 -0
  164. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_cli_verify_config.py +0 -0
  165. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_config.py +0 -0
  166. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_config_poetry.py +0 -0
  167. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_d2_download.py +0 -0
  168. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_dependencies.py +0 -0
  169. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_dependency_graph_model.py +0 -0
  170. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_design_models.py +0 -0
  171. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_diagrams_mermaid.py +0 -0
  172. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_documents.py +0 -0
  173. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_duplicate_names.py +0 -0
  174. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_explain.py +0 -0
  175. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_explain_status.py +0 -0
  176. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_extra_designs_coverage.py +0 -0
  177. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_facts.py +0 -0
  178. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_facts_code.py +0 -0
  179. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_facts_data_model.py +0 -0
  180. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_facts_dominators.py +0 -0
  181. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_generator.py +0 -0
  182. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_grep_performance.py +0 -0
  183. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_manifests.py +0 -0
  184. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_max_lines_per_file.py +0 -0
  185. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_output_dir.py +0 -0
  186. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_plan_e2e.py +0 -0
  187. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_plandoc.py +0 -0
  188. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_properties.py +0 -0
  189. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_raster.py +0 -0
  190. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_skill_models.py +0 -0
  191. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_skills_install.py +0 -0
  192. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_source_dirs.py +0 -0
  193. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_summary_slug_diagram_defaults.py +0 -0
  194. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_templating_security.py +0 -0
  195. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_verify.py +0 -0
  196. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_verify_locate.py +0 -0
  197. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_version.py +0 -0
  198. {kingmadoc-0.3.0.dev9 → kingmadoc-0.3.0.dev10}/tests/test_vscode_preview.py +0 -0
@@ -51,24 +51,27 @@ diagram_format: mermaid
51
51
  # `models` selects the design models (sections) of a document; default: all of them.
52
52
  extra_designs:
53
53
  functional_design:
54
- # <slug>-functional-design.md: user flows, edge cases, business rules,
55
- # permissions and roles.
54
+ # <slug>-functional-design.md, for stakeholders: user stories, use case diagram, per
55
+ # story a use case, screen design (screenshot or wireframe) and evil user stories;
56
+ # user flows.
56
57
  enabled: false
57
58
  template: functional_design.md.j2
58
- models: []
59
+ models: [user_stories, use_case_diagram, use_cases, screen_designs, evil_user_stories, user_flows]
59
60
  technical_design:
60
- # <slug>-technical-design.md: database schema, API contracts, error handling,
61
- # performance and security considerations.
61
+ # <slug>-technical-design.md, for developers: database schema, API contracts,
62
+ # business rules, permissions, edge cases, error handling, performance and security,
63
+ # threat model (Microsoft Threat Modeling Tool style), dependency graph.
62
64
  enabled: false
63
65
  template: technical_design.md.j2
64
- models: [dependency_graph]
66
+ models: [business_rules, permissions, edge_cases, threat_model, dependency_graph]
65
67
  domain_design:
66
68
  # <slug>-domain-design.md: domain model and event storming.
67
69
  enabled: false
68
70
  template: domain_design.md.j2
69
71
  models: [domain_model, event_storming]
70
72
  security_design:
71
- # <slug>-security-design.md: threat model (STRIDE) and who may do what.
73
+ # <slug>-security-design.md: threat model (Threat Modeling Tool style) and who may
74
+ # do what.
72
75
  enabled: false
73
76
  template: security_design.md.j2
74
77
  models: [threat_model, permissions]
@@ -80,5 +83,11 @@ adr:
80
83
 
81
84
  # Explainers written by the explaining-code agent skill ("explain this project").
82
85
  # format: arc42 (the 12 arc42 sections, default) or c4 (compact zoom-in).
86
+ # documents: single (one explainer, default), split (functional + technical, "FO/TO"),
87
+ # functional (only the FO) or technical (only the TO). The request overrides it.
88
+ # models: what the agent may draw (default: all; each only when the code has it). The
89
+ # request can narrow it too ("without screens", "only the threat model").
83
90
  explain:
84
91
  format: arc42
92
+ documents: single
93
+ models: [c4_context, c4_container, c4_component, c4_code, c4_deployment, c4_dynamic, sequence, state_machine, er_diagram, domain_model, class_diagram, package_diagram, activity, user_journey, use_case, event_flow, context_map, data_flow, algorithm, user_stories, screens, evil_user_stories, threat_model]
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Fixed
11
+
12
+ - Explainers can no longer end up without pictures. `kingmadoc render` links the SVG of
13
+ a diagram whose PNG conversion fails (a missing `resvg-py` wheel, a Rust panic in
14
+ resvg) instead of failing the whole document, and `resvg-py` is loaded only when a
15
+ PNG is made, so a platform without its wheel keeps every other command. The
16
+ `explaining-code` skill (6.0) delivers first and asks afterwards: it never stops on a
17
+ question before the document is written and rendered (screenshots are offered at
18
+ hand-over, wireframes come first), and it must pass the new
19
+ `kingmadoc explain check <folder>` (no placeholders, no unrendered D2, no missing
20
+ images, no figure without a picture) before it hands over. The eval scenarios run
21
+ the same check.
22
+
10
23
  ### Changed
11
24
 
12
25
  - `kingmadoc render` links a PNG for each diagram, so the pictures show in every
@@ -42,6 +55,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
42
55
 
43
56
  ### Added
44
57
 
58
+ - The functional design follows one red thread: user stories (one per `REQ-n`), a use
59
+ case diagram, and per story `US-n` a use case `UC-n`, a screen design `S-n` (a
60
+ screenshot when the screen exists, else a text wireframe) and evil user stories
61
+ `EUS-n.m`, each pointing at a security measure `SM-n`. The technical design gets the
62
+ threat model with those measures. Skill 1.2.0 writes the same.
63
+ - Threat models follow the Microsoft Threat Modeling Tool (template SDL TM Knowledge
64
+ Base): its stencils (External Interactor, Process, Data Store, trust boundaries such
65
+ as Internet Boundary), and its report: per interaction the tool's STRIDE threats, each
66
+ with a state (Not Started, Not Applicable, Needs Investigation, Mitigation
67
+ Implemented), a priority and a justification, plus the state summary. `threat_model`
68
+ is now also a model of `technical_design` (default: on). The threats come from
69
+ Microsoft's own knowledge base (the tool's default template, *SDL TM Knowledge Base
70
+ (Core)* 4.1.0.11, MIT, bundled from microsoft/threat-modeling-templates):
71
+ `kingmadoc threats <file>.yml` evaluates its generation rules for every data flow as
72
+ the tool does and prints the data flow diagram (D2, Mermaid or PlantUML) and the
73
+ report; `--types` lists the stencils. `explaining-code` uses it, or its generated
74
+ `reference/threats.md` without the CLI.
75
+ - Every model is on by default and can be chosen: the functional design's parts are
76
+ models now (`user_stories`, `use_case_diagram`, `use_cases`, `screen_designs`,
77
+ `evil_user_stories`, `user_flows`, `edge_cases`, `business_rules`, `permissions`);
78
+ `kingmadoc plan --models a,b` keeps only those (and switches on the documents that
79
+ have them); `explain.models` lists what the explaining-code agent may draw, and the
80
+ request can narrow it ("without screens").
81
+ - The functional design (FO) is for stakeholders: what the feature does and for whom,
82
+ in plain words. Business rules, permissions and edge cases moved to the technical
83
+ design (TO), which is for developers only: they are models of `technical_design` now
84
+ (with where each is enforced and its test). The explainer's `functional.md` and
85
+ `technical.md` split the same way; the threat model has its own reference,
86
+ `reference/threat-model.md`.
87
+ - `kingmadoc explain scaffold "<subject>"` writes the empty explainer (arc42 or c4;
88
+ one document, FO + TO, only an FO or only a TO; the chosen models) straight from the
89
+ skill's reference formats, with the key facts, headings, tables and figure numbers
90
+ filled in, so the agent no longer reads the output formats. `kingmadoc screenshots
91
+ <url> /route=name …` captures screens of a running app (one browser with the optional
92
+ `kingmadoc[screenshots]` extra, else `npx playwright`). The skill is shorter
93
+ (SKILL.md about 3,400 instead of 4,900 tokens); user stories, screens and evil user
94
+ stories have their own reference, `reference/stories.md`.
95
+ - `kingmadoc plan --documents split|functional|technical`: by default only the plan is
96
+ written; "make an FO and TO" (or "functional and technical design", "split") adds
97
+ both designs, "only an FO" / "only a TO" just that one. The plan skill (1.2.0) maps
98
+ the request the same way.
99
+ - Explainers pick their documents from the request, without asking back: arc42 by
100
+ default, "as an FO/TO" writes both, "only an FO" or "only a TO" writes just that one
101
+ (`explain.documents: functional` / `technical` sets it per project).
102
+ - The arc42 explainer reads like a software architecture document: section 1 lists
103
+ documented stakeholders and links the requirements (`REQ-n` plan docs); section 3
104
+ splits into a Business context for stakeholders (actors, use case diagram, user
105
+ stories with use case, screen and evil user stories) and a Technical context for
106
+ developers; section 8 adds testability and the repository's stated conventions
107
+ (code, branches, commits); section 10 lists the quality scenarios the tests cover
108
+ (context, goal, how it is tested).
109
+ - `explaining-code` 5.9: "document an FO/TO" (functioneel/technisch ontwerp) writes the
110
+ split explainer with the same red thread: user stories, per story a use case, a
111
+ screenshot of the running app (the agent asks first; a D2 wireframe from the view code
112
+ when it cannot run) and evil user stories; `technical.md` gets a threat model in
113
+ Threat Modeling Tool style (data flow diagram in its notation, its threats per
114
+ interaction, the security measures the code takes, sensitive data), which a single arc42 or c4 explainer also gets when the code has logins,
115
+ tokens, personal data or uploads. "Document an arc42" picks the arc42 format.
45
116
  - `kingmadoc explain facts` lists private modules from the dominator tree of the module
46
117
  graph (Python and JavaScript/TypeScript): what only one module leads to belongs to
47
118
  it, which shows the real component boundaries. A single entry point is left out.
@@ -35,13 +35,35 @@ Flow for `plan "<description>"` (`cli.py`): `config.load_config` → `plan.analy
35
35
  - `adr.py` (`kingmadoc adr "<title>"`, gated by the top-level `adr.enabled`; `adr.template` selects the template): `adr_path` → `next_number` (max existing + 1, never reused) + `adr_filename` → `render_adr` (`templates/adr.md.j2`, bundled) → `docs/adr/<NNNN>-<slug>.md`. Not a mode; shares `naming.slugify` and `templating.load_template` with plan.
36
36
  - `render.py` (`kingmadoc render <doc>`): renders each ```` ```d2 ```` block with ELK to `img/<doc>-<n>.svg` (dark theme; D2 via `d2_binary.ensure_d2`) and, by default, `img/<doc>-<n>.png` via `raster.svg_to_png` (resvg; D2's embedded WOFF fonts unpacked to TTF and the `d2-N-font-*` CSS names mapped to family + weight, else text is missing), moves its source to `img/<doc>-<n>.d2`, and leaves only `<!-- kingmadoc:diagram img/<doc>-<n>.d2 -->` + the PNG (`--format svg`: the SVG) in the document; `diagram_warnings` = dark-mode styles (only reported for `--format svg`) + crowding (> 12 arrows, doubled pairs) (the comment is invisible in previews; re-rendering reads the `.d2` files, so edit those). Converts the older `<details>` format. Renders everything to a temp dir first, so a failing diagram changes nothing.
37
37
  - `d2_binary.py`: `ensure_d2` finds D2 (`KINGMADOC_D2`, PATH, cache) or downloads the pinned release once into the user cache; the SHA-256 per platform is pinned in `D2_ASSETS` (update version + all hashes together, cross-checked with the release's SHA256SUMS). `skills.py` + `kingmadoc skills install`: the skills in `skill/` ship as package data (hatch force-include) and are copied into the agent's skills dir; a `.kingmadoc-skill.json` manifest per skill folder records the installed hashes, so a reinstall updates unchanged files and only blocks local edits (`PREVIOUS_RELEASES` is the frozen hash list for installs from before the manifest).
38
- - `skill/explaining-code/`: second product skill; explains existing code (feature, branch, project, part) with D2 pictures, one folder per subject `docs/explain/<NNNN>-<slug>/README.md` (`explain.py` + `kingmadoc explain new`: next ID, never reused, same subject reuses its folder; regenerates the index `docs/explain/README.md`, also after `render` of such a file; `explain status` → `freshness`: `git diff --relative --name-only <Based on commit>` over the paths the explainer names in code spans (else the whole project), excluding `docs/explain`; `render` names a README's images `figure-<n>`). `SKILL.md` = workflow and D2 examples; the formats are `reference/arc42.md` (default) and `reference/c4.md`, chosen by `explain.format`; `reference/split.md` for `explain.documents: split` (cover + `functional.md` + `technical.md`); `reference/c4-model.md` (Simon Brown's C4: abstractions, 7 diagrams, notation, D2 style block, checklist) and `reference/models.md` (decision table + rules + one example per other model). `tests/test_skill_explaining_code.py` checks its format and compiles every D2 example with the real `d2` when available (`D2_BIN`); `tests/test_skill_models.py` checks every example obeys its model's rules. D2 pitfalls: quote labels with `[`/`:`; `source-arrowhead` only works on `<->`.
38
+ - `skill/explaining-code/`: second product skill; explains existing code (feature, branch, project, part) with D2 pictures, one folder per subject `docs/explain/<NNNN>-<slug>/README.md` (`explain.py` + `kingmadoc explain new`: next ID, never reused, same subject reuses its folder; regenerates the index `docs/explain/README.md`, also after `render` of such a file; `explain status` → `freshness`: `git diff --relative --name-only <Based on commit>` over the paths the explainer names in code spans (else the whole project), excluding `docs/explain`; `render` names a README's images `figure-<n>`). `SKILL.md` = workflow and D2 examples; the formats are `reference/arc42.md` (default) and `reference/c4.md`, chosen by `explain.format`; `reference/split.md` for `explain.documents: split` (cover + `functional.md` for stakeholders + `technical.md` for developers: rules, permissions, edge cases); `reference/threat-model.md` (Threat Modeling Tool format, via `kingmadoc threats`) and the generated `reference/threats.md`; `reference/c4-model.md` (Simon Brown's C4: abstractions, 7 diagrams, notation, D2 style block, checklist) and `reference/models.md` (decision table + rules + one example per other model). `tests/test_skill_explaining_code.py` checks its format and compiles every D2 example with the real `d2` when available (`D2_BIN`); `tests/test_skill_models.py` checks every example obeys its model's rules. D2 pitfalls: quote labels with `[`/`:`; `source-arrowhead` only works on `<->`.
39
39
  - `facts/` (`kingmadoc explain facts`): pure parsers `projects.project_references` (.csproj) and `data_model.data_model` (EF Core via `DbSet<T>`, Prisma, Django, SQLAlchemy, TypeORM; regex, test files skipped) → frozen `Entity`/`Field`/`Relation`; `routes.routes` (ASP.NET controllers + minimal APIs, Next.js app/pages, Django urls + decorators, FastAPI, Flask, Express; `access` = what the code states), `services.services` (.NET DI), `js_modules.js_dependencies` (relative + tsconfig `paths` imports, `plan.dependencies.collapse` above 25 modules, `max_nodes=None` for the raw graph), `dominators.private_modules` (Cooper–Harvey–Kennedy on the raw Python + JS graphs; virtual root above the modules nothing imports; a single entry point is left out); `branch.branch_changes` (git I/O via `git.run_git`, merge base → working tree); `collect.collect_facts` reads files from the `CodebaseReport` and renders Markdown/JSON.
40
40
  - `plandoc.py` (not a mode; pure): the plan frontmatter (B2) and `REQ-n` requirements (B1): `check_plan` (every problem as a message), `parse_plan` → `PlanMeta`, `set_status` (frontmatter + header table). `kingmadoc check <slug>` / `approve <slug>` in `cli.py` use `verify.locate.find_plan`. The template renders the frontmatter from `PlanContext.slug/requirements/files_expected` (`generator.requirements_from_answers`: acceptance answer split on `;`/newlines; `files_from_answers`: existing paths only).
41
41
  - `verify/` (`kingmadoc verify <slug> [--run-checks]`): `locate.find_plan` (bad slug / missing plan → `VerificationError`) → `changes.detect_changes` (git; base = parent of the commit that added the plan, else last commit before **Generated** + 59 s; working tree incl. untracked; the plan's folder ignored) → `deviations.find_deviations` (pure: draft plan with code = process, `files_expected` untouched / changes outside, `REQ-n` not mentioned in tests or commit messages, containers vs `planned_containers` from the plan text; the CLI passes `infer_containers` names since verify may not import plan) → `commands.detect_commands` (config `verify:` > Makefile > npm > cargo > go > dotnet > pytest/ruff) and `run_check` (no shell; only with `--run-checks`, never enabled by the repo's config) → `report.render_verify` + `verify_status`; the plan's status becomes `implemented`/`partial` unless draft or not verified (written together, `write_documents`). Modes may not import each other (E5, auto-checked), so shared I/O lives in `documents.py`.
42
+ - `scaffold.py` (`kingmadoc explain scaffold`; pure): cuts the ```` ```markdown ```` output blocks out of the explaining-code reference files (`arc42.md`, `c4.md`, `split.md`, `threat-model.md`: the one source of every format), assembles them per format/documents/models (`MODEL_SECTIONS` drops a switched-off model's sections; the TO is the format minus its functional parts plus rules and threat model), fills the key facts and numbers the figures. Change a format in the reference file; `tests/test_scaffold.py` checks the result. `explain.check_explainer` (`kingmadoc explain check`) is the finish gate. `screenshots.py` (`kingmadoc screenshots`): optional Playwright, else `npx playwright screenshot`; http(s) only.
43
+ - `threats/` (`kingmadoc threats <file>.yml`; not a mode, E5): Microsoft Threat Modeling Tool style. `knowledge_base.load_knowledge_base` reads `sdl_knowledge_base.json` (Microsoft's "SDL TM Knowledge Base (Core)", MIT, imported by `scripts/import_tmt_knowledge_base.py`; never edit by hand) → `model.parse_threat_model` (elements/boundaries/flows by the tool's type names) → `model.generate_threats` evaluates each threat type's include/exclude filter per flow with `filters.matches` (types match their parents; `flow crosses`; property defaults = first allowed value) → `report.render_report` (elements, state summary, one table per interaction) + `render_diagram` (d2/mermaid/plantuml). `plan.models._threat_model` feeds it an inferred DFD; `scripts/build_threat_reference.py` writes the skill's `reference/threats.md` (a test fails when stale).
42
44
  - `diagrams/`: backend pattern, selected by `diagram_format` (`mermaid` default, `plantuml`, `d2`) via `diagrams.get_backend`. `base.py` has the `DiagramBackend` Protocol (`render_context/container/component/sequence/class`) and the shared pure model: `build_*` validate input, assign unique aliases and resolve relationships into frozen `Diagram`/`Node`/`Edge`. Backend modules (`mermaid.py`, `plantuml.py`, `d2.py`) only format that model and return a fenced block (templates must not add fences). Escaping differs per backend and is verified against the real tools: Mermaid `"`→`#quot;` (C4 titles drop `#`/`;`), PlantUML `"`→`<U+0022>`, D2 escapes `\`, `"`, `$`. Adding a backend: a module, an entry in `diagrams.BACKENDS` and `config.DIAGRAM_FORMATS`, snapshots via `KINGMADOC_UPDATE_SNAPSHOTS=1 pytest tests/test_diagram_backends.py`. Extra-doc templates pick their ER/flowchart placeholder by `diagram_format`. No knowledge of analysis: `generator.build_plan_context` maps analysis → C4 elements.
43
45
  - Templates live in `src/kingmadoc/templates/` (shipped as package data). Security: `templating.load_template` loads bundled templates only from that package dir and never searches the analyzed project's root; a project template is used only when a `template:` setting gives an explicit path (`ConfigError` if missing or not a file). Every template renders in Jinja's `SandboxedEnvironment` (repos may be untrusted; see `tests/test_templating_security.py`). Jinja uses `StrictUndefined`, so every template variable must be passed.
44
46
 
47
+ ## Never again: explainers without pictures
48
+
49
+ An explainer must **always** end written, rendered and with every picture shown; an empty
50
+ or picture-less `docs/explain/…` is the worst failure this product can have (it happened
51
+ once: a blocking question before writing, and a PNG step that could take the whole render
52
+ down). Guarded by, and never to be weakened:
53
+
54
+ - `render_file` falls back to the SVG per diagram when PNG conversion fails, and
55
+ `raster.py` imports `resvg_py` lazily, so a missing wheel or a Rust panic costs PNG,
56
+ never the pictures or other commands (`tests/test_render.py`: `…falls_back_to_svg`,
57
+ `…starts_without_resvg`, and `…real_d2_produces_pictures` with `D2_BIN` set).
58
+ - `kingmadoc explain check <folder>` (`explain.check_explainer`) fails on unfilled
59
+ placeholders, unrendered D2, missing images and captions without pictures; the skill's
60
+ Step 6 must pass it, and every explain eval scenario runs it (`explain_check`).
61
+ - The skill's first rule is "Always deliver the pictures": no question before the
62
+ document exists (screenshots are offered at hand-over, wireframes first)
63
+ (`tests/test_skill_explaining_code.py::test_the_skill_always_delivers_rendered_pictures`).
64
+ - A test that fails with the real `d2` binary (`D2_BIN=…/d2 pytest`) is a bug, never
65
+ "pre-existing": run the suite with `D2_BIN` before any render or skill change.
66
+
45
67
  ## Conventions
46
68
 
47
69
  All docs are indexed in `docs/index.md` (English only; add new `.md` files there). Rules: the **Rule summary** table at the top of `docs/conventions.md` (ID, status, auto/manual); open a rule's section only when needed. Key rules:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: kingmadoc
3
- Version: 0.3.0.dev9
3
+ Version: 0.3.0.dev10
4
4
  Summary: Feature docs for AI coding agents: a plan with C4 diagrams before the code, a verification doc after.
5
5
  Project-URL: Homepage, https://github.com/ATkingma/KingmaDoc
6
6
  Project-URL: Issues, https://github.com/ATkingma/KingmaDoc/issues
@@ -51,6 +51,8 @@ Requires-Dist: pytest-cov>=6.0; extra == 'dev'
51
51
  Requires-Dist: pytest>=8.0; extra == 'dev'
52
52
  Requires-Dist: ruff>=0.16; extra == 'dev'
53
53
  Requires-Dist: types-pyyaml; extra == 'dev'
54
+ Provides-Extra: screenshots
55
+ Requires-Dist: playwright>=1.40; extra == 'screenshots'
54
56
  Description-Content-Type: text/markdown
55
57
 
56
58
  # KingmaDoc
@@ -149,7 +151,8 @@ change), a whole project, or a part of one. Each subject gets its own folder wit
149
151
  unique ID, `docs/explain/<NNNN>-<name>/` (the explainer `README.md` plus its `img/`),
150
152
  listed in `docs/explain/README.md`; explaining it again updates that folder. The
151
153
  explainer is one document, or on request (or with `explain: {documents: split}`) a
152
- functional and a technical document next to a cover page. It is by default an **arc42** architecture document (the twelve arc42
154
+ functional and a technical document next to a cover page (FO/TO: user stories with
155
+ use cases, screenshots and evil user stories; a threat model in the technical side). It is by default an **arc42** architecture document (the twelve arc42
153
156
  sections, with C4 diagrams per level, runtime flows and deployment), or a compact C4
154
157
  zoom-in with `explain: {format: c4}` in `.featuredoc.yml`. Every figure is numbered,
155
158
  rendered as an image and decoded by a small table. The C4 diagrams follow Simon Brown's
@@ -196,6 +199,11 @@ More commands:
196
199
 
197
200
  ```bash
198
201
  kingmadoc plan "…" --no-input --stdout # no questions, print instead of writing
202
+ kingmadoc plan "…" --models user_stories,screen_designs,threat_model # only these models
203
+ kingmadoc threats threat-model.yml # Microsoft Threat Modeling Tool threats for a DFD
204
+ kingmadoc explain scaffold "Checkout" --documents split # empty FO + TO to fill in
205
+ kingmadoc explain check docs/explain/0001-checkout # fails until every picture shows
206
+ kingmadoc screenshots http://localhost:8000 /cart=screen-us-1 -o docs/explain/0001-checkout/img
199
207
  kingmadoc check add-login # validate a plan's frontmatter and REQ IDs
200
208
  kingmadoc approve add-login # draft -> approved: the gate before code
201
209
  kingmadoc explain new "Checkout" # folder for a subject: docs/explain/0001-checkout/
@@ -224,15 +232,28 @@ file with all defaults and comments; [this repository's
224
232
  | `analyzer.exclude_dirs` | `.git`, `.venv`, `node_modules`, … | Directory names/globs to skip |
225
233
  | `diagrams` | `[c4_context, c4_container]` | Which C4 diagrams the plan contains |
226
234
  | `diagram_format` | `mermaid` | `mermaid`, `plantuml` (C4-PlantUML) or `d2` |
227
- | `extra_designs.functional_design.enabled` | `false` | Also write `<slug>-functional-design.md`: user flows, edge cases, business rules, permissions |
228
- | `extra_designs.technical_design.enabled` | `false` | Also write `<slug>-technical-design.md`: database schema, API contracts, error handling, performance, security, and a module dependency graph derived from the code |
235
+ | `extra_designs.functional_design.enabled` | `false` | Also write `<slug>-functional-design.md`, for stakeholders (plain words, no technical terms): user stories, use case diagram, per story a use case, screen design and evil user stories, user flows |
236
+ | `extra_designs.technical_design.enabled` | `false` | Also write `<slug>-technical-design.md`, for developers: database schema, API contracts, business rules, permissions, edge cases, error handling, performance, security, a threat model in Microsoft Threat Modeling Tool style with security measures, and a module dependency graph derived from the code |
229
237
  | `extra_designs.domain_design.enabled` | `false` | Also write `<slug>-domain-design.md`: domain model, event storming |
230
- | `extra_designs.security_design.enabled` | `false` | Also write `<slug>-security-design.md`: STRIDE threat model (with the inferred elements), who may do what |
231
- | `extra_designs.<name>.models` | all models of that document | Which design models (sections) the document contains, e.g. `[threat_model]` |
238
+ | `extra_designs.security_design.enabled` | `false` | Also write `<slug>-security-design.md`: threat model (with the inferred elements), who may do what |
239
+ | `extra_designs.<name>.models` | all models of that document | Which design models (sections) the document contains, e.g. `[threat_model]`; `plan --models` picks them per run |
240
+ | `explain.format` / `.documents` | `arc42` / `single` | Explainer format (`arc42`, `c4`); documents: one (arc42), `split` (FO + TO), or only `functional` (FO) or `technical` (TO). The request overrides both ("describe this branch with an FO and a TO", "only a TO") |
241
+ | `explain.models` | all models | What the explaining-code agent may draw (C4, UML, ER, user stories, screens, evil user stories, threat model …); the request can narrow it |
232
242
  | `extra_designs.<name>.template` | bundled template | Template for that document: bundled name or explicit path (runs sandboxed) |
233
243
  | `adr.enabled` | `false` | Enable `kingmadoc adr "<title>"`, which writes numbered Architecture Decision Records to `docs/adr/` |
234
244
  | `adr.template` | `adr.md.j2` | ADR template: bundled name or explicit path (runs sandboxed) |
235
245
 
246
+ ### Threat models
247
+
248
+ Threat models follow the [Microsoft Threat Modeling
249
+ Tool](https://learn.microsoft.com/en-us/azure/security/develop/threat-modeling-tool):
250
+ its data flow notation, and its report (per interaction the threats, with state,
251
+ priority and justification). The threats themselves come from Microsoft's own
252
+ knowledge base, the tool's default template *SDL TM Knowledge Base (Core)*, bundled
253
+ from [microsoft/threat-modeling-templates](https://github.com/microsoft/threat-modeling-templates)
254
+ (MIT license, Copyright (c) Microsoft Corporation); `kingmadoc threats` evaluates its
255
+ generation rules for every data flow the way the tool does.
256
+
236
257
  ## Comparison
237
258
 
238
259
  How KingmaDoc relates to tools with overlapping goals, based on each project's own
@@ -94,7 +94,8 @@ change), a whole project, or a part of one. Each subject gets its own folder wit
94
94
  unique ID, `docs/explain/<NNNN>-<name>/` (the explainer `README.md` plus its `img/`),
95
95
  listed in `docs/explain/README.md`; explaining it again updates that folder. The
96
96
  explainer is one document, or on request (or with `explain: {documents: split}`) a
97
- functional and a technical document next to a cover page. It is by default an **arc42** architecture document (the twelve arc42
97
+ functional and a technical document next to a cover page (FO/TO: user stories with
98
+ use cases, screenshots and evil user stories; a threat model in the technical side). It is by default an **arc42** architecture document (the twelve arc42
98
99
  sections, with C4 diagrams per level, runtime flows and deployment), or a compact C4
99
100
  zoom-in with `explain: {format: c4}` in `.featuredoc.yml`. Every figure is numbered,
100
101
  rendered as an image and decoded by a small table. The C4 diagrams follow Simon Brown's
@@ -141,6 +142,11 @@ More commands:
141
142
 
142
143
  ```bash
143
144
  kingmadoc plan "…" --no-input --stdout # no questions, print instead of writing
145
+ kingmadoc plan "…" --models user_stories,screen_designs,threat_model # only these models
146
+ kingmadoc threats threat-model.yml # Microsoft Threat Modeling Tool threats for a DFD
147
+ kingmadoc explain scaffold "Checkout" --documents split # empty FO + TO to fill in
148
+ kingmadoc explain check docs/explain/0001-checkout # fails until every picture shows
149
+ kingmadoc screenshots http://localhost:8000 /cart=screen-us-1 -o docs/explain/0001-checkout/img
144
150
  kingmadoc check add-login # validate a plan's frontmatter and REQ IDs
145
151
  kingmadoc approve add-login # draft -> approved: the gate before code
146
152
  kingmadoc explain new "Checkout" # folder for a subject: docs/explain/0001-checkout/
@@ -169,15 +175,28 @@ file with all defaults and comments; [this repository's
169
175
  | `analyzer.exclude_dirs` | `.git`, `.venv`, `node_modules`, … | Directory names/globs to skip |
170
176
  | `diagrams` | `[c4_context, c4_container]` | Which C4 diagrams the plan contains |
171
177
  | `diagram_format` | `mermaid` | `mermaid`, `plantuml` (C4-PlantUML) or `d2` |
172
- | `extra_designs.functional_design.enabled` | `false` | Also write `<slug>-functional-design.md`: user flows, edge cases, business rules, permissions |
173
- | `extra_designs.technical_design.enabled` | `false` | Also write `<slug>-technical-design.md`: database schema, API contracts, error handling, performance, security, and a module dependency graph derived from the code |
178
+ | `extra_designs.functional_design.enabled` | `false` | Also write `<slug>-functional-design.md`, for stakeholders (plain words, no technical terms): user stories, use case diagram, per story a use case, screen design and evil user stories, user flows |
179
+ | `extra_designs.technical_design.enabled` | `false` | Also write `<slug>-technical-design.md`, for developers: database schema, API contracts, business rules, permissions, edge cases, error handling, performance, security, a threat model in Microsoft Threat Modeling Tool style with security measures, and a module dependency graph derived from the code |
174
180
  | `extra_designs.domain_design.enabled` | `false` | Also write `<slug>-domain-design.md`: domain model, event storming |
175
- | `extra_designs.security_design.enabled` | `false` | Also write `<slug>-security-design.md`: STRIDE threat model (with the inferred elements), who may do what |
176
- | `extra_designs.<name>.models` | all models of that document | Which design models (sections) the document contains, e.g. `[threat_model]` |
181
+ | `extra_designs.security_design.enabled` | `false` | Also write `<slug>-security-design.md`: threat model (with the inferred elements), who may do what |
182
+ | `extra_designs.<name>.models` | all models of that document | Which design models (sections) the document contains, e.g. `[threat_model]`; `plan --models` picks them per run |
183
+ | `explain.format` / `.documents` | `arc42` / `single` | Explainer format (`arc42`, `c4`); documents: one (arc42), `split` (FO + TO), or only `functional` (FO) or `technical` (TO). The request overrides both ("describe this branch with an FO and a TO", "only a TO") |
184
+ | `explain.models` | all models | What the explaining-code agent may draw (C4, UML, ER, user stories, screens, evil user stories, threat model …); the request can narrow it |
177
185
  | `extra_designs.<name>.template` | bundled template | Template for that document: bundled name or explicit path (runs sandboxed) |
178
186
  | `adr.enabled` | `false` | Enable `kingmadoc adr "<title>"`, which writes numbered Architecture Decision Records to `docs/adr/` |
179
187
  | `adr.template` | `adr.md.j2` | ADR template: bundled name or explicit path (runs sandboxed) |
180
188
 
189
+ ### Threat models
190
+
191
+ Threat models follow the [Microsoft Threat Modeling
192
+ Tool](https://learn.microsoft.com/en-us/azure/security/develop/threat-modeling-tool):
193
+ its data flow notation, and its report (per interaction the threats, with state,
194
+ priority and justification). The threats themselves come from Microsoft's own
195
+ knowledge base, the tool's default template *SDL TM Knowledge Base (Core)*, bundled
196
+ from [microsoft/threat-modeling-templates](https://github.com/microsoft/threat-modeling-templates)
197
+ (MIT license, Copyright (c) Microsoft Corporation); `kingmadoc threats` evaluates its
198
+ generation rules for every data flow the way the tool does.
199
+
181
200
  ## Comparison
182
201
 
183
202
  How KingmaDoc relates to tools with overlapping goals, based on each project's own
@@ -31,7 +31,10 @@ Feature Verification Doc afterwards.
31
31
  [arc42](../skill/explaining-code/reference/arc42.md), [C4](../skill/explaining-code/reference/c4.md);
32
32
  models: [C4 model](../skill/explaining-code/reference/c4-model.md),
33
33
  [UML, ER, DFD and others](../skill/explaining-code/reference/models.md);
34
- [one document or functional and technical apart](../skill/explaining-code/reference/split.md))
34
+ [one document or functional and technical apart (FO/TO)](../skill/explaining-code/reference/split.md),
35
+ [user stories, use cases, screens](../skill/explaining-code/reference/stories.md),
36
+ [threat model](../skill/explaining-code/reference/threat-model.md),
37
+ [Microsoft threat knowledge base](../skill/explaining-code/reference/threats.md))
35
38
  ([README: Markdown-only install](../README.md#markdown-only-no-python))
36
39
  - **Seeing what the output looks like** → [Example plan doc](../examples/verify-mode-plan.md)
37
40
  - **Contributing code** → [Conventions: Python coding standards](conventions.md#d-python-coding-standards)
@@ -65,6 +68,8 @@ in the package.
65
68
  | [`checking-conventions` skill](../.claude/skills/checking-conventions/SKILL.md) | Checks changes against the conventions: automatic checker + manual review workflow |
66
69
  | [`.claude/settings.json`](../.claude/settings.json) | Stop hook that runs the convention checker after every agent turn |
67
70
  | [`scripts/build_skill_variants.py`](../scripts/build_skill_variants.py) | Generates the Cursor, Codex and Copilot skill variants from `skill/SKILL.md` |
71
+ | [`scripts/import_tmt_knowledge_base.py`](../scripts/import_tmt_knowledge_base.py) | Imports Microsoft's threat knowledge base (`default.tb7`) into `src/kingmadoc/threats/sdl_knowledge_base.json` |
72
+ | [`scripts/build_threat_reference.py`](../scripts/build_threat_reference.py) | Writes the skill's `reference/threats.md` from that knowledge base |
68
73
  | [`.github/workflows/ci.yml`](../.github/workflows/ci.yml) | CI: pytest on Python 3.11–3.13, Linux/macOS/Windows, plus a CLI smoke test |
69
74
  | [Bug report](../.github/ISSUE_TEMPLATE/bug_report.md), [feature request](../.github/ISSUE_TEMPLATE/feature_request.md) | GitHub issue templates |
70
75
 
@@ -7,6 +7,7 @@ skills installed (roadmap WP5).
7
7
  | Scenario | Skill | Request | Checks |
8
8
  | --- | --- | --- | --- |
9
9
  | [explain-feature](scenarios/explain-feature.yml) | `explaining-code` | Explain how placing an order works | explainer in `docs/explain/0001-*/`, arc42 headings, pictures only, at most three questions, no code changed |
10
+ | [explain-fo-to](scenarios/explain-fo-to.yml) | `explaining-code` | "Maak een FO en TO over de branch" (Dutch) | cover, `functional.md` (domain model, user stories, evil user stories) and `technical.md` (business rules, threat model, C4 level 2), `kingmadoc explain check`, no code changed |
10
11
  | [explain-branch](scenarios/explain-branch.yml) | `explaining-code` | Explain what `feature/discount` changed | "What changed" about the discount, pictures only, no code changed |
11
12
  | [plan-feature](scenarios/plan-feature.yml) | `kingmadoc` | Plan cancelling an order, don't build it | plan in `docs/features/`, plan headings, passes `kingmadoc check`, no code changed (the approval gate) |
12
13
 
@@ -41,6 +42,16 @@ recorded result shows a real failure.
41
42
  | same run, without skill | 2/6 | 2/5 | 1/3 |
42
43
  | [2026-09-27 11:26](results/2026-09-27T112600Z.json), with skill, 3 runs | | | 4/4, 4/4, 4/4 |
43
44
 
45
+ | [2026-09-28 06:45](results/2026-09-28T064505Z.json), skill 5.9 (before the optimisation) | 7/7, 173 s, $1.15 | 6/6, 100 s, $0.86 | FO/TO: stopped by the spend limit, D2 left unrendered |
46
+ | [2026-09-28 09:26](results/2026-09-28T092643Z.json), skill 6.0 (scaffold, shorter skill) | 7/7, 256 s, $1.54 | 6/6, 99 s, $0.81 | FO/TO: 8/8, 367 s, $2.10 |
47
+
48
+ Rows from 2026-09-28 are re-checked with the current checks (`explain_check`,
49
+ `__pycache__` ignored, Dutch headings accepted). The 6.0 feature run filled the scaffold
50
+ placeholder by placeholder (41 turns instead of 22); the skill now says to write each
51
+ document in one pass: [2026-09-28 09:30](results/2026-09-28T093046Z.json), explain-feature
52
+ 7/7, 192 s, $1.23, 20 turns, with the larger 6.0 content (user stories, rules, threat
53
+ model) at about the cost of the 5.9 run.
54
+
44
55
  After the first run the plan scenario says the user cannot answer now (the skill's
45
56
  non-interactive path). The baseline runs of 11:26 hit the account's spend limit and
46
57
  did not run; they are not a result.
@@ -0,0 +1,159 @@
1
+ {
2
+ "agent": "claude -p {request} --output-format json --max-turns 80 --allowedTools 'Read,Write,Edit,Glob,Grep,Skill,Bash(kingmadoc:*),Bash(git log:*),Bash(git diff:*),Bash(git status:*),Bash(git show:*),Bash(git branch:*),Bash(git rev-parse:*),Bash(ls:*)'",
3
+ "results": [
4
+ {
5
+ "scenario": "explain-branch",
6
+ "variant": "with skill",
7
+ "agent": {
8
+ "exit_code": 0,
9
+ "seconds": 100,
10
+ "total_cost_usd": 0.8613995499999999,
11
+ "num_turns": 25,
12
+ "tokens": {
13
+ "input_tokens": 30,
14
+ "cache_creation_input_tokens": 64155,
15
+ "cache_read_input_tokens": 690090,
16
+ "output_tokens": 9188
17
+ },
18
+ "reply": "ld the discounted amount. No field keeps the original total or the discount amount. The threshold and rate are fixed in the code, and there are no tests for any of this.\n- **Other commit (`7bc5fcf`):** it only adds the KingmaDoc skill files under `.claude/skills/`. The shop never runs them.\n\nThe three diagrams show which parts changed, how placing an order runs with the discount step, and how the discount is calculated, with a table of example inputs checked by running the function.\n\nShould VS Code open explainers directly as a preview, so the pictures show? Otherwise, Ctrl+Shift+V shows them."
19
+ },
20
+ "checks": [
21
+ {
22
+ "check": "exists docs/explain/0001-*/README.md",
23
+ "ok": true,
24
+ "detail": "docs/explain/0001-branch-feature-discount/README.md"
25
+ },
26
+ {
27
+ "check": "contains docs/explain/0001-*/README.md",
28
+ "ok": true,
29
+ "detail": "all present"
30
+ },
31
+ {
32
+ "check": "pictures_only docs/explain/0001-*/*.md",
33
+ "ok": true,
34
+ "detail": "3 images"
35
+ },
36
+ {
37
+ "check": "max_questions docs/explain/0001-*/README.md",
38
+ "ok": true,
39
+ "detail": "0 question(s)"
40
+ },
41
+ {
42
+ "check": "unchanged_outside [docs/, .claude/]",
43
+ "ok": false,
44
+ "detail": "shop/__pycache__/__init__.cpython-311.pyc, shop/__pycache__/discounts.cpython-311.pyc"
45
+ }
46
+ ],
47
+ "passed": 4,
48
+ "total": 5
49
+ },
50
+ {
51
+ "scenario": "explain-feature",
52
+ "variant": "with skill",
53
+ "agent": {
54
+ "exit_code": 0,
55
+ "seconds": 173,
56
+ "total_cost_usd": 1.15176445,
57
+ "num_turns": 22,
58
+ "tokens": {
59
+ "input_tokens": 34,
60
+ "cache_creation_input_tokens": 71975,
61
+ "cache_read_input_tokens": 890083,
62
+ "output_tokens": 18567
63
+ },
64
+ "reply": "hipped` status.\n- Stock taken by orders that are never paid is never given back.\n- There's no CSRF protection.\n- An unknown product ID, bad JSON, or a missing customer returns a 500 error.\n- There are no tests or migrations.\n\n**Couldn't work out:**\n- How does a customer sign in? `shop/settings.py` has no `MIDDLEWARE` and doesn't install sessions, and there's no login route, so `@login_required` has nothing to check against.\n- Who creates `Customer` rows, and is `shipped` still planned?\n\nShould VS Code open explainers directly as a preview, so the pictures show? If not, Ctrl+Shift+V shows them."
65
+ },
66
+ "checks": [
67
+ {
68
+ "check": "exists docs/explain/0001-*/README.md",
69
+ "ok": true,
70
+ "detail": "docs/explain/0001-placing-an-order/README.md"
71
+ },
72
+ {
73
+ "check": "exists docs/explain/README.md",
74
+ "ok": true,
75
+ "detail": "docs/explain/README.md"
76
+ },
77
+ {
78
+ "check": "contains docs/explain/0001-*/README.md",
79
+ "ok": true,
80
+ "detail": "all present"
81
+ },
82
+ {
83
+ "check": "pictures_only docs/explain/0001-*/*.md",
84
+ "ok": true,
85
+ "detail": "8 images"
86
+ },
87
+ {
88
+ "check": "max_questions docs/explain/0001-*/README.md",
89
+ "ok": true,
90
+ "detail": "2 question(s)"
91
+ },
92
+ {
93
+ "check": "unchanged_outside [docs/, .claude/]",
94
+ "ok": true,
95
+ "detail": "27 change(s), all allowed"
96
+ }
97
+ ],
98
+ "passed": 6,
99
+ "total": 6
100
+ },
101
+ {
102
+ "scenario": "explain-fo-to",
103
+ "variant": "with skill",
104
+ "agent": {
105
+ "exit_code": 1,
106
+ "seconds": 113,
107
+ "total_cost_usd": 0.8422781499999998,
108
+ "num_turns": 16,
109
+ "tokens": {
110
+ "input_tokens": 20,
111
+ "cache_creation_input_tokens": 65220,
112
+ "cache_read_input_tokens": 482569,
113
+ "output_tokens": 11015
114
+ },
115
+ "reply": "You've hit your monthly spend limit \u00b7 raise it at claude.ai/settings/usage?from=cc_cli_limit_message \u00b7 your session limit resets 11am (Europe/Amsterdam)",
116
+ "error": "You've hit your monthly spend limit \u00b7 raise it at claude.ai/settings/usage?from=cc_cli_limit_message \u00b7 your session limit resets 11am (Europe/Amsterdam)"
117
+ },
118
+ "checks": [
119
+ {
120
+ "check": "exists docs/explain/0001-*/functional.md",
121
+ "ok": true,
122
+ "detail": "docs/explain/0001-branch-feature-discount/functional.md"
123
+ },
124
+ {
125
+ "check": "exists docs/explain/0001-*/technical.md",
126
+ "ok": false,
127
+ "detail": "nothing at docs/explain/0001-*/technical.md"
128
+ },
129
+ {
130
+ "check": "contains docs/explain/0001-*/functional.md",
131
+ "ok": true,
132
+ "detail": "all present"
133
+ },
134
+ {
135
+ "check": "contains docs/explain/0001-*/technical.md",
136
+ "ok": false,
137
+ "detail": "nothing at docs/explain/0001-*/technical.md"
138
+ },
139
+ {
140
+ "check": "pictures_only docs/explain/0001-*/*.md",
141
+ "ok": false,
142
+ "detail": "docs/explain/0001-branch-feature-discount/functional.md: D2 source not rendered; no images"
143
+ },
144
+ {
145
+ "check": "max_questions docs/explain/0001-*/*.md",
146
+ "ok": true,
147
+ "detail": "0 question(s)"
148
+ },
149
+ {
150
+ "check": "unchanged_outside [docs/, .claude/]",
151
+ "ok": false,
152
+ "detail": "shop/__pycache__/__init__.cpython-311.pyc, shop/__pycache__/discounts.cpython-311.pyc"
153
+ }
154
+ ],
155
+ "passed": 3,
156
+ "total": 7
157
+ }
158
+ ]
159
+ }