pz-cli 5.0.0__py3-none-any.whl

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 (399) hide show
  1. pz_cli-5.0.0.dist-info/METADATA +51 -0
  2. pz_cli-5.0.0.dist-info/RECORD +399 -0
  3. pz_cli-5.0.0.dist-info/WHEEL +4 -0
  4. pz_cli-5.0.0.dist-info/entry_points.txt +5 -0
  5. pz_core/__init__.py +64 -0
  6. pz_core/__main__.py +7 -0
  7. pz_core/app.py +45 -0
  8. pz_core/assembly/__init__.py +17 -0
  9. pz_core/assembly/app_discovery.py +1240 -0
  10. pz_core/assembly/apps/__init__.py +25 -0
  11. pz_core/assembly/apps/compiler.py +824 -0
  12. pz_core/assembly/apps/providers.py +188 -0
  13. pz_core/assembly/cli/__init__.py +9 -0
  14. pz_core/assembly/cli/compiler.py +166 -0
  15. pz_core/assembly/diagnostics/__init__.py +21 -0
  16. pz_core/assembly/diagnostics/checks.py +257 -0
  17. pz_core/assembly/diagnostics/dev_sources.py +569 -0
  18. pz_core/assembly/events/__init__.py +5 -0
  19. pz_core/assembly/events/compiler.py +219 -0
  20. pz_core/assembly/extensions/__init__.py +5 -0
  21. pz_core/assembly/extensions/compiler.py +696 -0
  22. pz_core/assembly/infra/__init__.py +6 -0
  23. pz_core/assembly/infra/compiler.py +272 -0
  24. pz_core/assembly/lifecycle/__init__.py +5 -0
  25. pz_core/assembly/lifecycle/compiler.py +95 -0
  26. pz_core/assembly/middlewares/__init__.py +19 -0
  27. pz_core/assembly/middlewares/compiler.py +508 -0
  28. pz_core/assembly/project/__init__.py +7 -0
  29. pz_core/assembly/project/compiler.py +9 -0
  30. pz_core/assembly/project/context.py +17 -0
  31. pz_core/assembly/project/discovery.py +227 -0
  32. pz_core/assembly/resources/__init__.py +19 -0
  33. pz_core/assembly/resources/compiler.py +310 -0
  34. pz_core/assembly/resources/settings.py +129 -0
  35. pz_core/assembly/routes/__init__.py +7 -0
  36. pz_core/assembly/routes/compiler.py +400 -0
  37. pz_core/assembly/runtime_manifests/__init__.py +13 -0
  38. pz_core/assembly/runtime_manifests/compiler.py +159 -0
  39. pz_core/assembly/settings/__init__.py +17 -0
  40. pz_core/assembly/settings/compiler.py +786 -0
  41. pz_core/assembly/settings/host_project_overrides.py +82 -0
  42. pz_core/assembly/settings/host_runtime_endpoint.py +207 -0
  43. pz_core/authoring/__init__.py +79 -0
  44. pz_core/authoring/app_init_service.py +946 -0
  45. pz_core/authoring/app_versions.py +814 -0
  46. pz_core/authoring/cli.py +192 -0
  47. pz_core/authoring/commands.py +1810 -0
  48. pz_core/authoring/conflicts.py +180 -0
  49. pz_core/authoring/dev_bindings.py +916 -0
  50. pz_core/authoring/dev_git.py +1087 -0
  51. pz_core/authoring/dev_import.py +1061 -0
  52. pz_core/authoring/dev_manifest.py +522 -0
  53. pz_core/authoring/dev_sources.py +1638 -0
  54. pz_core/authoring/env_cli.py +454 -0
  55. pz_core/authoring/files.py +109 -0
  56. pz_core/authoring/ide_projection.py +1129 -0
  57. pz_core/authoring/naming.py +58 -0
  58. pz_core/authoring/official_dev_sources.py +432 -0
  59. pz_core/authoring/official_sources.json +156 -0
  60. pz_core/authoring/orchestration_service.py +558 -0
  61. pz_core/authoring/project_default.jsonc +53 -0
  62. pz_core/authoring/project_defaults.py +88 -0
  63. pz_core/authoring/project_metadata_service.py +199 -0
  64. pz_core/authoring/project_settings_checks.py +51 -0
  65. pz_core/authoring/project_settings_cli.py +299 -0
  66. pz_core/authoring/project_settings_service.py +1700 -0
  67. pz_core/authoring/project_state.py +399 -0
  68. pz_core/authoring/publish_git.py +423 -0
  69. pz_core/authoring/publish_lock.py +188 -0
  70. pz_core/authoring/publish_source.py +195 -0
  71. pz_core/authoring/release.py +1382 -0
  72. pz_core/authoring/repo_keys.py +29 -0
  73. pz_core/authoring/root_cli.py +28 -0
  74. pz_core/authoring/scaffold_service.py +325 -0
  75. pz_core/authoring/sync_service.py +787 -0
  76. pz_core/authoring/templates/app/__init__.py +1 -0
  77. pz_core/authoring/templates/app/api.py +25 -0
  78. pz_core/authoring/templates/app/apps.py +31 -0
  79. pz_core/authoring/templates/app/auth_package_init.py +14 -0
  80. pz_core/authoring/templates/app/auth_readme.py +29 -0
  81. pz_core/authoring/templates/app/configs_package_init.py +14 -0
  82. pz_core/authoring/templates/app/default_env.py +18 -0
  83. pz_core/authoring/templates/app/default_jsonc.py +25 -0
  84. pz_core/authoring/templates/app/locales_readme.py +25 -0
  85. pz_core/authoring/templates/app/migrations_readme.py +19 -0
  86. pz_core/authoring/templates/app/models.py +14 -0
  87. pz_core/authoring/templates/app/package_init.py +8 -0
  88. pz_core/authoring/templates/app/pages_base.py +161 -0
  89. pz_core/authoring/templates/app/pages_readme.py +25 -0
  90. pz_core/authoring/templates/app/public.py +31 -0
  91. pz_core/authoring/templates/app/pyproject.py +77 -0
  92. pz_core/authoring/templates/app/readme.py +74 -0
  93. pz_core/authoring/templates/app/settings.py +46 -0
  94. pz_core/authoring/templates/app/static_app_js.py +24 -0
  95. pz_core/authoring/templates/app/static_readme.py +31 -0
  96. pz_core/authoring/templates/app/template_config_page.py +23 -0
  97. pz_core/authoring/templates/app/template_index_html.py +28 -0
  98. pz_core/authoring/templates/app/templates_readme.py +32 -0
  99. pz_core/authoring/templates/app/urls.py +36 -0
  100. pz_core/authoring/templates/app/views.py +36 -0
  101. pz_core/authoring/templates/project/__init__.py +1 -0
  102. pz_core/authoring/templates/project/agents.py +51 -0
  103. pz_core/authoring/templates/project/apps_container_readme.py +37 -0
  104. pz_core/authoring/templates/project/main_py.py +59 -0
  105. pz_core/authoring/templates/project/project_env.py +19 -0
  106. pz_core/authoring/templates/project/pyproject.py +26 -0
  107. pz_core/authoring/templates/project/pz_env_env.py +65 -0
  108. pz_core/authoring/templates/project/pz_env_jsonc.py +69 -0
  109. pz_core/authoring/templates/project/pz_jsonc.py +12 -0
  110. pz_core/authoring/templates/project/readme.py +94 -0
  111. pz_core/authoring/templates/project/root_gitkeep.py +8 -0
  112. pz_core/authoring/templates/shared/__init__.py +5 -0
  113. pz_core/authoring/templates/shared/text.py +10 -0
  114. pz_core/authoring/venv_service.py +87 -0
  115. pz_core/authoring/workspace.py +167 -0
  116. pz_core/cli.py +291 -0
  117. pz_core/cli_options.py +74 -0
  118. pz_core/core/__init__.py +3 -0
  119. pz_core/core/errors/__init__.py +5 -0
  120. pz_core/core/errors/models.py +117 -0
  121. pz_core/core/events/__init__.py +5 -0
  122. pz_core/core/events/registry.py +54 -0
  123. pz_core/core/extensions/__init__.py +51 -0
  124. pz_core/core/extensions/registry.py +790 -0
  125. pz_core/core/health/__init__.py +6 -0
  126. pz_core/core/health/contracts.py +10 -0
  127. pz_core/core/middlewares/__init__.py +6 -0
  128. pz_core/core/middlewares/models.py +24 -0
  129. pz_core/core/routing/__init__.py +5 -0
  130. pz_core/core/routing/models.py +21 -0
  131. pz_core/core/settings_contracts.py +25 -0
  132. pz_core/docs/README.md +20 -0
  133. pz_core/docs/distribution-README.md +438 -0
  134. pz_core/docs/pz/345/221/275/344/273/244/346/200/273/350/247/210.md +1011 -0
  135. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/00-pz/346/236/266/346/236/204/346/200/273/347/272/262.md +240 -0
  136. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/01-/347/233/256/345/275/225/344/270/216/345/210/206/345/261/202/350/247/204/350/214/203.md +216 -0
  137. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/02-/345/214/205/344/270/216/345/210/206/345/217/221/350/247/204/350/214/203.md +403 -0
  138. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/03-App/346/234/200/345/260/217/345/255/220/345/214/205/350/247/204/350/214/203.md +571 -0
  139. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/04-Settings/344/270/216/351/205/215/347/275/256/350/247/204/350/214/203.md +1177 -0
  140. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/05-/350/265/204/346/272/220/344/270/216/350/277/220/350/241/214/347/233/256/345/275/225/350/247/204/350/214/203.md +575 -0
  141. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/06-/346/225/260/346/215/256/345/272/223/344/270/216/345/217/257/351/200/211/345/237/272/347/241/200/350/256/276/346/226/275/350/247/204/350/214/203.md +499 -0
  142. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/07-App/346/233/277/346/215/242/350/247/204/350/214/203.md +206 -0
  143. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/08-/345/271/263/345/217/260/347/272/247App/344/270/216/350/277/220/350/241/214/346/227/266/345/215/225/344/276/213/350/247/204/350/214/203.md +445 -0
  144. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/09-CLI/344/270/216Worker/345/205/245/345/217/243/350/247/204/350/214/203.md +950 -0
  145. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/10-/346/265/213/350/257/225/344/270/216/345/245/221/347/272/246/350/247/204/350/214/203.md +1001 -0
  146. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/11-/344/273/223/345/272/223/347/234/237/347/233/270/346/272/220/345/234/260/345/233/276.md +102 -0
  147. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/12-/346/236/204/345/273/272/344/270/216/345/217/221/345/270/203/346/243/200/346/237/245/346/270/205/345/215/225.md +171 -0
  148. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/13-/346/255/243/345/274/217Facade/346/200/273/350/241/250.md +402 -0
  149. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/14-/345/210/206/345/261/202/344/270/216/346/211/251/345/261/225/350/247/204/350/214/203.md +550 -0
  150. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/15-/345/255/220/345/214/205/345/274/200/345/217/221/344/275/277/347/224/250/346/211/213/345/206/214.md +1004 -0
  151. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/16-/346/211/251/345/261/225/347/202/271/346/255/243/345/274/217/345/215/217/350/256/256/346/270/205/345/215/225.md +352 -0
  152. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/17-pz.protocols.v1/346/255/243/345/274/217/345/215/217/350/256/256.md +266 -0
  153. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/18-/346/211/251/345/261/225/347/202/271/345/206/262/347/252/201/350/243/201/345/206/263/346/200/273/350/241/250.md +131 -0
  154. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/19-/351/224/231/350/257/257/347/240/201/344/270/216/350/257/212/346/226/255/345/215/217/350/256/256.md +176 -0
  155. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/20-/347/247/201/346/234/211/345/214/205/344/273/223/344/270/216/347/273/237/344/270/200/350/256/244/350/257/201/351/203/250/347/275/262/350/247/204/350/214/203.md +243 -0
  156. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/21-contrib/347/272/246/345/256/232/344/270/216Provider/346/216/245/345/205/245/350/247/204/350/214/203.md +365 -0
  157. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/22-/345/244/232/345/233/275/350/257/255/350/250/200/350/265/204/346/272/220/346/262/273/347/220/206/344/270/216/346/214/211/351/234/200/345/212/240/350/275/275/350/247/204/350/214/203.md +912 -0
  158. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/23-/351/246/226/345/261/217/345/261/225/347/244/272/344/270/216/351/246/226/345/270/247/347/250/263/345/256/232/350/247/204/350/214/203.md +269 -0
  159. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/24-pz/345/220/257/345/212/250/344/270/216/350/277/220/350/241/214/346/227/266/347/274/226/350/257/221/346/265/201/347/250/213.md +245 -0
  160. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/25-/351/235/242/345/220/221/345/257/271/350/261/241/345/274/200/345/217/221/350/247/204/350/214/203.md +300 -0
  161. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/README.md +98 -0
  162. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/00-legacy_core/346/240/207/345/207/206pip/345/214/205/345/214/226/351/207/215/346/236/204/346/200/273/347/272/262.md +1073 -0
  163. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/01-/347/233/256/345/275/225/344/270/216/345/210/206/345/261/202/351/207/215/346/236/204/346/211/247/350/241/214/346/226/271/346/241/210.md +224 -0
  164. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/02-/345/214/205/344/270/216/345/210/206/345/217/221/350/247/204/350/214/203-/345/220/253/345/216/206/345/217/262/345/217/243/345/276/204.md +671 -0
  165. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/13-/344/270/200/346/254/241/346/200/247/345/256/236/346/226/275/346/270/205/345/215/225.md +387 -0
  166. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/14-/345/255/220/345/214/205/351/200/202/351/205/215/346/224/271/351/200/240/346/270/205/345/215/225.md +592 -0
  167. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/15-infra/350/243/201/345/211/252/344/270/216/350/220/275/344/275/215/346/270/205/345/215/225.md +81 -0
  168. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/19-core/345/215/225/344/270/200/346/255/243/345/274/217/346/226/271/346/241/210/346/224/266/346/225/233/346/211/247/350/241/214/346/270/205/345/215/225.md +161 -0
  169. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/25-/345/215/217/350/256/256/345/210/260/346/272/220/347/240/201/345/267/256/350/267/235/346/270/205/345/215/225.md +377 -0
  170. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/26-cutover/345/256/214/345/267/245/346/243/200/346/237/245/346/270/205/345/215/225.md +117 -0
  171. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/29-/345/244/232/345/233/275/350/257/255/350/250/200/350/265/204/346/272/220/346/262/273/347/220/206/344/270/216/346/214/211/351/234/200/345/212/240/350/275/275/350/247/204/350/214/203-/345/220/253/350/277/201/347/247/273/347/255/226/347/225/245.md +956 -0
  172. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/99-/350/265/204/346/272/220/346/224/266/345/217/243/345/220/216/347/273/255TODO.md +84 -0
  173. pz_core/docs//345/217/221/347/211/210/345/211/215/346/270/205/345/215/225-4.0.11.md +84 -0
  174. pz_core/docs//346/226/260/346/211/213/346/214/207/345/215/227.md +422 -0
  175. pz_core/infra/__init__.py +17 -0
  176. pz_core/infra/db/__init__.py +23 -0
  177. pz_core/infra/db/contracts.py +73 -0
  178. pz_core/infra/health/__init__.py +5 -0
  179. pz_core/infra/health/contracts.py +8 -0
  180. pz_core/infra/kv/__init__.py +5 -0
  181. pz_core/infra/kv/contracts.py +17 -0
  182. pz_core/infra/observability/__init__.py +23 -0
  183. pz_core/infra/observability/contracts.py +142 -0
  184. pz_core/infra/resilience/__init__.py +5 -0
  185. pz_core/infra/resilience/contracts.py +17 -0
  186. pz_core/infra/resources/__init__.py +5 -0
  187. pz_core/infra/resources/contracts.py +16 -0
  188. pz_core/infra/settings/__init__.py +17 -0
  189. pz_core/infra/settings/models.py +81 -0
  190. pz_core/infra/storage/__init__.py +5 -0
  191. pz_core/infra/storage/ports.py +27 -0
  192. pz_core/project_root_commands.py +282 -0
  193. pz_core/project_runtime_cli.py +344 -0
  194. pz_core/project_sources.py +253 -0
  195. pz_core/pz_launcher.py +209 -0
  196. pz_core/root_cli.py +70 -0
  197. pz_core/runtime/__init__.py +229 -0
  198. pz_core/runtime/access.py +86 -0
  199. pz_core/runtime/adapters/__init__.py +5 -0
  200. pz_core/runtime/adapters/base.py +18 -0
  201. pz_core/runtime/asyncio_bridge.py +18 -0
  202. pz_core/runtime/bindings/__init__.py +5 -0
  203. pz_core/runtime/bindings/container.py +50 -0
  204. pz_core/runtime/cli/__init__.py +5 -0
  205. pz_core/runtime/cli/_args.py +67 -0
  206. pz_core/runtime/cli/app_commands.py +417 -0
  207. pz_core/runtime/cli/check.py +214 -0
  208. pz_core/runtime/cli/db.py +297 -0
  209. pz_core/runtime/cli/main.py +89 -0
  210. pz_core/runtime/cli/resources.py +280 -0
  211. pz_core/runtime/discovery.py +23 -0
  212. pz_core/runtime/environment_integrity.py +157 -0
  213. pz_core/runtime/errors.py +5 -0
  214. pz_core/runtime/events.py +87 -0
  215. pz_core/runtime/facades/__init__.py +38 -0
  216. pz_core/runtime/facades/_capabilities.py +46 -0
  217. pz_core/runtime/facades/cache.py +103 -0
  218. pz_core/runtime/facades/database.py +71 -0
  219. pz_core/runtime/facades/events.py +380 -0
  220. pz_core/runtime/facades/health.py +101 -0
  221. pz_core/runtime/facades/mail.py +121 -0
  222. pz_core/runtime/facades/observability.py +102 -0
  223. pz_core/runtime/facades/providers.py +75 -0
  224. pz_core/runtime/facades/resources.py +52 -0
  225. pz_core/runtime/facades/storage.py +296 -0
  226. pz_core/runtime/health/__init__.py +5 -0
  227. pz_core/runtime/health/service.py +102 -0
  228. pz_core/runtime/host.py +188 -0
  229. pz_core/runtime/host_runner.py +282 -0
  230. pz_core/runtime/http/__init__.py +20 -0
  231. pz_core/runtime/http/app.py +576 -0
  232. pz_core/runtime/http_timing.py +173 -0
  233. pz_core/runtime/invocation.py +29 -0
  234. pz_core/runtime/json_safe.py +47 -0
  235. pz_core/runtime/lifecycle/__init__.py +25 -0
  236. pz_core/runtime/lifecycle/manager.py +533 -0
  237. pz_core/runtime/plan.py +214 -0
  238. pz_core/runtime/plan_context.py +33 -0
  239. pz_core/runtime/plan_snapshot.py +177 -0
  240. pz_core/runtime/registries/__init__.py +27 -0
  241. pz_core/runtime/registries/capabilities.py +101 -0
  242. pz_core/runtime/registries/providers.py +396 -0
  243. pz_core/runtime/resource_assets.py +344 -0
  244. pz_core/runtime/run_cli.py +211 -0
  245. pz_core/runtime/settings.py +888 -0
  246. pz_core/runtime/worker/__init__.py +21 -0
  247. pz_core/runtime/worker/engine.py +921 -0
  248. pz_core/runtime/worker/runtime.py +25 -0
  249. pz_core/testing/__init__.py +15 -0
  250. pz_core/testing/doc_route_contracts.py +305 -0
  251. pz_core/utils/__init__.py +44 -0
  252. pz_core/utils/env.py +65 -0
  253. pz_core/utils/project_jsonc/__init__.py +29 -0
  254. pz_core/utils/project_jsonc/document.py +420 -0
  255. pz_core/utils/project_settings.py +99 -0
  256. pz_foundation/__init__.py +50 -0
  257. pz_foundation/_contracts.py +81 -0
  258. pz_foundation/_errors.py +34 -0
  259. pz_foundation/api.py +14 -0
  260. pz_foundation/apps.py +127 -0
  261. pz_foundation/auth/__init__.py +1 -0
  262. pz_foundation/cache_control.py +233 -0
  263. pz_foundation/cli/__init__.py +2 -0
  264. pz_foundation/cli/workers.py +565 -0
  265. pz_foundation/configs/__init__.py +0 -0
  266. pz_foundation/configs/default.env +15 -0
  267. pz_foundation/configs/default.jsonc +452 -0
  268. pz_foundation/db/__init__.py +94 -0
  269. pz_foundation/db/aerich_executor.py +664 -0
  270. pz_foundation/db/config.py +358 -0
  271. pz_foundation/db/connection_manager.py +689 -0
  272. pz_foundation/db/connection_probe.py +204 -0
  273. pz_foundation/db/database.py +1291 -0
  274. pz_foundation/db/deps.py +47 -0
  275. pz_foundation/db/lifecycle_status.py +85 -0
  276. pz_foundation/db/migrations.py +477 -0
  277. pz_foundation/db/mysql.py +57 -0
  278. pz_foundation/db/postgresql.py +409 -0
  279. pz_foundation/db/production_pool_fallback.py +143 -0
  280. pz_foundation/db/public.py +45 -0
  281. pz_foundation/db/session.py +369 -0
  282. pz_foundation/db/sqlite.py +15 -0
  283. pz_foundation/db/tortoise_manager.py +724 -0
  284. pz_foundation/db/tortoise_psycopg.py +148 -0
  285. pz_foundation/docs/README.md +18 -0
  286. pz_foundation/docs/distribution-README.md +319 -0
  287. pz_foundation/docs/infra/350/243/201/345/211/252/344/270/216/350/220/275/344/275/215/350/257/264/346/230/216.md +39 -0
  288. pz_foundation/docs//345/205/254/345/274/200/345/205/215/350/264/271/346/216/245/345/217/243/351/230/262/346/273/245/347/224/250/344/270/216/344/272/272/346/234/272/346/240/241/351/252/214.md +680 -0
  289. pz_foundation/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +288 -0
  290. pz_foundation/docs//350/267/257/347/224/261/344/270/216URL/345/244/204/347/220/206/350/247/204/350/214/203.md +119 -0
  291. pz_foundation/health.py +105 -0
  292. pz_foundation/host/__init__.py +11 -0
  293. pz_foundation/host/builder.py +34 -0
  294. pz_foundation/host/cache_runtime.py +44 -0
  295. pz_foundation/host/db/__init__.py +17 -0
  296. pz_foundation/host/db/aerich_config.py +36 -0
  297. pz_foundation/host/db/config.py +106 -0
  298. pz_foundation/host/db/connection_manager.py +48 -0
  299. pz_foundation/host/db/deps.py +5 -0
  300. pz_foundation/host/db/orm_retry_patch.py +566 -0
  301. pz_foundation/host/db/request_adapter.py +325 -0
  302. pz_foundation/host/db/router.py +28 -0
  303. pz_foundation/host/db/session.py +284 -0
  304. pz_foundation/host/db/tortoise_manager.py +10 -0
  305. pz_foundation/host/idempotency.py +132 -0
  306. pz_foundation/host/lifespan.py +247 -0
  307. pz_foundation/host/redis_runtime.py +100 -0
  308. pz_foundation/host/web.py +790 -0
  309. pz_foundation/infra_provider.py +236 -0
  310. pz_foundation/kv/__init__.py +25 -0
  311. pz_foundation/kv/cache.py +1166 -0
  312. pz_foundation/kv/deps.py +84 -0
  313. pz_foundation/kv/public.py +25 -0
  314. pz_foundation/kv/redis_manager.py +1531 -0
  315. pz_foundation/lazy_exports.py +43 -0
  316. pz_foundation/lazy_imports.py +124 -0
  317. pz_foundation/lifecycle.py +392 -0
  318. pz_foundation/managed_workers.py +1117 -0
  319. pz_foundation/middlewares/__init__.py +26 -0
  320. pz_foundation/middlewares/_settings.py +250 -0
  321. pz_foundation/middlewares/analytics.py +124 -0
  322. pz_foundation/middlewares/cache_control.py +156 -0
  323. pz_foundation/middlewares/compression.py +202 -0
  324. pz_foundation/middlewares/cors.py +62 -0
  325. pz_foundation/middlewares/geo_country.py +44 -0
  326. pz_foundation/middlewares/inner_router.py +50 -0
  327. pz_foundation/middlewares/rate_limited/__init__.py +3 -0
  328. pz_foundation/middlewares/rate_limited/key_limiter.py +115 -0
  329. pz_foundation/middlewares/request_logging.py +104 -0
  330. pz_foundation/middlewares/route_owner.py +309 -0
  331. pz_foundation/middlewares/security_csrf.py +44 -0
  332. pz_foundation/middlewares/security_headers/__init__.py +4 -0
  333. pz_foundation/middlewares/security_headers/conflicts.py +44 -0
  334. pz_foundation/middlewares/security_headers/csp_nonce.py +200 -0
  335. pz_foundation/middlewares/security_headers/security_headers.py +44 -0
  336. pz_foundation/migrations/__init__.py +1 -0
  337. pz_foundation/migrations/pz_foundation/__init__.py +1 -0
  338. pz_foundation/models.py +22 -0
  339. pz_foundation/notifications/__init__.py +23 -0
  340. pz_foundation/notifications/email.py +542 -0
  341. pz_foundation/notifications/public.py +31 -0
  342. pz_foundation/observability/__init__.py +71 -0
  343. pz_foundation/observability/http.py +34 -0
  344. pz_foundation/observability/logger/__init__.py +49 -0
  345. pz_foundation/observability/logger/_bot_settings.py +126 -0
  346. pz_foundation/observability/logger/bot_message.py +592 -0
  347. pz_foundation/observability/logger/core.py +385 -0
  348. pz_foundation/observability/logger/delivery_audit.py +84 -0
  349. pz_foundation/observability/logger/feishu_bot.py +199 -0
  350. pz_foundation/observability/logger/telegram_bot.py +194 -0
  351. pz_foundation/observability/metrics.py +365 -0
  352. pz_foundation/observability/runtime.py +68 -0
  353. pz_foundation/public.py +405 -0
  354. pz_foundation/resources/__init__.py +12 -0
  355. pz_foundation/resources/builder.py +900 -0
  356. pz_foundation/resources/images.py +363 -0
  357. pz_foundation/root_cli.py +20 -0
  358. pz_foundation/routing/__init__.py +203 -0
  359. pz_foundation/routing/canonical.py +486 -0
  360. pz_foundation/routing/convertors.py +82 -0
  361. pz_foundation/routing/declarations.py +843 -0
  362. pz_foundation/routing/exports.py +148 -0
  363. pz_foundation/routing/loaders.py +138 -0
  364. pz_foundation/routing/manifest.py +215 -0
  365. pz_foundation/routing/manifest_provider.py +47 -0
  366. pz_foundation/routing/mounts.py +101 -0
  367. pz_foundation/routing/ordering.py +172 -0
  368. pz_foundation/routing/registry.py +133 -0
  369. pz_foundation/routing/utils.py +28 -0
  370. pz_foundation/runtime.py +234 -0
  371. pz_foundation/settings.py +253 -0
  372. pz_foundation/settings_normalization.py +130 -0
  373. pz_foundation/storage/__init__.py +25 -0
  374. pz_foundation/storage/local.py +209 -0
  375. pz_foundation/storage/public.py +106 -0
  376. pz_foundation/storage/s3.py +116 -0
  377. pz_foundation/storage/service.py +234 -0
  378. pz_foundation/urls.py +19 -0
  379. pz_foundation/utils/__init__.py +6 -0
  380. pz_foundation/utils/merge.py +160 -0
  381. pz_foundation/worker_replicas.py +55 -0
  382. pz_settings_center/__init__.py +5 -0
  383. pz_settings_center/api/__init__.py +5 -0
  384. pz_settings_center/api/runtime_overrides.py +360 -0
  385. pz_settings_center/apps.py +28 -0
  386. pz_settings_center/configs/__init__.py +0 -0
  387. pz_settings_center/configs/default.env +2 -0
  388. pz_settings_center/configs/default.jsonc +1 -0
  389. pz_settings_center/docs/01-settings_center/350/203/275/345/212/233/350/276/271/347/225/214.md +124 -0
  390. pz_settings_center/docs/README.md +12 -0
  391. pz_settings_center/docs/distribution-README.md +150 -0
  392. pz_settings_center/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +48 -0
  393. pz_settings_center/integration_payload.py +18 -0
  394. pz_settings_center/project_helpers.py +405 -0
  395. pz_settings_center/public.py +139 -0
  396. pz_settings_center/routing_helpers.py +73 -0
  397. pz_settings_center/runtime_override_provider.py +61 -0
  398. pz_settings_center/typed_settings.py +324 -0
  399. pz_settings_center/urls.py +9 -0
