pz-cli 5.0.1__tar.gz → 5.0.2__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 (593) hide show
  1. {pz_cli-5.0.1 → pz_cli-5.0.2}/PKG-INFO +1 -1
  2. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/superpowers/specs/2026-07-13-pz-app-version-resolution-design.md +66 -34
  3. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/superpowers/specs/2026-07-13-pz-cli-single-wheel-design.md +1 -1
  4. {pz_cli-5.0.1 → pz_cli-5.0.2}/pyproject.toml +2 -2
  5. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/_contracts.py +6 -1
  6. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/cli/workers.py +9 -5
  7. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/configs/default.jsonc +27 -2
  8. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/tortoise_manager.py +0 -5
  9. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/docs/distribution-README.md +8 -5
  10. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +39 -4
  11. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/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 +1 -0
  12. pz_cli-5.0.2/pz_contrib/pz_foundation/pz_foundation/edge_cache.py +46 -0
  13. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/web.py +38 -62
  14. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/lifecycle.py +6 -0
  15. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/managed_workers.py +235 -9
  16. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/cache_control.py +125 -20
  17. pz_cli-5.0.2/pz_contrib/pz_foundation/pz_foundation/middlewares/request_logging.py +133 -0
  18. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/security_headers/csp_nonce.py +101 -4
  19. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/logger/core.py +17 -1
  20. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/logger/feishu_bot.py +8 -1
  21. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/logger/telegram_bot.py +17 -6
  22. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/public.py +74 -1
  23. pz_cli-5.0.2/pz_contrib/pz_foundation/pz_foundation/request_ids.py +92 -0
  24. pz_cli-5.0.2/pz_contrib/pz_foundation/pz_foundation/resource_delivery.py +101 -0
  25. pz_cli-5.0.2/pz_contrib/pz_foundation/pz_foundation/root_cli.py +16 -0
  26. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/declarations.py +130 -143
  27. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/loaders.py +58 -15
  28. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/manifest.py +77 -71
  29. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/registry.py +30 -10
  30. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/settings.py +31 -0
  31. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/storage/local.py +34 -3
  32. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/storage/public.py +24 -4
  33. pz_cli-5.0.2/pz_contrib/pz_foundation/pz_foundation/storage/s3.py +219 -0
  34. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/storage/service.py +29 -0
  35. pz_cli-5.0.2/pz_contrib/pz_foundation/pz_foundation/third_party.py +291 -0
  36. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/urls.py +1 -2
  37. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_managed_workers_contract.py +54 -6
  38. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_public_contract.py +17 -0
  39. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_settings_surface_contract.py +21 -1
  40. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_observability_logger_contract.py +9 -4
  41. pz_cli-5.0.2/pz_contrib/pz_foundation/tests/test_request_id_contract.py +136 -0
  42. pz_cli-5.0.2/pz_contrib/pz_foundation/tests/test_resource_delivery_contract.py +66 -0
  43. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_routing_declarations.py +104 -1
  44. pz_cli-5.0.2/pz_contrib/pz_foundation/tests/test_runtime_middlewares.py +718 -0
  45. pz_cli-5.0.2/pz_contrib/pz_foundation/tests/test_storage_backends.py +329 -0
  46. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_tortoise_manager_runtime_recovery.py +9 -0
  47. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/docs/distribution-README.md +1 -1
  48. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/project_helpers.py +5 -5
  49. pz_cli-5.0.2/pz_contrib/pz_settings_center/tests/test_project_helpers_contract.py +11 -0
  50. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/tests/test_metadata_contract.py +1 -1
  51. pz_cli-5.0.2/pz_core/pz_core/app_availability.py +476 -0
  52. pz_cli-5.0.2/pz_core/pz_core/app_sources.py +355 -0
  53. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/app_discovery.py +71 -0
  54. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/apps/compiler.py +24 -26
  55. pz_cli-5.0.2/pz_core/pz_core/assembly/cli/__init__.py +20 -0
  56. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/cli/compiler.py +51 -21
  57. pz_cli-5.0.2/pz_core/pz_core/assembly/cli/inventory.py +43 -0
  58. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/diagnostics/checks.py +3 -4
  59. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/diagnostics/dev_sources.py +9 -7
  60. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/extensions/compiler.py +8 -0
  61. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/project/discovery.py +23 -0
  62. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/settings/compiler.py +13 -24
  63. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/app_init_service.py +273 -20
  64. pz_cli-5.0.2/pz_core/pz_core/authoring/app_source_providers.py +398 -0
  65. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/app_versions.py +424 -23
  66. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/commands.py +621 -177
  67. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/dev_import.py +454 -57
  68. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/dev_sources.py +58 -7
  69. pz_cli-5.0.2/pz_core/pz_core/authoring/installed_app_dependencies.py +266 -0
  70. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/official_dev_sources.py +100 -16
  71. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/orchestration_service.py +453 -150
  72. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_settings_service.py +3 -1
  73. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/release.py +6 -0
  74. pz_cli-5.0.2/pz_core/pz_core/authoring/root_cli.py +23 -0
  75. pz_cli-5.0.2/pz_core/pz_core/authoring/source_closure.py +623 -0
  76. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/urls.py +3 -6
  77. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/apps_container_readme.py +2 -1
  78. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/pyproject.py +1 -1
  79. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/readme.py +6 -6
  80. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/cli.py +105 -53
  81. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/cli_options.py +5 -3
  82. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/command_catalog.py +27 -17
  83. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/extensions/registry.py +1 -0
  84. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/docs/README.md +4 -1
  85. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/docs/distribution-README.md +17 -21
  86. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/docs/pz/345/221/275/344/273/244/346/200/273/350/247/210.md +119 -70
  87. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +1 -1
  88. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +12 -4
  89. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +3 -0
  90. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +1 -1
  91. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +276 -68
  92. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +122 -25
  93. pz_cli-5.0.2/pz_core/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 +142 -0
  94. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +10 -1
  95. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +1 -1
  96. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +46 -39
  97. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +2 -0
  98. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +48 -3
  99. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +14 -11
  100. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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 +17 -3
  101. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/README.md +1 -0
  102. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/docs//346/226/260/346/211/213/346/214/207/345/215/227.md +14 -13
  103. pz_cli-5.0.2/pz_core/pz_core/import_ref.py +50 -0
  104. pz_cli-5.0.2/pz_core/pz_core/imported_command.py +36 -0
  105. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/storage/ports.py +6 -1
  106. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/root_cli.py +24 -4
  107. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/cli/app_commands.py +267 -58
  108. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/cli/check.py +11 -0
  109. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/cli/main.py +28 -29
  110. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/storage.py +127 -5
  111. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/host.py +6 -1
  112. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/host_runner.py +42 -14
  113. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/http/app.py +6 -14
  114. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/http_timing.py +3 -2
  115. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/lifecycle/__init__.py +2 -0
  116. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/plan.py +6 -2
  117. pz_cli-5.0.2/pz_core/pz_core/runtime/request_id.py +62 -0
  118. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/settings.py +5 -1
  119. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/worker/engine.py +8 -5
  120. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/scripts/README.md +4 -4
  121. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/assembly/test_visible_app_discovery.py +38 -1
  122. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_app_init_from_bindings.py +143 -2
  123. pz_cli-5.0.2/pz_core/tests/authoring/test_app_source_providers.py +209 -0
  124. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_app_versions.py +336 -18
  125. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_business_app_id.py +1 -1
  126. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_binding_transaction.py +73 -0
  127. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_check_diagnostics.py +2 -2
  128. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_cli.py +252 -21
  129. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_import.py +96 -0
  130. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_ide_projection.py +70 -28
  131. pz_cli-5.0.2/pz_core/tests/authoring/test_installed_app_dependencies.py +134 -0
  132. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_orchestration_service.py +231 -18
  133. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_project_pyproject_repair.py +2 -2
  134. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_repair_cli.py +1 -1
  135. pz_cli-5.0.2/pz_core/tests/authoring/test_source_closure.py +419 -0
  136. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_source_locator_resolution.py +30 -5
  137. pz_cli-5.0.2/pz_core/tests/core/test_app_availability.py +131 -0
  138. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_app_registry_contract.py +39 -0
  139. pz_cli-5.0.2/pz_core/tests/core/test_app_source_catalog.py +82 -0
  140. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_cli_list_contract.py +145 -0
  141. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_http_timing_contract.py +4 -4
  142. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_infra_contracts.py +6 -0
  143. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_infra_facades_contract.py +9 -0
  144. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_project_settings_contract.py +5 -1
  145. pz_cli-5.0.2/pz_core/tests/core/test_request_id_contract.py +32 -0
  146. pz_cli-5.0.2/pz_core/tests/core/test_root_cli_discovery.py +67 -0
  147. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_runtime_access_contract.py +52 -2
  148. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_runtime_facades_contract.py +154 -23
  149. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_runtime_plan_app_factory_contract.py +8 -4
  150. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_runtime_plan_contract.py +7 -3
  151. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/test_cli_contract.py +210 -94
  152. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/test_publish_contract.py +4 -0
  153. {pz_cli-5.0.1 → pz_cli-5.0.2}/uv.lock +1 -1
  154. pz_cli-5.0.1/docs/superpowers/specs/2026-07-12-pz-shared-sources-symlink-design.md +0 -80
  155. pz_cli-5.0.1/docs/superpowers/specs/2026-07-13-pz-dev-add-link-source-ownership-design.md +0 -493
  156. pz_cli-5.0.1/docs/superpowers/specs/2026-07-14-pz-project-pyproject-repair-design.md +0 -432
  157. pz_cli-5.0.1/docs/superpowers/specs/2026-07-14-pz-version-flag-design.md +0 -18
  158. pz_cli-5.0.1/pz_contrib/pz_foundation/pz_foundation/middlewares/request_logging.py +0 -104
  159. pz_cli-5.0.1/pz_contrib/pz_foundation/pz_foundation/root_cli.py +0 -20
  160. pz_cli-5.0.1/pz_contrib/pz_foundation/pz_foundation/storage/s3.py +0 -116
  161. pz_cli-5.0.1/pz_contrib/pz_foundation/tests/test_runtime_middlewares.py +0 -346
  162. pz_cli-5.0.1/pz_contrib/pz_foundation/tests/test_storage_backends.py +0 -72
  163. pz_cli-5.0.1/pz_core/pz_core/assembly/cli/__init__.py +0 -9
  164. pz_cli-5.0.1/pz_core/pz_core/authoring/root_cli.py +0 -28
  165. pz_cli-5.0.1/pz_core/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 +0 -102
  166. {pz_cli-5.0.1 → pz_cli-5.0.2}/.gitignore +0 -0
  167. {pz_cli-5.0.1 → pz_cli-5.0.2}/AGENTS.md +0 -0
  168. {pz_cli-5.0.1 → pz_cli-5.0.2}/README.md +0 -0
  169. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/history/pz_contrib/2026-04-22-contrib-deprecated-code-audit.md +0 -0
  170. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/history/pz_contrib/README.md +0 -0
  171. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/history/pz_contrib/distribution-README.md +0 -0
  172. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/in_progress/README.md +0 -0
  173. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/in_progress/Studio/347/274/226/350/276/221/345/231/250/350/256/276/350/256/241.md" +0 -0
  174. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/in_progress//344/270/212/344/274/240/345/220/216/347/253/213/345/215/263/345/274/200/345/247/213/345/274/200/345/205/263/344/270/216/346/211/213/345/212/250/347/277/273/350/257/221/351/230/237/345/210/227/346/226/271/346/241/210.md" +0 -0
  175. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/in_progress//346/212/275/345/245/226/346/250/241/345/235/227/350/256/276/350/256/241.md" +0 -0
  176. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/superpowers/plans/2026-06-27-page-center-pseo-admin.md +0 -0
  177. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/superpowers/specs/2026-06-27-page-center-pseo-admin-design.md +0 -0
  178. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/superpowers/specs/2026-07-13-pz-publish-git-release-orchestration-design.md +0 -0
  179. {pz_cli-5.0.1 → pz_cli-5.0.2}/docs/superpowers/specs/2026-07-13-pz-vscode-shadow-projection-design.md +0 -0
  180. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/.gitignore +0 -0
  181. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/AGENTS.md +0 -0
  182. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/foundation_testsupport/__init__.py +0 -0
  183. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/foundation_testsupport/orm_models.py +0 -0
  184. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/__init__.py +0 -0
  185. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/_errors.py +0 -0
  186. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/api.py +0 -0
  187. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/apps.py +0 -0
  188. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/auth/__init__.py +0 -0
  189. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/cache_control.py +0 -0
  190. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/cli/__init__.py +0 -0
  191. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/configs/__init__.py +0 -0
  192. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/configs/default.env +0 -0
  193. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/__init__.py +0 -0
  194. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/aerich_executor.py +0 -0
  195. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/config.py +0 -0
  196. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/connection_manager.py +0 -0
  197. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/connection_probe.py +0 -0
  198. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/database.py +0 -0
  199. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/deps.py +0 -0
  200. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/lifecycle_status.py +0 -0
  201. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/migrations.py +0 -0
  202. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/mysql.py +0 -0
  203. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/postgresql.py +0 -0
  204. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/production_pool_fallback.py +0 -0
  205. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/public.py +0 -0
  206. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/session.py +0 -0
  207. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/sqlite.py +0 -0
  208. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/db/tortoise_psycopg.py +0 -0
  209. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/docs/README.md +0 -0
  210. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/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" +0 -0
  211. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/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" +0 -0
  212. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/health.py +0 -0
  213. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/__init__.py +0 -0
  214. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/builder.py +0 -0
  215. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/cache_runtime.py +0 -0
  216. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/__init__.py +0 -0
  217. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/aerich_config.py +0 -0
  218. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/config.py +0 -0
  219. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/connection_manager.py +0 -0
  220. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/deps.py +0 -0
  221. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/orm_retry_patch.py +0 -0
  222. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/request_adapter.py +0 -0
  223. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/router.py +0 -0
  224. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/session.py +0 -0
  225. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/db/tortoise_manager.py +0 -0
  226. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/idempotency.py +0 -0
  227. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/lifespan.py +0 -0
  228. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/host/redis_runtime.py +0 -0
  229. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/infra_provider.py +0 -0
  230. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/kv/__init__.py +0 -0
  231. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/kv/cache.py +0 -0
  232. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/kv/deps.py +0 -0
  233. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/kv/public.py +0 -0
  234. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/kv/redis_manager.py +0 -0
  235. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/lazy_exports.py +0 -0
  236. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/lazy_imports.py +0 -0
  237. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/__init__.py +0 -0
  238. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/_settings.py +0 -0
  239. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/analytics.py +0 -0
  240. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/compression.py +0 -0
  241. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/cors.py +0 -0
  242. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/geo_country.py +0 -0
  243. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/inner_router.py +0 -0
  244. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/rate_limited/__init__.py +0 -0
  245. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/rate_limited/key_limiter.py +0 -0
  246. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/route_owner.py +0 -0
  247. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/security_csrf.py +0 -0
  248. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/security_headers/__init__.py +0 -0
  249. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/security_headers/conflicts.py +0 -0
  250. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/middlewares/security_headers/security_headers.py +0 -0
  251. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/migrations/__init__.py +0 -0
  252. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/migrations/pz_foundation/__init__.py +0 -0
  253. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/models.py +0 -0
  254. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/notifications/__init__.py +0 -0
  255. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/notifications/email.py +0 -0
  256. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/notifications/public.py +0 -0
  257. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/__init__.py +0 -0
  258. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/http.py +0 -0
  259. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/logger/__init__.py +0 -0
  260. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/logger/_bot_settings.py +0 -0
  261. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/logger/bot_message.py +0 -0
  262. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/logger/delivery_audit.py +0 -0
  263. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/metrics.py +0 -0
  264. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/observability/runtime.py +0 -0
  265. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/resources/__init__.py +0 -0
  266. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/resources/builder.py +0 -0
  267. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/resources/images.py +0 -0
  268. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/__init__.py +0 -0
  269. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/canonical.py +0 -0
  270. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/convertors.py +0 -0
  271. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/exports.py +0 -0
  272. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/manifest_provider.py +0 -0
  273. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/mounts.py +0 -0
  274. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/ordering.py +0 -0
  275. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/routing/utils.py +0 -0
  276. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/runtime.py +0 -0
  277. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/settings_normalization.py +0 -0
  278. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/storage/__init__.py +0 -0
  279. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/utils/__init__.py +0 -0
  280. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/utils/merge.py +0 -0
  281. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/pz_foundation/worker_replicas.py +0 -0
  282. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/conftest.py +0 -0
  283. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/fixtures/__init__.py +0 -0
  284. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/fixtures/orm_models.py +0 -0
  285. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_aerich_executor_contract.py +0 -0
  286. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_asset_directory_contract.py +0 -0
  287. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_database_probe_contract.py +0 -0
  288. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_database_url_options.py +0 -0
  289. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_distribution_contract.py +0 -0
  290. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_aerich_executor.py +0 -0
  291. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_analytics_contract.py +0 -0
  292. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_database_runtime_contract.py +0 -0
  293. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_database_session.py +0 -0
  294. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_db_connection_manager_contract.py +0 -0
  295. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_db_lifecycle_status_contract.py +0 -0
  296. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_db_request_adapter_contract.py +0 -0
  297. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_host_db_session_contract.py +0 -0
  298. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_host_lifespan_contract.py +0 -0
  299. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_lazy_imports_contract.py +0 -0
  300. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_mail_runtime_contract.py +0 -0
  301. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_prometheus_metrics.py +0 -0
  302. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_provider_contract.py +0 -0
  303. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_redis_config.py +0 -0
  304. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_redis_runtime_contract.py +0 -0
  305. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_resource_images_contract.py +0 -0
  306. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_security_headers_contract.py +0 -0
  307. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_tortoise_model_binding.py +0 -0
  308. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_foundation_tortoise_psycopg_contract.py +0 -0
  309. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_key_limiter.py +0 -0
  310. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_managed_workers_cli.py +0 -0
  311. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_observability_bot_backpressure.py +0 -0
  312. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_observability_lazy_import_contract.py +0 -0
  313. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_orm_retry_patch.py +0 -0
  314. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_redis_manager.py +0 -0
  315. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_resource_images.py +0 -0
  316. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_route_ordering.py +0 -0
  317. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_route_owner_middleware.py +0 -0
  318. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_settings_template_contract.py +0 -0
  319. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_utils_merge.py +0 -0
  320. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_foundation/tests/test_v5_regression_contract.py +0 -0
  321. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/__init__.py +0 -0
  322. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/api/__init__.py +0 -0
  323. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/api/runtime_overrides.py +0 -0
  324. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/apps.py +0 -0
  325. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/configs/__init__.py +0 -0
  326. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/configs/default.env +0 -0
  327. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/configs/default.jsonc +0 -0
  328. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/docs/01-settings_center/350/203/275/345/212/233/350/276/271/347/225/214.md" +0 -0
  329. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/docs/README.md +0 -0
  330. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/docs//350/256/276/350/256/241/346/226/207/346/241/243.md" +0 -0
  331. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/integration_payload.py +0 -0
  332. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/public.py +0 -0
  333. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/routing_helpers.py +0 -0
  334. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/runtime_override_provider.py +0 -0
  335. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/typed_settings.py +0 -0
  336. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/pz_settings_center/urls.py +0 -0
  337. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/tests/test_integration_payload.py +0 -0
  338. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/pz_settings_center/tests/test_runtime_overrides_contract.py +0 -0
  339. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_contrib/tests/test_minimal_dependency_direction_contract.py +0 -0
  340. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/.gitignore +0 -0
  341. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/AGENTS.md +0 -0
  342. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/__init__.py +0 -0
  343. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/__main__.py +0 -0
  344. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/app.py +0 -0
  345. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/__init__.py +0 -0
  346. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/apps/__init__.py +0 -0
  347. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/apps/providers.py +0 -0
  348. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/diagnostics/__init__.py +0 -0
  349. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/events/__init__.py +0 -0
  350. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/events/compiler.py +0 -0
  351. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/extensions/__init__.py +0 -0
  352. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/infra/__init__.py +0 -0
  353. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/infra/compiler.py +0 -0
  354. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/lifecycle/__init__.py +0 -0
  355. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/lifecycle/compiler.py +0 -0
  356. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/middlewares/__init__.py +0 -0
  357. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/middlewares/compiler.py +0 -0
  358. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/project/__init__.py +0 -0
  359. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/project/compiler.py +0 -0
  360. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/project/context.py +0 -0
  361. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/resources/__init__.py +0 -0
  362. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/resources/compiler.py +0 -0
  363. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/resources/settings.py +0 -0
  364. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/routes/__init__.py +0 -0
  365. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/routes/compiler.py +0 -0
  366. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/runtime_manifests/__init__.py +0 -0
  367. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/runtime_manifests/compiler.py +0 -0
  368. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/settings/__init__.py +0 -0
  369. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/settings/host_project_overrides.py +0 -0
  370. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/assembly/settings/host_runtime_endpoint.py +0 -0
  371. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/__init__.py +0 -0
  372. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/cli.py +0 -0
  373. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/conflicts.py +0 -0
  374. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/dependency_checks.py +0 -0
  375. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/dev_bindings.py +0 -0
  376. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/dev_git.py +0 -0
  377. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/dev_manifest.py +0 -0
  378. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/dev_project.py +0 -0
  379. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/env_cli.py +0 -0
  380. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/file_transaction.py +0 -0
  381. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/files.py +0 -0
  382. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/ide_projection.py +0 -0
  383. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/naming.py +0 -0
  384. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/official_sources.json +0 -0
  385. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/orchestration.py +0 -0
  386. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_default.jsonc +0 -0
  387. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_defaults.py +0 -0
  388. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_dependencies.py +0 -0
  389. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_metadata_service.py +0 -0
  390. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_repair.py +0 -0
  391. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_settings_checks.py +0 -0
  392. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_settings_cli.py +0 -0
  393. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/project_state.py +0 -0
  394. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/publish_git.py +0 -0
  395. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/publish_lock.py +0 -0
  396. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/publish_source.py +0 -0
  397. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/pyproject_repair.py +0 -0
  398. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/repo_keys.py +0 -0
  399. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/scaffold_service.py +0 -0
  400. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/source_identity.py +0 -0
  401. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/sync_service.py +0 -0
  402. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/__init__.py +0 -0
  403. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/api.py +0 -0
  404. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/apps.py +0 -0
  405. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/auth_package_init.py +0 -0
  406. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/auth_readme.py +0 -0
  407. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/configs_package_init.py +0 -0
  408. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/default_env.py +0 -0
  409. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/default_jsonc.py +0 -0
  410. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/locales_readme.py +0 -0
  411. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/migrations_readme.py +0 -0
  412. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/models.py +0 -0
  413. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/package_init.py +0 -0
  414. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/pages_base.py +0 -0
  415. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/pages_readme.py +0 -0
  416. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/public.py +0 -0
  417. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/pyproject.py +0 -0
  418. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/readme.py +0 -0
  419. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/settings.py +0 -0
  420. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/static_app_js.py +0 -0
  421. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/static_readme.py +0 -0
  422. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/template_config_page.py +0 -0
  423. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/template_index_html.py +0 -0
  424. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/templates_readme.py +0 -0
  425. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/app/views.py +0 -0
  426. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/__init__.py +0 -0
  427. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/agents.py +0 -0
  428. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/main_py.py +0 -0
  429. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/project_env.py +0 -0
  430. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/pz_env_env.py +0 -0
  431. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/pz_env_jsonc.py +0 -0
  432. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/pz_jsonc.py +0 -0
  433. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/project/root_gitkeep.py +0 -0
  434. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/shared/__init__.py +0 -0
  435. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/templates/shared/text.py +0 -0
  436. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/venv_service.py +0 -0
  437. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/authoring/workspace.py +0 -0
  438. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/cli_routing.py +0 -0
  439. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/__init__.py +0 -0
  440. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/errors/__init__.py +0 -0
  441. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/errors/models.py +0 -0
  442. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/events/__init__.py +0 -0
  443. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/events/registry.py +0 -0
  444. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/extensions/__init__.py +0 -0
  445. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/health/__init__.py +0 -0
  446. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/health/contracts.py +0 -0
  447. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/middlewares/__init__.py +0 -0
  448. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/middlewares/models.py +0 -0
  449. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/routing/__init__.py +0 -0
  450. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/routing/models.py +0 -0
  451. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/core/settings_contracts.py +0 -0
  452. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  453. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  454. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  455. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  456. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  457. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  458. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  459. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  460. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  461. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  462. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  463. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  464. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  465. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  466. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  467. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  468. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  469. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  470. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  471. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  472. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  473. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  474. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/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" +0 -0
  475. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/docs//345/217/221/347/211/210/345/211/215/346/270/205/345/215/225-4.0.11.md" +0 -0
  476. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/__init__.py +0 -0
  477. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/db/__init__.py +0 -0
  478. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/db/contracts.py +0 -0
  479. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/health/__init__.py +0 -0
  480. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/health/contracts.py +0 -0
  481. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/kv/__init__.py +0 -0
  482. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/kv/contracts.py +0 -0
  483. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/observability/__init__.py +0 -0
  484. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/observability/contracts.py +0 -0
  485. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/resilience/__init__.py +0 -0
  486. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/resilience/contracts.py +0 -0
  487. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/resources/__init__.py +0 -0
  488. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/resources/contracts.py +0 -0
  489. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/settings/__init__.py +0 -0
  490. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/settings/models.py +0 -0
  491. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/infra/storage/__init__.py +0 -0
  492. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/project_root_commands.py +0 -0
  493. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/project_runtime_cli.py +0 -0
  494. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/project_runtime_entry.py +0 -0
  495. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/project_sources.py +0 -0
  496. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/pz_launcher.py +0 -0
  497. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/__init__.py +0 -0
  498. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/access.py +0 -0
  499. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/adapters/__init__.py +0 -0
  500. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/adapters/base.py +0 -0
  501. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/asyncio_bridge.py +0 -0
  502. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/bindings/__init__.py +0 -0
  503. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/bindings/container.py +0 -0
  504. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/cli/__init__.py +0 -0
  505. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/cli/_args.py +0 -0
  506. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/cli/db.py +0 -0
  507. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/cli/resources.py +0 -0
  508. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/discovery.py +0 -0
  509. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/environment_integrity.py +0 -0
  510. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/errors.py +0 -0
  511. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/events.py +0 -0
  512. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/__init__.py +0 -0
  513. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/_capabilities.py +0 -0
  514. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/cache.py +0 -0
  515. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/database.py +0 -0
  516. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/events.py +0 -0
  517. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/health.py +0 -0
  518. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/mail.py +0 -0
  519. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/observability.py +0 -0
  520. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/providers.py +0 -0
  521. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/facades/resources.py +0 -0
  522. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/health/__init__.py +0 -0
  523. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/health/service.py +0 -0
  524. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/http/__init__.py +0 -0
  525. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/invocation.py +0 -0
  526. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/json_safe.py +0 -0
  527. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/lifecycle/manager.py +0 -0
  528. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/plan_context.py +0 -0
  529. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/plan_snapshot.py +0 -0
  530. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/registries/__init__.py +0 -0
  531. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/registries/capabilities.py +0 -0
  532. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/registries/providers.py +0 -0
  533. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/resource_assets.py +0 -0
  534. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/run_cli.py +0 -0
  535. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/worker/__init__.py +0 -0
  536. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/runtime/worker/runtime.py +0 -0
  537. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/testing/__init__.py +0 -0
  538. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/testing/doc_route_contracts.py +0 -0
  539. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/utils/__init__.py +0 -0
  540. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/utils/env.py +0 -0
  541. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/utils/project_jsonc/__init__.py +0 -0
  542. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/utils/project_jsonc/document.py +0 -0
  543. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/pz_core/utils/project_settings.py +0 -0
  544. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/scripts/build_pz.sh +0 -0
  545. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/scripts/install_pz.sh +0 -0
  546. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/__init__.py +0 -0
  547. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/git_fixtures.py +0 -0
  548. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dependency_checks.py +0 -0
  549. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_bindings.py +0 -0
  550. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_git_integration.py +0 -0
  551. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_git_unit.py +0 -0
  552. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_manifest.py +0 -0
  553. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_dev_update_remove.py +0 -0
  554. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_file_transaction.py +0 -0
  555. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_project_metadata_service.py +0 -0
  556. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_project_repair_environment.py +0 -0
  557. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_source_identity.py +0 -0
  558. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/authoring/test_sync_service_artifacts.py +0 -0
  559. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/conftest.py +0 -0
  560. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_api_assembly_minimal_host_contract.py +0 -0
  561. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_cli_check_contract.py +0 -0
  562. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_core_layout_contract.py +0 -0
  563. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_db_cli_contract.py +0 -0
  564. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_doc_route_contracts.py +0 -0
  565. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_event_extension_registry_contract.py +0 -0
  566. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_extension_registry_contract.py +0 -0
  567. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_host_assembly_contract.py +0 -0
  568. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_middleware_manifest_contract.py +0 -0
  569. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_project_context_contract.py +0 -0
  570. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_project_jsonc_contract.py +0 -0
  571. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_project_sources_contract.py +0 -0
  572. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_release_contract.py +0 -0
  573. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_resource_manifest_contract.py +0 -0
  574. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_route_manifest_contract.py +0 -0
  575. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_runtime_import_contract.py +0 -0
  576. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_runtime_settings_contract.py +0 -0
  577. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_settings_contracts.py +0 -0
  578. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/core/test_settings_snapshot_precedence_contract.py +0 -0
  579. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/runtime/test_environment_integrity.py +0 -0
  580. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/test_resources_cli_contract.py +0 -0
  581. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/test_runtime_resource_assets.py +0 -0
  582. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/test_runtime_resources_cli.py +0 -0
  583. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/test_scaffold_service_contract.py +0 -0
  584. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/test_utils_env_contract.py +0 -0
  585. {pz_cli-5.0.1 → pz_cli-5.0.2}/pz_core/tests/test_utils_project_settings_contract.py +0 -0
  586. {pz_cli-5.0.1 → pz_cli-5.0.2}/tools/release/pyproject.toml +0 -0
  587. {pz_cli-5.0.1 → pz_cli-5.0.2}/tools/release/pz_release/__init__.py +0 -0
  588. {pz_cli-5.0.1 → pz_cli-5.0.2}/tools/release/pz_release/build_minimal.py +0 -0
  589. {pz_cli-5.0.1 → pz_cli-5.0.2}/tools/release/pz_release/distributions.py +0 -0
  590. {pz_cli-5.0.1 → pz_cli-5.0.2}/tools/release/pz_release/verify_minimal_runtime.py +0 -0
  591. {pz_cli-5.0.1 → pz_cli-5.0.2}/tools/release/tests/test_distribution_graph.py +0 -0
  592. {pz_cli-5.0.1 → pz_cli-5.0.2}/tools/release/tests/test_verify_minimal_runtime.py +0 -0
  593. {pz_cli-5.0.1 → pz_cli-5.0.2}/tools/release/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pz-cli