@@ -0,0 +1,188 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from pz_core.assembly.apps import AppRegistry, load_app_object_from_decl
6
+ from pz_core.assembly.project import active_project_import_root
7
+ from pz_core.assembly.settings import SettingsSnapshot
8
+ from pz_core.core.errors import PzError
9
+ from pz_core.runtime.registries.providers import ProviderDecl
10
+
11
+
12
+ def _read_required_string(
13
+ payload: dict[str, Any],
14
+ *,
15
+ key: str,
16
+ default: str | None = None,
17
+ code: str,
18
+ message: str,
19
+ owner: str,
20
+ ) -> str:
21
+ raw = payload.get(key)
22
+ if raw is None:
23
+ raw = default
24
+ if not isinstance(raw, str) or not raw.strip():
25
+ raise PzError(
26
+ code=code,
27
+ message=message,
28
+ stage="providers",
29
+ owner=owner,
30
+ action="compile_provider_declarations",
31
+ )
32
+ return raw.strip()
33
+
34
+
35
+ def _read_optional_string(
36
+ payload: dict[str, Any],
37
+ *,
38
+ key: str,
39
+ code: str,
40
+ message: str,
41
+ owner: str,
42
+ ) -> str | None:
43
+ if key not in payload:
44
+ return None
45
+ raw = payload.get(key)
46
+ if not isinstance(raw, str) or not raw.strip():
47
+ raise PzError(
48
+ code=code,
49
+ message=message,
50
+ stage="providers",
51
+ owner=owner,
52
+ action="compile_provider_declarations",
53
+ )
54
+ return raw.strip()
55
+
56
+
57
+ def _normalize_decl(payload: Any, *, owner_hint: str) -> ProviderDecl:
58
+ if not isinstance(payload, dict):
59
+ raise PzError(
60
+ code="PZ_PROVIDER_DECL_INVALID",
61
+ message=f"Provider declaration from '{owner_hint}' must be a table.",
62
+ stage="providers",
63
+ owner=owner_hint,
64
+ action="compile_provider_declarations",
65
+ )
66
+ binding_id = _read_required_string(
67
+ payload,
68
+ key="id",
69
+ code="PZ_PROVIDER_ID_INVALID",
70
+ message=f"Provider declaration from '{owner_hint}' must declare id as a non-empty string.",
71
+ owner=owner_hint,
72
+ )
73
+ capability = _read_required_string(
74
+ payload,
75
+ key="capability",
76
+ code="PZ_PROVIDER_CAPABILITY_INVALID",
77
+ message=f"Provider '{binding_id}' must declare capability as a non-empty string.",
78
+ owner=binding_id,
79
+ )
80
+ owner = _read_required_string(
81
+ payload,
82
+ key="owner",
83
+ default=owner_hint,
84
+ code="PZ_PROVIDER_OWNER_INVALID",
85
+ message=f"Provider '{binding_id}' must declare owner as a non-empty string.",
86
+ owner=binding_id,
87
+ )
88
+ scope = _read_required_string(
89
+ payload,
90
+ key="scope",
91
+ default="runtime",
92
+ code="PZ_PROVIDER_SCOPE_INVALID",
93
+ message=f"Provider '{binding_id}' scope must be 'runtime'.",
94
+ owner=binding_id,
95
+ )
96
+ provider_path = _read_optional_string(
97
+ payload,
98
+ key="provider_path",
99
+ code="PZ_PROVIDER_PATH_INVALID",
100
+ message=f"Provider '{binding_id}' provider_path must be a non-empty string import path when declared.",
101
+ owner=binding_id,
102
+ )
103
+ if scope not in {"runtime"}:
104
+ raise PzError(
105
+ code="PZ_PROVIDER_SCOPE_INVALID",
106
+ message=f"Provider '{binding_id}' scope must be 'runtime'.",
107
+ stage="providers",
108
+ owner=binding_id,
109
+ action="compile_provider_declarations",
110
+ )
111
+ return ProviderDecl(
112
+ binding_id=binding_id,
113
+ capability=capability,
114
+ owner=owner,
115
+ scope=scope,
116
+ provider_path=provider_path,
117
+ )
118
+
119
+
120
+ def _read_project_providers(settings: SettingsSnapshot) -> tuple[ProviderDecl, ...]:
121
+ raw = settings.get("providers", default=())
122
+ if raw in (None, (), []):
123
+ return ()
124
+ if not isinstance(raw, list):
125
+ raise PzError(
126
+ code="PZ_PROVIDERS_INVALID",
127
+ message="providers must be an array of tables.",
128
+ stage="providers",
129
+ owner="providers",
130
+ action="compile_provider_declarations",
131
+ )
132
+ return tuple(_normalize_decl(item, owner_hint="project.providers") for item in raw)
133
+
134
+
135
+ def _load_app_providers(app_registry: AppRegistry) -> tuple[ProviderDecl, ...]:
136
+ declarations: list[ProviderDecl] = []
137
+ for app in app_registry.apps:
138
+ app_obj = load_app_object_from_decl(app)
139
+ providers_factory = getattr(app_obj, "providers", None)
140
+ if providers_factory is None:
141
+ continue
142
+ if not callable(providers_factory):
143
+ raise PzError(
144
+ code="PZ_APP_PROVIDERS_INVALID",
145
+ message=f"App '{app.app_id}' exposes non-callable providers().",
146
+ stage="providers",
147
+ owner=app.app_id,
148
+ action="compile_provider_declarations",
149
+ )
150
+ declared = providers_factory()
151
+ if declared in (None, (), []):
152
+ continue
153
+ if not isinstance(declared, (list, tuple)):
154
+ raise PzError(
155
+ code="PZ_APP_PROVIDERS_INVALID",
156
+ message=f"App '{app.app_id}' providers() must return a list or tuple.",
157
+ stage="providers",
158
+ owner=app.app_id,
159
+ action="compile_provider_declarations",
160
+ )
161
+ for item in declared:
162
+ declarations.append(_normalize_decl(item, owner_hint=app.app_id))
163
+ return tuple(declarations)
164
+
165
+
166
+ def compile_provider_declarations(
167
+ settings: SettingsSnapshot,
168
+ app_registry: AppRegistry,
169
+ ) -> tuple[ProviderDecl, ...]:
170
+ project_dir = getattr(settings, "project_dir", None)
171
+ import_roots = getattr(settings, "import_roots", ())
172
+ with active_project_import_root(
173
+ project_dir,
174
+ extra_import_roots=import_roots,
175
+ ):
176
+ declarations = _read_project_providers(settings) + _load_app_providers(app_registry)
177
+ seen: set[str] = set()
178
+ for declaration in declarations:
179
+ if declaration.binding_id in seen:
180
+ raise PzError(
181
+ code="PZ_PROVIDER_DUPLICATE_ID",
182
+ message=f"Duplicate provider binding id '{declaration.binding_id}'.",
183
+ stage="providers",
184
+ owner=declaration.binding_id,
185
+ action="compile_provider_declarations",
186
+ )
187
+ seen.add(declaration.binding_id)
188
+ return declarations
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from .compiler import AppCliCommand, CliManifest, compile_cli_manifest
4
+
5
+ __all__ = [
6
+ "AppCliCommand",
7
+ "CliManifest",
8
+ "compile_cli_manifest",
9
+ ]
@@ -0,0 +1,166 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+ from pz_core.assembly.apps import AppRegistry
8
+ from pz_core.assembly.resources import ResourceManifest
9
+ from pz_core.core.errors import PzError
10
+ from pz_core.core.extensions import CliToolSpec
11
+
12
+
13
+ @dataclass(frozen=True, slots=True)
14
+ class AppCliCommand:
15
+ app_id: str
16
+ tool_name: str
17
+ module_path: str
18
+ import_path: str
19
+ spec: CliToolSpec
20
+
21
+ @property
22
+ def summary(self) -> str:
23
+ return self.spec.summary
24
+
25
+
26
+ @dataclass(frozen=True, slots=True)
27
+ class CliManifest:
28
+ commands: tuple[AppCliCommand, ...]
29
+
30
+
31
+ def _app_cli_import_root(*, entrypoint: str, owner: str) -> str:
32
+ module_name, _, attr_name = entrypoint.partition(":")
33
+ if attr_name != "app" or not module_name.endswith(".apps"):
34
+ raise PzError(
35
+ code="PZ_APP_CLI_IMPORT_ROOT_INVALID",
36
+ message=(
37
+ f"App '{owner}' entrypoint '{entrypoint}' must use "
38
+ "'<pkg>.apps:app' before CLI discovery."
39
+ ),
40
+ stage="cli",
41
+ owner=owner,
42
+ action="compile_cli_manifest",
43
+ )
44
+ return module_name[:-5]
45
+
46
+
47
+ def _cli_dir(package_root: Path) -> Path | None:
48
+ cli_dir = package_root / "cli"
49
+ if cli_dir.is_dir():
50
+ return cli_dir
51
+ if cli_dir.exists():
52
+ raise PzError(
53
+ code="PZ_APP_CLI_DIR_INVALID",
54
+ message=f"App CLI path '{cli_dir.name}' for package '{package_root.name}' must be a directory.",
55
+ stage="cli",
56
+ owner=str(package_root),
57
+ action="compile_cli_manifest",
58
+ )
59
+ return None
60
+
61
+
62
+ def _load_module(import_path: str) -> ModuleType:
63
+ return __import__(import_path, fromlist=["tool"])
64
+
65
+
66
+ def _load_cli_tool_spec(module: ModuleType, *, app_id: str, tool_name: str) -> CliToolSpec:
67
+ raw_tool = getattr(module, "tool", None)
68
+ if raw_tool is None:
69
+ raise PzError(
70
+ code="PZ_APP_CLI_TOOL_MISSING",
71
+ message=(
72
+ f"App CLI module '{module.__name__}' must expose a formal "
73
+ "CliToolSpec named 'tool'."
74
+ ),
75
+ stage="cli",
76
+ owner=app_id,
77
+ action="compile_cli_manifest",
78
+ )
79
+ if not isinstance(raw_tool, CliToolSpec):
80
+ raise PzError(
81
+ code="PZ_APP_CLI_TOOL_INVALID",
82
+ message=f"App CLI module '{module.__name__}' exposes non-CliToolSpec 'tool'.",
83
+ stage="cli",
84
+ owner=app_id,
85
+ action="compile_cli_manifest",
86
+ )
87
+ if raw_tool.kind != "cli.tool":
88
+ raise PzError(
89
+ code="PZ_APP_CLI_TOOL_KIND_INVALID",
90
+ message=f"App CLI tool '{raw_tool.id}' must declare kind='cli.tool'.",
91
+ stage="cli",
92
+ owner=app_id,
93
+ action="compile_cli_manifest",
94
+ )
95
+ if raw_tool.owner_app != app_id:
96
+ raise PzError(
97
+ code="PZ_APP_CLI_TOOL_OWNER_INVALID",
98
+ message=f"App CLI tool '{raw_tool.id}' owner_app must match '{app_id}'.",
99
+ stage="cli",
100
+ owner=app_id,
101
+ action="compile_cli_manifest",
102
+ )
103
+ if raw_tool.command != (tool_name,):
104
+ raise PzError(
105
+ code="PZ_APP_CLI_TOOL_COMMAND_INVALID",
106
+ message=f"App CLI tool '{raw_tool.id}' command must be ('{tool_name}',).",
107
+ stage="cli",
108
+ owner=app_id,
109
+ action="compile_cli_manifest",
110
+ )
111
+ tool_obj = raw_tool.tool
112
+ if not callable(getattr(tool_obj, "configure", None)) or not callable(getattr(tool_obj, "run", None)):
113
+ raise PzError(
114
+ code="PZ_APP_CLI_TOOL_OBJECT_INVALID",
115
+ message=f"App CLI tool '{raw_tool.id}' must expose configure(parser) and run(ctx).",
116
+ stage="cli",
117
+ owner=app_id,
118
+ action="compile_cli_manifest",
119
+ )
120
+ return raw_tool
121
+
122
+
123
+ def compile_cli_manifest(app_registry: AppRegistry, resource_manifest: ResourceManifest) -> CliManifest:
124
+ commands: list[AppCliCommand] = []
125
+ sources_by_app_id = {source.app_id: source for source in resource_manifest.sources}
126
+ for app in app_registry.apps:
127
+ import_root = _app_cli_import_root(entrypoint=app.entrypoint, owner=app.app_id)
128
+ source = sources_by_app_id.get(app.app_id)
129
+ if source is None:
130
+ raise PzError(
131
+ code="PZ_APP_CLI_RESOURCE_SOURCE_MISSING",
132
+ message=f"App '{app.app_id}' is missing a resource source entry for CLI discovery.",
133
+ stage="cli",
134
+ owner=app.app_id,
135
+ action="compile_cli_manifest",
136
+ )
137
+ cli_dir = _cli_dir(source.package_root)
138
+ if cli_dir is None:
139
+ continue
140
+ for path in sorted(cli_dir.glob("*.py")):
141
+ if path.name == "__init__.py" or path.name.startswith("_"):
142
+ continue
143
+ if not path.stem.isidentifier():
144
+ raise PzError(
145
+ code="PZ_APP_CLI_TOOL_INVALID",
146
+ message=(
147
+ f"App '{app.app_id}' CLI module '{path.name}' must use a valid Python "
148
+ "identifier filename."
149
+ ),
150
+ stage="cli",
151
+ owner=app.app_id,
152
+ action="compile_cli_manifest",
153
+ )
154
+ import_path = f"{import_root}.cli.{path.stem}"
155
+ module = _load_module(import_path)
156
+ spec = _load_cli_tool_spec(module, app_id=app.app_id, tool_name=path.stem)
157
+ commands.append(
158
+ AppCliCommand(
159
+ app_id=app.app_id,
160
+ tool_name=path.stem,
161
+ module_path=app.module_path,
162
+ import_path=import_path,
163
+ spec=spec,
164
+ )
165
+ )
166
+ return CliManifest(commands=tuple(commands))
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ from .checks import (
4
+ CheckItem,
5
+ CheckReport,
6
+ build_check_report,
7
+ build_dev_source_check_items,
8
+ build_source_preflight_report,
9
+ extend_check_report,
10
+ has_blocking_dev_source_failures,
11
+ )
12
+
13
+ __all__ = [
14
+ "CheckItem",
15
+ "CheckReport",
16
+ "build_check_report",
17
+ "build_dev_source_check_items",
18
+ "build_source_preflight_report",
19
+ "extend_check_report",
20
+ "has_blocking_dev_source_failures",
21
+ ]
@@ -0,0 +1,257 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from pathlib import Path
5
+ from typing import TYPE_CHECKING
6
+ from typing import Any
7
+
8
+ from pz_core.runtime.plan import RuntimePlan
9
+ from pz_core.runtime.registries import CapabilityStatus
10
+
11
+ if TYPE_CHECKING:
12
+ from pz_core.authoring.dev_git import DevGitService
13
+
14
+
15
+ @dataclass(frozen=True, slots=True)
16
+ class CheckItem:
17
+ severity: str
18
+ code: str
19
+ owner: str
20
+ scope: str
21
+ message: str
22
+ ok: bool
23
+ expected: str | None = None
24
+ actual: str | None = None
25
+ repair_command: str | None = None
26
+
27
+ def to_dict(self) -> dict[str, Any]:
28
+ return {
29
+ "severity": self.severity,
30
+ "code": self.code,
31
+ "owner": self.owner,
32
+ "scope": self.scope,
33
+ "message": self.message,
34
+ "ok": self.ok,
35
+ "expected": self.expected,
36
+ "actual": self.actual,
37
+ "repair_command": self.repair_command,
38
+ }
39
+
40
+
41
+ @dataclass(frozen=True, slots=True)
42
+ class CheckReport:
43
+ status: str
44
+ code: str
45
+ stage: str
46
+ owner: str
47
+ action: str
48
+ checks: tuple[CheckItem, ...]
49
+ installed_apps: tuple[str, ...]
50
+
51
+ def to_dict(self) -> dict[str, Any]:
52
+ return {
53
+ "status": self.status,
54
+ "code": self.code,
55
+ "stage": self.stage,
56
+ "owner": self.owner,
57
+ "action": self.action,
58
+ "installed_apps": list(self.installed_apps),
59
+ "checks": [item.to_dict() for item in self.checks],
60
+ }
61
+
62
+
63
+ def extend_check_report(
64
+ report: CheckReport, checks: tuple[CheckItem, ...]
65
+ ) -> CheckReport:
66
+ if not checks:
67
+ return report
68
+ merged_checks = tuple(report.checks) + tuple(checks)
69
+ has_failures = any(not item.ok for item in checks)
70
+ return CheckReport(
71
+ status="degraded" if has_failures or report.status != "ok" else report.status,
72
+ code="PZ_CHECK_DEGRADED"
73
+ if has_failures or report.status != "ok"
74
+ else report.code,
75
+ stage=report.stage,
76
+ owner=report.owner,
77
+ action=report.action,
78
+ checks=merged_checks,
79
+ installed_apps=report.installed_apps,
80
+ )
81
+
82
+
83
+ def build_dev_source_check_items(
84
+ project_dir: str | Path,
85
+ *,
86
+ git_service: DevGitService | None = None,
87
+ ) -> tuple[CheckItem, ...]:
88
+ from .dev_sources import build_dev_source_check_items as build_items
89
+
90
+ return build_items(project_dir, git_service=git_service)
91
+
92
+
93
+ def has_blocking_dev_source_failures(checks: tuple[CheckItem, ...]) -> bool:
94
+ from .dev_sources import has_blocking_dev_source_failures as has_failures
95
+
96
+ return has_failures(checks)
97
+
98
+
99
+ def build_source_preflight_report(checks: tuple[CheckItem, ...]) -> CheckReport:
100
+ return CheckReport(
101
+ status="degraded",
102
+ code="PZ_CHECK_DEGRADED",
103
+ stage="check",
104
+ owner="runtime.check",
105
+ action="compile_runtime_plan",
106
+ checks=checks,
107
+ installed_apps=(),
108
+ )
109
+
110
+
111
+ _ALLOWED_CAPABILITY_STATUSES: tuple[CapabilityStatus, ...] = (
112
+ "disabled",
113
+ "enabled",
114
+ "ready",
115
+ "unavailable",
116
+ )
117
+
118
+
119
+ def build_check_report(plan: RuntimePlan) -> CheckReport:
120
+ capability_statuses = plan.capability_registry.statuses()
121
+ unavailable_names = tuple(
122
+ name for name, status in capability_statuses.items() if status == "unavailable"
123
+ )
124
+ invalid_status_names = tuple(
125
+ name
126
+ for name, status in capability_statuses.items()
127
+ if status not in _ALLOWED_CAPABILITY_STATUSES
128
+ )
129
+
130
+ overall_status = "degraded" if unavailable_names else "ok"
131
+ overall_code = "PZ_CHECK_DEGRADED" if unavailable_names else "PZ_CHECK_OK"
132
+
133
+ checks = (
134
+ CheckItem(
135
+ severity="info",
136
+ code="PZ_CHECK_RUNTIME_PLAN_COMPILED",
137
+ owner="runtime.check",
138
+ scope="runtime_plan",
139
+ message="RuntimePlan compiled successfully.",
140
+ ok=True,
141
+ ),
142
+ CheckItem(
143
+ severity="info",
144
+ code="PZ_CHECK_INSTALLED_APPS_EMPTY_DEFAULT",
145
+ owner="runtime.check",
146
+ scope="settings",
147
+ message="installed_apps defaults to empty unless explicitly configured.",
148
+ ok=isinstance(plan.settings.installed_apps, tuple),
149
+ ),
150
+ CheckItem(
151
+ severity="info",
152
+ code="PZ_CHECK_CAPABILITY_REGISTRY_PRESENT",
153
+ owner="runtime.check",
154
+ scope="capabilities",
155
+ message="CapabilityRegistry is attached to RuntimePlan.",
156
+ ok=bool(plan.capability_registry.capabilities),
157
+ ),
158
+ CheckItem(
159
+ severity="info",
160
+ code="PZ_CHECK_CAPABILITY_STATUS_SEMANTICS",
161
+ owner="runtime.check",
162
+ scope="capabilities",
163
+ message="Capability status semantics use disabled/enabled/ready/unavailable.",
164
+ ok=not invalid_status_names,
165
+ ),
166
+ CheckItem(
167
+ severity="info",
168
+ code="PZ_CHECK_APP_REGISTRY_UNIQUE",
169
+ owner="runtime.check",
170
+ scope="apps",
171
+ message="AppRegistry keeps a unique app_id mapping.",
172
+ ok=len(plan.app_registry.apps) == len(plan.app_registry.by_id()),
173
+ ),
174
+ CheckItem(
175
+ severity="info",
176
+ code="PZ_CHECK_APP_INIT_EXECUTED",
177
+ owner="runtime.check",
178
+ scope="apps",
179
+ message="App init hooks completed during declared -> compiled.",
180
+ ok=plan.app_registry.initialized_app_ids
181
+ == tuple(app.app_id for app in plan.app_registry.apps),
182
+ ),
183
+ CheckItem(
184
+ severity="info",
185
+ code="PZ_CHECK_EVENT_REGISTRY_PRESENT",
186
+ owner="runtime.check",
187
+ scope="events",
188
+ message="EventRegistry was compiled before execution.",
189
+ ok=isinstance(plan.event_registry.events, tuple)
190
+ and isinstance(plan.event_registry.handlers, tuple),
191
+ ),
192
+ CheckItem(
193
+ severity="info",
194
+ code="PZ_CHECK_EXTENSION_REGISTRY_PRESENT",
195
+ owner="runtime.check",
196
+ scope="extensions",
197
+ message="ExtensionRegistry was compiled before execution.",
198
+ ok=isinstance(plan.extension_registry.extensions, tuple),
199
+ ),
200
+ CheckItem(
201
+ severity="info",
202
+ code="PZ_CHECK_PROVIDER_DECLARATIONS_PRESENT",
203
+ owner="runtime.check",
204
+ scope="providers",
205
+ message="Provider declarations were compiled before execution.",
206
+ ok=isinstance(plan.provider_declarations, tuple),
207
+ ),
208
+ CheckItem(
209
+ severity="info",
210
+ code="PZ_CHECK_RESOURCE_MANIFEST_LOCATION",
211
+ owner="runtime.check",
212
+ scope="resources",
213
+ message="ResourceManifest outputs stay under ProjectContext cache/runtime directories.",
214
+ ok=plan.resource_manifest.output_root == plan.infra.resources.output_dir
215
+ and plan.resource_manifest.lock_path == plan.infra.resources.lock_path
216
+ and plan.resource_manifest.manifest_path
217
+ == plan.infra.resources.manifest_path
218
+ and plan.resource_manifest.staging_root == plan.infra.resources.staging_dir,
219
+ ),
220
+ CheckItem(
221
+ severity="info",
222
+ code="PZ_CHECK_ROUTE_MANIFEST_PRESENT",
223
+ owner="runtime.check",
224
+ scope="routes",
225
+ message="RouteManifest was compiled before execution.",
226
+ ok=isinstance(plan.route_manifest.routes, tuple),
227
+ ),
228
+ CheckItem(
229
+ severity="info",
230
+ code="PZ_CHECK_MIDDLEWARE_MANIFEST_PRESENT",
231
+ owner="runtime.check",
232
+ scope="middlewares",
233
+ message="MiddlewareManifest was compiled before execution.",
234
+ ok=isinstance(plan.middleware_manifest.middlewares, tuple),
235
+ ),
236
+ CheckItem(
237
+ severity="warning" if unavailable_names else "info",
238
+ code="PZ_CHECK_CAPABILITY_AVAILABILITY",
239
+ owner="runtime.check",
240
+ scope="capabilities",
241
+ message=(
242
+ "Unavailable capabilities: " + ", ".join(unavailable_names)
243
+ if unavailable_names
244
+ else "No unavailable capabilities detected in current RuntimePlan."
245
+ ),
246
+ ok=not unavailable_names,
247
+ ),
248
+ )
249
+ return CheckReport(
250
+ status=overall_status,
251
+ code=overall_code,
252
+ stage="check",
253
+ owner="runtime.check",
254
+ action="compile_runtime_plan",
255
+ checks=checks,
256
+ installed_apps=plan.settings.installed_apps,
257
+ )