3
- Version: 5.0.1
3
+ Version: 5.0.2
4
4
  Summary: PZ CLI, runtime compiler, settings owner, and foundation runtime
5
5
  Project-URL: Homepage, https://github.com/JiXiangTools/pz
6
6
  Project-URL: Repository, https://github.com/JiXiangTools/pz
@@ -2,8 +2,11 @@
2
2
 
3
3
  ## Status
4
4
 
5
- This document defines the implemented contract for version-aware package
6
- installation in `pz app`.
5
+ This document defines the original implemented contract for version-aware
6
+ package installation in `pz app`. Source selection, Git package-tag installs,
7
+ and the replacement of the index-only model are now owned by the formal
8
+ `pz_core/pz_core/docs/pz规范与使用/09-CLI与Worker入口规范.md`; the exact-version,
9
+ PEP 440, orchestration, and retry contracts below remain applicable.
7
10
 
8
11
  ## Goal
9
12
 
@@ -13,7 +16,8 @@ reproducible exact installed version.
13
16
 
14
17
  The normal workflow must be simple:
15
18
 
16
- - `pz app add <app_id>` installs the latest compatible stable version;
19
+ - `pz app add <app_id>` installs the latest compatible stable version from the
20
+ selected source, defaulting to `internal-pypi`;
17
21
  - `pz app add <app_id> --version <version>` installs one exact version;
18
22
  - `pz app update <app_id>` resolves the latest compatible stable version;
19
23
  - `pz app update <app_id> --version <version>` moves to one exact version;
@@ -26,16 +30,16 @@ PZ retains the explicit atomic-command plus orchestration-command model.
26
30
  Orchestration commands are:
27
31
 
28
32
  - `pz app init`;
29
- - `pz app add <app_id> [--version <version>]`;
30
- - `pz app update <app_id> [--version <version>]`;
33
+ - `pz app add <app_id> [--source <source>] [--version <version>]`;
34
+ - `pz app update <app_id> [--source <source>] [--version <version>]`;
31
35
  - `pz app rm <app_id>`.
32
36
 
33
37
  Public atomic commands are:
34
38
 
35
39
  - `pz app versions <app_id>`;
36
- - `pz app declare <app_id> --version <version>`;
40
+ - `pz app declare <app_id> --version <version> [--source <source>]`;
37
41
  - `pz app undeclare <app_id>`;
38
- - `pz app install <app_id> --version <version>`.
42
+ - `pz app install <app_id> --version <version> [--source <source>]`.
39
43
 
40
44
  The orchestrators also reuse atomic `pz settings update` and environment sync
41
45
  capabilities. Each command belongs to exactly one layer. Normal human workflows
@@ -63,7 +67,10 @@ minimal apps.
63
67
  ## Version Resolution
64
68
 
65
69
  Without `--version`, `app add`, `app update`, and `app init` resolve the latest
66
- compatible stable version from the configured formal package index.
70
+ compatible stable version from the configured `AppSourceCatalog` source.
71
+ PyPI sources enumerate releases through the Simple API. Git sources enumerate
72
+ formal `<distribution>@<version>` package tags and resolve the selected tag to
73
+ one full commit and exact leaf subdirectory.
67
74
 
68
75
  The resolver must:
69
76
 
@@ -86,9 +93,9 @@ package dependency metadata, not an ambiguous project installation request.
86
93
 
87
94
  ## `pz app versions`
88
95
 
89
- `pz app versions <app_id>` is read-only and performs no project, environment,
90
- or index mutation. It resolves the formal distribution and configured package
91
- index, then reports:
96
+ `pz app versions <app_id> [--source <source_id>]` is read-only and performs no
97
+ project, environment, Git remote, or index mutation. It resolves the formal
98
+ distribution and selected catalog source, then reports:
92
99
 
93
100
  - `app_id` and distribution name;
94
101
  - all available versions in descending PEP 440 order;
@@ -106,10 +113,19 @@ redacted.
106
113
 
107
114
  ### `pz app declare`
108
115
 
109
- `pz app declare <app_id> --version <version>` atomically writes the exact
110
- distribution pin and app identity/load-order declaration. It does not install
111
- the package or refresh app settings. Repeating an exact matching declaration is
112
- idempotent; conflicting local source ownership is a hard error.
116
+ `pz app declare <app_id> --version <version> [--source <source>]` atomically
117
+ writes the exact distribution plan and app identity/load-order declaration.
118
+ Before install, a PyPI declaration contains the root identity. With a Git
119
+ source, the command first compiles the complete formal app closure from the root
120
+ package tag's full commit, then writes every member's exact version, the same
121
+ credential-free Git URL/full commit, and its own leaf subdirectory in one
122
+ project transaction; no member may fall back to an index. After `app install`,
123
+ repeating the
124
+ same atomic declaration inspects installed metadata, validates the complete
125
+ formal app dependency closure against hard distribution dependencies and lock
126
+ versions, and reconciles the closure into `installed_apps` in dependency-first
127
+ order. It does not install packages or refresh app settings. Existing explicit
128
+ dev source ownership is preserved and remains higher priority.
113
129
 
114
130
  ### `pz app undeclare`
115
131
 
@@ -119,11 +135,18 @@ or remote package artifacts.
119
135
 
120
136
  ### `pz app install`
121
137
 
122
- `pz app install <app_id> --version <version>` installs exactly one already
123
- resolved distribution version into the project environment and converges the
124
- corresponding `uv.lock` state. It does not choose latest, mutate
125
- `installed_apps`, or modify source directories. The locked and installed
126
- metadata must match the requested distribution and version before success.
138
+ `pz app install <app_id> --version <version> [--source <source>]` installs the resolved root
139
+ distribution and its compatible distribution dependency graph into the project
140
+ environment and converges `uv.lock`. Missing formal app dependencies use the
141
+ root app's same install source. A PyPI install does not inherit `UV_INDEX`, uses
142
+ `first-index`, and cannot silently redirect a closure member to another private
143
+ index. A PyPI resolution persists an exact version. A Git resolution consumes
144
+ the exact same-commit closure entries already persisted by `app declare`; the
145
+ explicit source also makes failure recovery reuse the same source. It does not
146
+ choose latest or modify source directories. The
147
+ second atomic `app declare` projects the installed graph into `installed_apps`.
148
+ Locked and installed metadata must match the root request and every formal
149
+ dependency before success.
127
150
 
128
151
  ## Orchestration
129
152
 
@@ -133,16 +156,18 @@ metadata must match the requested distribution and version before success.
133
156
 
134
157
  ```text
135
158
  resolve latest stable or validate --version
136
- -> app declare exact version
137
- -> app install exact version
159
+ -> app declare exact same-source plan
160
+ -> app install exact same-source plan
161
+ -> app declare installed dependency closure
138
162
  -> settings update
139
163
  ```
140
164
 
141
- Each successful atomic stage remains committed. If installation fails after
142
- declaration, the exact declaration remains and retry resumes from install. If
143
- settings refresh fails after declaration and installation succeed, retry
144
- resumes from settings refresh. The orchestration always reports completed
145
- stages, the selected exact version, and the first incomplete stage.
165
+ Each successful atomic stage remains committed. If installation fails after the
166
+ root declaration, that exact declaration remains and retry resumes from install.
167
+ If closure declaration fails after installation, retry repeats `app declare`;
168
+ if settings refresh fails, retry resumes from settings. The orchestration always
169
+ reports completed stages, the selected exact version, and the first incomplete
170
+ stage.
146
171
 
147
172
  ### `pz app update`
148
173
 
@@ -155,8 +180,9 @@ reinstalling.
155
180
 
156
181
  `pz app init` resolves every selected package first, forms one dependency-safe
157
182
  exact plan, then declares and installs in dependency order. A resolver conflict
158
- fails before project mutation. It never uses versions found in source checkout
159
- `pyproject.toml` files as production pins.
183
+ fails before project mutation. It never uses a branch, `HEAD`, floating tag, or
184
+ the current version of an arbitrary source checkout as a production pin. A Git
185
+ source is valid only through a formal package tag resolved to a full commit.
160
186
 
161
187
  ### `pz app rm`
162
188
 
@@ -180,7 +206,8 @@ refresh. It does not remove local source or delete remote package versions.
180
206
  Publishing and installation remain separate chains. The leaf
181
207
  `[project].version`, package tag, wheel metadata, and package-index version must
182
208
  match under the Git release orchestration design. `pz app` consumes those
183
- published versions and never commits, tags, or publishes source.
209
+ published versions from PyPI or a formal Git package tag and never commits,
210
+ tags, or publishes source.
184
211
 
185
212
  ## Testing
186
213
 
@@ -194,12 +221,15 @@ Tests must cover:
194
221
  4. `app versions` reports available, latest, declared, locked, and installed
195
222
  versions consistently in human and JSON output without mutation;
196
223
  5. install validates installed distribution metadata;
197
- 6. add/update/init preserve dependency order and fail before mutation on
198
- resolution conflict;
224
+ 6. add/update/init install the formal dependency closure from the same source,
225
+ preserve dependency order, and fail deterministically on resolution conflict;
199
226
  7. staged declaration rollback and forward recovery after later-stage failure;
200
227
  8. source/distribution identity conflicts remain hard errors;
201
228
  9. repository-root version never overrides a leaf package version;
202
- 10. credentials and authenticated index URLs are redacted.
229
+ 10. credentials and authenticated index URLs are redacted;
230
+ 11. inherited `UV_INDEX` cannot redirect a private formal dependency, while an
231
+ explicit existing dev source remains higher priority and is never deleted
232
+ or rewritten by `pz app`.
203
233
 
204
234
  ## Non-Goals
205
235
 
@@ -207,4 +237,6 @@ Tests must cover:
207
237
  - Giving every app in one repository the same release version.
208
238
  - Persisting floating `latest` dependencies.
209
239
  - Automatically selecting or bumping a package's publish version.
210
- - Installing directly from source checkout in the `pz app` command family.
240
+ - Installing from a mutable branch, `HEAD`, floating tag, dirty checkout, or
241
+ unversioned local source in the `pz app` command family. Exact Git package-tag
242
+ installs are formal inputs under the unified source catalog design.
@@ -140,7 +140,7 @@ The wheel exposes both existing entry-point contracts:
140
140
  pz = "pz_core.pz_launcher:main"
141
141
 
142
142
  [project.entry-points."pz.root_cli"]
143
- pz_foundation = "pz_foundation.root_cli:get_root_command_handlers"
143
+ workers = "pz_foundation.root_cli:get_root_command_handlers"
144
144
  ```
145
145
 
146
146
  ## Dependency Metadata
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pz-cli"
7
- version = "5.0.1"
7
+ version = "5.0.2"
8
8
  description = "PZ CLI, runtime compiler, settings owner, and foundation runtime"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -45,7 +45,7 @@ db-mysql = ["pymysql>=1.1,<2.0"]
45
45
  pz = "pz_core.pz_launcher:main"
46
46
 
47
47
  [project.entry-points."pz.root_cli"]
48
- pz_foundation = "pz_foundation.root_cli:get_root_command_handlers"
48
+ workers = "pz_foundation.root_cli:get_root_command_handlers"
49
49
 
50
50
  [dependency-groups]
51
51
  dev = [
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from dataclasses import dataclass
3
+ from dataclasses import dataclass, field
4
4
  from pathlib import Path
5
5
  from typing import Any, Protocol, runtime_checkable
6
6
 
@@ -10,6 +10,7 @@ class PresignInfo:
10
10
  method: str
11
11
  url: str
12
12
  expires_in_seconds: int
13
+ headers: dict[str, str] = field(default_factory=dict)
13
14
 
14
15
 
15
16
  @dataclass(frozen=True, slots=True)
@@ -23,6 +24,10 @@ class StoredObject:
23
24
  class StoragePort(Protocol):
24
25
  def store_bytes(self, object_key: str, payload: bytes, *, content_type: str | None = None) -> StoredObject: ...
25
26
 
27
+ def stat(self, object_key: str) -> StoredObject: ...
28
+
29
+ def read_range(self, object_key: str, *, offset: int = 0, length: int) -> bytes: ...
30
+
26
31
  def delete(self, object_key: str) -> None: ...
27
32
 
28
33
  def presign_get(self, object_key: str, *, expires_in_seconds: int) -> PresignInfo: ...
@@ -9,7 +9,6 @@ from pathlib import Path
9
9
 
10
10
  from pz_core.core.extensions import CliToolSpec
11
11
  from pz_core.cli_options import add_cli_option
12
- from pz_core.runtime import compile_runtime_plan
13
12
  from pz_core.runtime.cli._args import (
14
13
  PzArgumentParser,
15
14
  json_output_requested,
@@ -26,7 +25,6 @@ from pz_foundation.managed_workers import (
26
25
  stop_managed_workers,
27
26
  )
28
27
 
29
-
30
28
  def _coerce_bool(value: object, default: bool) -> bool:
31
29
  if isinstance(value, bool):
32
30
  return value
@@ -538,9 +536,14 @@ def main(argv: list[str] | None = None, *, project_dir: str | None = None, plan=
538
536
  ns = parser.parse_args(normalized)
539
537
  command = ns.command or "list"
540
538
  json_output = bool(getattr(ns, "json_output", False))
541
- resolved_plan = plan or compile_runtime_plan(
542
- project_dir=project_dir or ns.project_dir
543
- )
539
+ resolved_plan = plan
540
+ if resolved_plan is None:
541
+ from pz_core.runtime import compile_runtime_plan
542
+
543
+ resolved_plan = compile_runtime_plan(
544
+ project_dir=project_dir or ns.project_dir,
545
+ include_cli_manifest=False,
546
+ )
544
547
  include_non_autostart = bool(
545
548
  getattr(ns, "include_non_autostart", False)
546
549
  )
@@ -641,4 +644,5 @@ tool = CliToolSpec(
641
644
  command=("workers",),
642
645
  summary="Manage project-attached worker runtimes.",
643
646
  tool=ManagedWorkersCliTool(),
647
+ requires_runtime_activation=False,
644
648
  )
@@ -156,7 +156,7 @@
156
156
  // shared_invalidation_versions 开启后,内容 tag 版本会进入 cache key,适配 8-20 worker 场景下的自动失效。
157
157
  "site_ui.public_html_response": {
158
158
  "enabled": true,
159
- "ttl_seconds": 60,
159
+ "ttl_seconds": 7200,
160
160
  "max_entries": 512,
161
161
  "shared_invalidation_versions": true
162
162
  },
@@ -230,6 +230,15 @@
230
230
  "failure_window_seconds": 60.0,
231
231
  "base_backoff_seconds": 5.0,
232
232
  "max_backoff_seconds": 300.0
233
+ },
234
+ "logs": {
235
+ // 单个 managed worker 活跃日志达到 50 MiB 或跨 UTC 日期时轮转。
236
+ "max_bytes": 52428800,
237
+ "backup_count": 7,
238
+ "rotate_daily": true,
239
+ "compress": true,
240
+ // 同一完整 traceback 在窗口内仅保留首次全文,其余写入抑制摘要。
241
+ "duplicate_traceback_window_seconds": 300.0
233
242
  }
234
243
  },
235
244
  "mail": {
@@ -292,10 +301,26 @@
292
301
  "access_key_id": "",
293
302
  "secret_access_key": "",
294
303
  "force_path_style": false,
295
- "public_base_url": ""
304
+ "public_base_url": "",
305
+ "private_bucket": "",
306
+ "private_key_patterns": []
296
307
  },
297
308
  "resources": {
298
309
  // 通用资源编译配置。图片响应式派生属于 foundation resource,而不是某个站点子包。
310
+ "delivery": {
311
+ // 可选静态 CDN 根地址,必须与 project.base_url 同源;空值表示继续使用当前站点相对 /static。
312
+ // 跨源静态域名还需要独立 CSP/CORS/字体合同,当前正式 resolver 会拒绝跨源值。
313
+ "cdn_base_url": "",
314
+ // develop/test 保持同源,避免本地调试被远端旧资源污染;product 仅在 cdn_base_url 非空时切换。
315
+ "cdn_enabled_by_pz_env": {
316
+ "dev": false,
317
+ "develop": false,
318
+ "development": false,
319
+ "local": false,
320
+ "test": false,
321
+ "product": true
322
+ }
323
+ },
299
324
  "images": {
300
325
  "enabled": true,
301
326
  // 默认让 `pz resources images` 等价启用 --force,绕过资源构建缓存并覆盖同名派生,避免站点图片变更后继续命中旧产物。
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- import importlib
5
4
  import traceback
6
5
  from dataclasses import dataclass
7
6
  from types import SimpleNamespace
@@ -357,10 +356,6 @@ class _TortoiseManager:
357
356
  continue
358
357
  engine = payload.get("engine")
359
358
  if isinstance(engine, str) and engine.strip():
360
- try:
361
- importlib.import_module(engine.strip())
362
- except Exception:
363
- return False
364
359
  continue
365
360
  return False
366
361
  return True
@@ -98,7 +98,10 @@ foundation 当前提供两层 API:
98
98
  - `<pkg>.urls` 只允许导出 `urlpatterns`
99
99
  - `urlpatterns` 必须是 `path(...)`、`include(...)`、`mount(...)` 或 `DeclaredUrlSpec(...)` 的声明序列
100
100
  - `<pkg>.urls` 使用 `path(...)` 时必须声明 `app_name`
101
- - `path(...)` 必须直接传入函数对象;不再支持字符串 handler 名
101
+ - `path(...)` 的 handler 必须写成绝对 `module:callable` 导入引用;`urls.py` 不直接导入普通 handler
102
+ - `mount(...)` 的 app factory 同样写成绝对 `module:callable` 导入引用;RuntimePlan 编译期不为 mount 导入 factory 模块
103
+ - RuntimePlan 编译只读取路径、方法、名称等轻量声明,不导入普通 handler,也不构建对应 FastAPI router
104
+ - Web 激活会在应用 ready 前一次性解析全部 handler 引用并构建 router;解析失败直接阻止启动,请求期不做首次导入
102
105
  - `path(...)` 的路径字符串使用 FastAPI / Starlette 原生 path 参数语法;既支持 `/{lang}/{module}/{slug}`,也支持 `/{lang:locale}/{slug}` 这类 convertor 形式
103
106
  - `path(...)` 声明的路径字符串会原样进入 FastAPI 路由表;foundation 不会在运行时再次重写业务声明层的 path 参数语法
104
107
  - `path(..., enabled_when="runtime_flag")` 表示这条路径只会在 `runtime.runtime_flag` 为真时注册
@@ -116,6 +119,7 @@ foundation 当前提供两层 API:
116
119
  - `include(...)` 负责子模块 include;上层 prefix 会与子模块 prefix 叠加;上层 namespace 会作为子模块 namespace 前缀继续下沉
117
120
  - `mount(...)` / `include(...)` 遵循 Django 风格父子 URLconf 语义:父级消费公共 prefix,子 app / 子 router 只声明相对路径,不得重复声明 mount prefix;例如挂载到 `/api/v1/payments` 时,子路由写 `/create-checkout-session`,不能写 `/api/v1/payments/create-checkout-session`
118
121
  - foundation 会先编译 `route_manifest`,再进入 FastAPI 挂载;同一路径/方法冲突必须在真实挂载前失败
122
+ - route manifest 的 namespace、prefix 与路径/方法冲突校验直接使用已编译结构,不创建占位 FastAPI router
119
123
  - `host.route` / `admin.panel` 这类 host 扩展路由也会先转成 `DeclaredUrlSpec`,再进入同一条 registry 编译链
120
124
  - host 挂载后会把 mounted route namespace 记录到 `app.state.pz_route_registry`
121
125
  - host 也会保留已编译的 `app.state.pz_route_manifest`
@@ -127,13 +131,10 @@ from __future__ import annotations
127
131
 
128
132
  from pz_foundation.routing import include, path
129
133
 
130
- from .views import demo_page
131
-
132
-
133
134
  app_name = "pz_demo"
134
135
 
135
136
  urlpatterns = (
136
- path("/demo", demo_page, name="pz_demo:demo-page"),
137
+ path("/demo", "pz_demo.views:demo_page", name="pz_demo:demo-page"),
137
138
  include("pz_demo.api", path_prefix="/api/v1", namespace="pz_demo.api"),
138
139
  )
139
140
  ```
@@ -248,6 +249,8 @@ managed worker 补充约定:
248
249
  - `pz workers stop [name ...]`
249
250
  - `pz workers restart [name ...]`
250
251
  - `pz workers run [name ...]`
252
+
253
+ managed worker 的 stdout/stderr 由 detached supervisor 统一承接。`managed_workers.logs` 是日志生命周期的唯一正式配置:活跃日志按 `max_bytes` 或 UTC 日期轮转,历史日志按 `compress` 压缩并最多保留 `backup_count` 份;同一完整 traceback 在 `duplicate_traceback_window_seconds` 内只保留首次全文和抑制摘要,避免故障期间无限重复堆栈。
251
254
  - `workers restart --start-timeout <seconds>` 控制启动后等待状态刷新的时间,超时后继续用 `workers status` 读取最终状态。
252
255
  - `pz pz_foundation workers ...` 是同一实现的 app CLI 入口;root 入口与 app 入口不得分叉。
253
256
 
@@ -22,6 +22,20 @@
22
22
  - `pz_foundation/public.py`
23
23
  - `pz_foundation/settings.py`
24
24
  - `pz_foundation/configs/default.jsonc`
25
+
26
+ ## Storage 对象事实合同
27
+
28
+ `pz_foundation` 的 local 与 S3-compatible provider(包含通过 `endpoint_url` 接入的 R2)统一实现正式 `StorageFacade` 合同:
29
+
30
+ - `stat(key)` 读取当前对象大小与 provider 已记录的 content type;S3-compatible backend 必须使用 `head_object`,不得用下载对象模拟 HEAD。
31
+ - `read_range(key, offset=0, length=...)` 只读取指定范围;S3-compatible backend 必须发送服务端 `Range`,local backend 必须 seek 后有界读取,返回值不得超过 `length`。
32
+ - S3-compatible client 必须固定使用 SigV4。PUT presign 的 `content_type` 与 `content_length` 必须进入签名参数;返回给调用方的显式 header 包含同一 `Content-Type`,浏览器生成的 `Content-Length` 必须与签名值一致。
33
+ - PUT presign 的 `write_once` 默认值固定为 `false`,避免改变需要覆盖同一 key 的正式输出上传。业务显式选择 `true` 时,S3-compatible provider 必须签入 `IfNoneMatch="*"` 并返回 `If-None-Match: *`;对象已存在时 provider 的 precondition failure 必须原样暴露,不能回退为覆盖写。local backend 接受该参数以保持合同一致,但仍不支持 PUT presign。
34
+ - `private_bucket` 必须是与公共 `bucket` 不同、未绑定公共域名的物理 bucket;`private_key_patterns` 匹配的 key 在所有读写/签名方法中都路由到该 bucket,且 `url()` 固定返回 `None`。缺失或同 bucket 配置属于安全错误,不能静默使用公共 bucket。
35
+ - `write_once` 不覆盖“删除后重建”场景:上传授权仍有效时,业务必须保留 rejected/cancelled 对象及 tombstone,使 `If-None-Match: *` 持续拒绝第二次 PUT;只有 capability 失效并留出时钟偏差窗口后才能删除。
36
+ - `open()` 是流式 handle 合同,不等于全量载入;需要文件头的调用方应优先使用 `read_range()`,不得通过无界 `read()` 实现探测。
37
+
38
+ Foundation 不判断对象是否为真实图片,也不保存业务 upload intent。业务 owner 应把 `stat()` 的对象大小/元数据、`read_range()` 的 magic bytes 与自身一次性 intent 交叉校验,并在 provider 不可用或事实不一致时 fail closed。
25
39
  - `pz_foundation/host/*`
26
40
 
27
41
  ## Redis / Cache 设计原则
@@ -53,7 +67,7 @@
53
67
 
54
68
  同时,foundation 的 async cache facade 不负责把 redis 故障偷偷吞成 `0 / None / False`。请求期是否记录 error、继续使用当前状态、回退 DB 还是返回 `503`,由上层子包显式决定。
55
69
 
56
- `cache_service.read_snapshot()` 是请求期需要一次读取多个 cache 事实时的正式快照入口。它只负责把多个 Redis string key 合并为一次读取,并按调用方声明的 `json_keys` / `version_names` 返回当前快照;它不改变 miss 语义、不引入跨请求放行缓存,也不会在 backend 故障时替上层吞错。
70
+ `cache_service.read_snapshot()` 是请求期需要一次读取多个 cache 事实时的正式快照入口,稳定公开面为 `CacheFacade.read_snapshot(json_keys=(), version_names=())`。它只负责把多个 Redis string key 合并为一次读取,并按调用方声明的 `json_keys` / `version_names` 返回当前快照;它不改变 miss 语义、不引入跨请求放行缓存,也不会在 backend 故障时替上层吞错。上层子包不得越过 facade 重新拼 Redis version key 或用循环 `get_version()` 代替一次快照读取。
57
71
 
58
72
  测试态 `RedisManager.for_testing()` 必须模拟“每个 manager 一个 Redis server”的语义:同一 manager 创建出的不同连接、不同事件循环连接、不同线程连接共享同一个 in-memory backend;`reset_connection` / `reset_all_redis_connections` 只重置连接对象,不 flush backend 数据;不同 manager 之间仍保持隔离。该 testing backend 必须覆盖 Redis key/value、集合、zset、stream、eval 以及 Pub/Sub 等已被正式 runtime 消费的能力,避免上层子包在测试中看到与真实 Redis 不一致的生命周期或跨进程语义。
59
73
 
@@ -122,6 +136,8 @@ Foundation capability 与基础设施探测结果只绑定到当前进程的 run
122
136
 
123
137
  Foundation infra 必须挂到正式 `RuntimePlan` lifecycle:Web、CLI、worker 与 Python API 在执行阶段都应先进入 runtime activate,再消费已绑定的 `SettingsSnapshot` / `settings_center.settings.pz_foundation` 初始化 DB、cache、settings operator 等基础设施。HTTP lifespan 只承担 ASGI 进程内的长驻后台探活与关闭协作,不再是 DB 初始化的唯一入口;CLI / programmatic runtime 不得为了 DB 连接重新读取 `.env`、`pz*.jsonc` 或包内默认模板。
124
138
 
139
+ Host builder、路由物化和 HTTP lifecycle 必须绑定 `RuntimePlan.settings` 中同一个 `SettingsSnapshot`。启动期导入的 handler/provider 只能消费该快照,不得再次编译 settings;请求期继续复用同一快照,避免把配置编译带入在线热路径。
140
+
125
141
  程序化入口在已有 event loop 内运行时必须使用 `await runtime.activate_async()` / `await runtime.shutdown_async()`,保证 async lifecycle 与 DB 连接池绑定在调用方当前 loop 上;同步 `runtime.activate()` 只适用于没有正在运行 event loop 的调用栈。
126
142
 
127
143
  因此:
@@ -162,6 +178,10 @@ Foundation infra 必须挂到正式 `RuntimePlan` lifecycle:Web、CLI、worker
162
178
 
163
179
  `pz_foundation` 是 managed worker 运维命令的正式 owner。命令实现集中在 `pz_foundation.cli.workers`,底层进程发现、状态、停止与 supervisor 启动语义集中在 `pz_foundation.managed_workers`;其它包不应再维护第二套 worker 管理 CLI。
164
180
 
181
+ 根命令通过名称为 `workers` 的 `pz.root_cli` entry point 注册。根 dispatcher 只在 argv 第一段为 `workers` 时加载该 provider;`workers` 仍消费同一份正式 `RuntimePlan`,不得另建 WorkerPlan 或第二套 app 发现链。
182
+
183
+ 独立执行 `pz workers ...` 时可通过 `compile_runtime_plan(include_cli_manifest=False)` 跳过该命令不会消费的 app CLI 静态索引;这只是同一 RuntimePlan 编译器的正式裁剪参数,不改变 settings、app、extension、worker role 或其它运行时真相源。宿主已经提供 plan 时必须直接复用,不得重复编译。
184
+
165
185
  正式命令面如下:
166
186
 
167
187
  - `pz workers list [name ...]`:列出当前 `RuntimePlan` 中声明的 worker role 与副本状态。
@@ -204,6 +224,8 @@ CLI 与 JSON 状态必须透出 `worker_kind`,用于上层审计“基础设
204
224
  - 同一 manifest 的资源构建不允许嵌套重入;foundation 负责快速失败并暴露明确错误,而不是让进程在资源锁上自锁。
205
225
  - 跨线程与跨进程仍必须由 foundation 资源构建锁串行化,业务包、site UI、crawler 或站点运行时不应各自绕开或复制资源锁语义。
206
226
 
227
+ 静态资源投递配置的唯一真相源是 `settings_center.settings.pz_foundation.resources.delivery`:`cdn_base_url` 只接受与 `project.base_url` 同源的 HTTPS 根地址,`cdn_enabled_by_pz_env` 决定各环境是否使用它。develop/test 默认使用相对同源 URL,product 在配置有效同源 CDN 根地址后才输出绝对 URL;URL 拼接与版本参数由消费方通过公开 resolver 完成,不允许模板另读环境变量。跨源 CDN 需要额外 CSP、CORS 与字体加载合同,在这些合同形成前 resolver 必须拒绝跨源配置,不能暴露半套能力。
228
+
207
229
  ## 缓存控制策略真相源
208
230
 
209
231
  `settings_center.settings.pz_foundation.cache_control` 是全系统缓存控制策略参数的唯一通用真相源。
@@ -220,10 +242,13 @@ CLI 与 JSON 状态必须透出 `worker_kind`,用于上层审计“基础设
220
242
  正式边界:
221
243
 
222
244
  - `pz_foundation` 只拥有通用缓存控制参数:`enabled`、`ttl_seconds`、`max_entries`、`shared_invalidation_versions`。
223
- - 匿名公开 HTML 的 Cloudflare/CDN 缓存头由 `http.public_html_cdn` 唯一控制;`CacheControlMiddleware` 输出浏览器侧 `Cache-Control: public, max-age=0, must-revalidate`,并在 policy 开启时输出 `Cloudflare-CDN-Cache-Control: public, max-age=<ttl_seconds>`。
245
+ - 公开 HTML 的 Cloudflare/CDN 缓存 TTL 由 `http.public_html_cdn` 唯一控制;但 policy 开启不等于任意 HTML 自动公开缓存。只有真正命中或成功写入公开 HTML 响应缓存的 owner,才能通过 `mark_public_html_edge_cache_eligible(response)` 显式 opt-in。
246
+ - `CacheControlMiddleware` 是 HTML edge cache 的最终 fail-closed 安全门:只接受 `GET` / `HEAD` 的 2xx 响应,且请求不得带 `Authorization`,响应不得带 `Set-Cookie`、`Cache-Control: private/no-store` 或 `Vary: Cookie/Authorization`。普通 opt-in 请求仍不得带任何 `Cookie`;只有请求状态与内部 marker 同时声明 `request_cookie_independent` 的公开静态壳才允许携带 Cookie。全部条件成立时才输出浏览器侧 `Cache-Control: public, max-age=0, must-revalidate` 与 `Cloudflare-CDN-Cache-Control: public, max-age=<ttl_seconds>`;其余 HTML 统一 `no-store`。
247
+ - opt-in 使用内部响应 header 传递,缓存资格不成立或存储失败时,响应 owner 通过 `clear_public_html_edge_cache_eligible(response)` 撤销标记。`CacheControlMiddleware` 在所有 HTTP 状态码和方法上都必须在最终响应中删除它,该 header 不属于外部协议。
224
248
  - JS/CSS、图片、字体、XML/JSON 等文件类型分类只从 `cache_control.http.file_extensions` 读取;对应 TTL 仍只从 `http.static.*` policies 读取。
225
- - 当 `http.public_html_cdn` 或全局 `runtime_enabled` 关闭时,公开 HTML 的 Cloudflare 头必须明确为 `Cloudflare-CDN-Cache-Control: no-store`,不能依赖 Cloudflare 面板或业务页面自己补规则。
226
- - 用户态 HTML 不属于匿名 CDN 缓存策略;`pz_site_essentials.HtmlCacheGuardMiddleware` 负责按用户态识别结果强制 `Cloudflare-CDN-Cache-Control: no-store` 与 `Vary: Cookie, Authorization`。
249
+ - 带版本参数的静态资源同时输出浏览器与 Cloudflare 的一年 `public, max-age=31536000, immutable`(具体秒数仍取 policy),让重复访问直接复用 memory/disk cache,强制网络校验则由 CDN edge 响应;未版本化资源也同步输出对应 CDN TTL,但不得标记 immutable。
250
+ - 当 `http.public_html_cdn` 或全局 `runtime_enabled` 关闭时,公开 HTML 的 Cloudflare 头必须明确为 `Cloudflare-CDN-Cache-Control: no-store`,不能依赖 Cloudflare 面板或业务页面自己补规则。未显式 opt-in 的 HTML 在 policy 开启时也同样 `no-store`。
251
+ - 用户态 HTML 不属于公开静态壳策略;只有正文不包含用户、余额、订阅或 Cookie 派生事实,且这些能力由客户端动态岛恢复的页面才可声明静态壳。其它用户态 owner 仍负责输出正确的 `Vary` 与业务语义,Foundation 安全门另外以请求/响应头独立复核并在任一条件不成立时强制 `no-store`。
227
252
  - `pz_foundation` 不拥有 CMS/Blog/业务内容的事实真相,不定义业务 tag 语义,也不决定某篇文章更新后应失效哪些业务集合。
228
253
  - 业务 owner 在自身正式写链路中声明业务 tag 和失效事实;读取链路只按 policy id 消费 TTL、容量和共享版本开关。
229
254
  - `pz_site_ui` 的公开 HTML 响应缓存、模板上下文缓存,CMS 的读模型/推荐/站点地图缓存,均应消费该 policy registry;不得在业务子包里重复放置同类 TTL/容量/共享版本配置。
@@ -252,6 +277,16 @@ CLI 与 JSON 状态必须透出 `worker_kind`,用于上层审计“基础设
252
277
 
253
278
  foundation 的日志与 bot 通道配置必须走正式 app settings。
254
279
 
280
+ ### HTTP Request ID 与日志关联
281
+
282
+ `pz_foundation` 是宿主 HTTP request correlation 与日志上下文的唯一 owner,正式规则如下:
283
+
284
+ - 唯一 header 名为 `x-request-id`,最终值遵守 `pz_core.runtime.request_id` 的 16 位小写十六进制合同。
285
+ - `RequestLoggingMiddleware` 必须作为 foundation 最外层通用中间件之一运行;合法入站值规范化后保留,缺失或非法值自动生成,并写入 ASGI `scope.state.request_id`、ContextVar 和响应 header。
286
+ - logger formatter 固定输出 `request_id=<value>`。请求上下文外使用 `request_id=-`;请求内所有 `pz.*` 业务日志和访问日志使用同一个最终 ID。
287
+ - `request_logging.exclude_paths` 只排除 header 明细,不能形成 correlation 日志盲区;只要 request logging 启用,每个 HTTP 请求仍写一条包含 ID、method、path、status、duration 的访问日志。
288
+ - 业务包发起下游 HTTP 时只消费 `pz_foundation.public.with_request_id_headers`、`outbound_http_request_id` 或接入它们的正式 transport,不复制生成与校验逻辑。
289
+
255
290
  正式默认值真相源:
256
291
 
257
292
  - `pz_foundation/configs/default.jsonc`
@@ -6,6 +6,7 @@
6
6
 
7
7
  - 路由声明真相仍在各 app 的 `<pkg>.urls` / `routes.py`;业务包只声明自己拥有的 canonical route。
8
8
  - 路由装配、排序、冲突检测、route manifest 与 host 级 redirect 归 `pz_foundation.routing` 统一处理。
9
+ - 普通 `path(...)` handler 使用绝对 `module:callable` 引用,并统一由基础包 `ImportRef` 值对象校验和解析。RuntimePlan 只编译轻量路由结构并保留正式 `DeclaredUrlSpec`;Web 激活直接物化同一声明对象,不重新扫描 URL 模块,在 ready 前统一构建 FastAPI router;请求期不做首次导入。
9
10
  - 公开页面 path 规范化使用 `public_canonical_path(...)`。
10
11
  - 模板、导航、footer、CTA、语言切换等 href 生成使用 `public_canonical_href(...)`,或由 `pz_site_ui` 暴露到模板的 `canonical_public_href(...)`。
11
12
  - 子包不要手写 `/{lang}/...`、`/en/...`、尾斜杠补齐、默认语言去前缀、语言 alias casing 处理。
@@ -0,0 +1,46 @@
1
+ """Internal response contract for public HTML edge caching."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TypeVar
6
+
7
+ from starlette.responses import Response
8
+
9
+
10
+ PUBLIC_HTML_EDGE_CACHE_OPT_IN_HEADER = "x-pz-public-html-edge-cache"
11
+ PUBLIC_HTML_STATIC_SHELL_SCOPE_STATE = "pz_public_html_static_shell"
12
+ _PUBLIC_HTML_EDGE_CACHE_OPT_IN_VALUE = "1"
13
+ _PUBLIC_HTML_EDGE_CACHE_STATIC_SHELL_VALUE = "static-shell-v1"
14
+ _ResponseT = TypeVar("_ResponseT", bound=Response)
15
+
16
+
17
+ def mark_public_html_edge_cache_eligible(
18
+ response: _ResponseT,
19
+ *,
20
+ request_cookie_independent: bool = False,
21
+ ) -> _ResponseT:
22
+ """Opt a response into the middleware's fail-closed public HTML checks."""
23
+
24
+ marker = (
25
+ _PUBLIC_HTML_EDGE_CACHE_STATIC_SHELL_VALUE
26
+ if request_cookie_independent
27
+ else _PUBLIC_HTML_EDGE_CACHE_OPT_IN_VALUE
28
+ )
29
+ response.headers[PUBLIC_HTML_EDGE_CACHE_OPT_IN_HEADER] = marker
30
+ return response
31
+
32
+
33
+ def clear_public_html_edge_cache_eligible(response: _ResponseT) -> _ResponseT:
34
+ """Remove a stale or untrusted opt-in marker before returning a response."""
35
+
36
+ if PUBLIC_HTML_EDGE_CACHE_OPT_IN_HEADER in response.headers:
37
+ del response.headers[PUBLIC_HTML_EDGE_CACHE_OPT_IN_HEADER]
38
+ return response
39
+
40
+
41
+ __all__ = [
42
+ "PUBLIC_HTML_EDGE_CACHE_OPT_IN_HEADER",
43
+ "PUBLIC_HTML_STATIC_SHELL_SCOPE_STATE",
44
+ "clear_public_html_edge_cache_eligible",
45
+ "mark_public_html_edge_cache_eligible",
46
+ ]