forge-autonomy 2.7.28__tar.gz → 2.7.30__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 (319) hide show
  1. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/PKG-INFO +1 -1
  2. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planner/codex_cli_session.py +10 -4
  3. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planner/openai_responses.py +14 -3
  4. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge_autonomy.egg-info/PKG-INFO +1 -1
  5. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/product-version.json +1 -1
  6. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_codex_cli_session.py +22 -0
  7. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_installed_forge_update.py +75 -3
  8. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/MANIFEST.in +0 -0
  9. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/README.md +0 -0
  10. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/__init__.py +0 -0
  11. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/__main__.py +0 -0
  12. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/_version.py +0 -0
  13. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/action_derivation_canary_closure.py +0 -0
  14. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/action_derivation_evidence.py +0 -0
  15. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/action_derivation_qualification.py +0 -0
  16. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/action_derivation_reattempt.py +0 -0
  17. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/ai_architect/__init__.py +0 -0
  18. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/ai_architect/provider_registry.py +0 -0
  19. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/api/operations-read-openapi-v1.json +0 -0
  20. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/api/operations-read-postman-v1.json +0 -0
  21. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/architecture/__init__.py +0 -0
  22. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/architecture/advisor.py +0 -0
  23. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/architecture/presentation.py +0 -0
  24. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/architecture/workspace.py +0 -0
  25. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/autonomous_orchestrator.py +0 -0
  26. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/business/__init__.py +0 -0
  27. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/business/advisor.py +0 -0
  28. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/business/ingress.py +0 -0
  29. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/business/presentation.py +0 -0
  30. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/business/workspace.py +0 -0
  31. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/canary.py +0 -0
  32. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/capabilities/__init__.py +0 -0
  33. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/capabilities/delegation.py +0 -0
  34. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/completion/__init__.py +0 -0
  35. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/completion/assessor.py +0 -0
  36. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/completion/host_control_observer.py +0 -0
  37. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/completion/mission.py +0 -0
  38. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/completion/repository_observer.py +0 -0
  39. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/constitutional/__init__.py +0 -0
  40. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/constitutional/assessor.py +0 -0
  41. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/core/__init__.py +0 -0
  42. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/core/json_store.py +0 -0
  43. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/decision_evidence/__init__.py +0 -0
  44. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/decision_evidence/repository.py +0 -0
  45. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/dispatcher/__init__.py +0 -0
  46. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/dispatcher/dispatcher.py +0 -0
  47. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/execution/__init__.py +0 -0
  48. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/execution/loop.py +0 -0
  49. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/execution/presentation.py +0 -0
  50. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/execution_host_configuration.py +0 -0
  51. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/foundation/__init__.py +0 -0
  52. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/foundation/loader.py +0 -0
  53. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/generation_two.py +0 -0
  54. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/generation_two_execution.py +0 -0
  55. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/governance/__init__.py +0 -0
  56. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/governance/execution_policy.py +0 -0
  57. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/governance/profiles.py +0 -0
  58. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/governance_authority.py +0 -0
  59. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/intake.py +0 -0
  60. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/integration/__init__.py +0 -0
  61. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/integration/coordinator.py +0 -0
  62. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/integration/repository.py +0 -0
  63. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/knowledge/__init__.py +0 -0
  64. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/knowledge/consumer.py +0 -0
  65. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/knowledge/registry.py +0 -0
  66. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/lifecycle/__init__.py +0 -0
  67. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/lifecycle/store.py +0 -0
  68. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/mission_amendment.py +0 -0
  69. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/mission_cli.py +0 -0
  70. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/mission_scheduler.py +0 -0
  71. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/__init__.py +0 -0
  72. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/action.py +0 -0
  73. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/action_derivation.py +0 -0
  74. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/agent_policy.py +0 -0
  75. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/ai_architect_provider.py +0 -0
  76. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/ai_architect_session.py +0 -0
  77. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/ai_provider_registry.py +0 -0
  78. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/architecture_mission.py +0 -0
  79. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/architecture_reasoning.py +0 -0
  80. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/architecture_review.py +0 -0
  81. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/codex_runtime_prompt.py +0 -0
  82. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/constitutional_validation.py +0 -0
  83. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/criterion_assessment.py +0 -0
  84. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/criterion_observation.py +0 -0
  85. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/decision_evidence.py +0 -0
  86. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/execution_host.py +0 -0
  87. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/foundation.py +0 -0
  88. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/historical_intent.py +0 -0
  89. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/integration.py +0 -0
  90. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/intent.py +0 -0
  91. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/intent_authoring.py +0 -0
  92. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/mission.py +0 -0
  93. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/mission_candidate.py +0 -0
  94. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/mission_completion.py +0 -0
  95. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/mission_planner.py +0 -0
  96. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/mission_recommendation.py +0 -0
  97. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/phase_completion.py +0 -0
  98. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/planning.py +0 -0
  99. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/producer.py +0 -0
  100. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/prompt_artifact.py +0 -0
  101. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/proposal.py +0 -0
  102. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/runtime_prompt.py +0 -0
  103. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/models/solution_template.py +0 -0
  104. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/operations_read_api.py +0 -0
  105. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/operator_identity.py +0 -0
  106. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planner/__init__.py +0 -0
  107. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planner/action_derivation.py +0 -0
  108. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planner/durable_derivation.py +0 -0
  109. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planner/engine.py +0 -0
  110. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planner/provider_adapter.py +0 -0
  111. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planning/__init__.py +0 -0
  112. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planning/loader.py +0 -0
  113. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/planning/registry.py +0 -0
  114. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/portfolio_intelligence.py +0 -0
  115. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/programme_authorization.py +0 -0
  116. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/prompts/__init__.py +0 -0
  117. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/prompts/codex_cli.py +0 -0
  118. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/prompts/generator.py +0 -0
  119. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/proposals/__init__.py +0 -0
  120. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/proposals/generator.py +0 -0
  121. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/provider_security.py +0 -0
  122. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/qualification/__init__.py +0 -0
  123. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/qualification/bootstrap_sequence.py +0 -0
  124. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/qualification/criterion_completion.py +0 -0
  125. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/qualification/generation_one.py +0 -0
  126. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/qualification/installed_smoke.py +0 -0
  127. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/recommendations/__init__.py +0 -0
  128. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/recommendations/engine.py +0 -0
  129. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/repository_truth.py +0 -0
  130. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/review/__init__.py +0 -0
  131. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/review/engine.py +0 -0
  132. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/__init__.py +0 -0
  133. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/bootstrap.py +0 -0
  134. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/data_root.py +0 -0
  135. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/database.py +0 -0
  136. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/dynamic_mission.py +0 -0
  137. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/evidence.py +0 -0
  138. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/execution_context.py +0 -0
  139. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/health.py +0 -0
  140. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/mission_controller.py +0 -0
  141. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/operational_reset.py +0 -0
  142. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/runner.py +0 -0
  143. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/runtime/service.py +0 -0
  144. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/scheduler/__init__.py +0 -0
  145. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/scheduler/adapter.py +0 -0
  146. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/scheduler/ep_http_adapter.py +0 -0
  147. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/scheduler/ep_v12.py +0 -0
  148. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/scheduler/scheduler.py +0 -0
  149. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/capability-registry-1.0.schema.json +0 -0
  150. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/capability.schema.json +0 -0
  151. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/common.schema.json +0 -0
  152. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/decision-evidence-1.0.schema.json +0 -0
  153. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/engineering-goal-0.5.schema.json +0 -0
  154. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/engineering-increment-proposal-0.5.schema.json +0 -0
  155. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/engineering-mode.schema.json +0 -0
  156. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/engineering-plan-0.5.schema.json +0 -0
  157. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/engineering-platform-peer-configuration-1.0.schema.json +0 -0
  158. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/engineering-platform-peer-configuration-1.1.schema.json +0 -0
  159. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/engineering-prompt-artifact-0.7.schema.json +0 -0
  160. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/engineering-proposal-0.6.schema.json +0 -0
  161. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/evidence-reference-0.5.schema.json +0 -0
  162. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/foundation-document.schema.json +0 -0
  163. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/governance-profile.schema.json +0 -0
  164. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/knowledge-source-0.4.schema.json +0 -0
  165. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/knowledge-source.schema.json +0 -0
  166. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/mission-candidate-1.0.schema.json +0 -0
  167. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/mission-candidate-1.1.schema.json +0 -0
  168. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/phase-completion-1.0.schema.json +0 -0
  169. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/planning-document-0.5.schema.json +0 -0
  170. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/repository-catalog.schema.json +0 -0
  171. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/repository.schema.json +0 -0
  172. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/solution-template-1.0.schema.json +0 -0
  173. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/schemas/workspace.schema.json +0 -0
  174. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/secure_store.py +0 -0
  175. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/solutions/__init__.py +0 -0
  176. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/solutions/catalogue.py +0 -0
  177. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/solutions/generator.py +0 -0
  178. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/state/__init__.py +0 -0
  179. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/state/mission_state.py +0 -0
  180. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge/workspace/__init__.py +0 -0
  181. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge_autonomy.egg-info/SOURCES.txt +0 -0
  182. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge_autonomy.egg-info/dependency_links.txt +0 -0
  183. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge_autonomy.egg-info/entry_points.txt +0 -0
  184. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/forge_autonomy.egg-info/top_level.txt +0 -0
  185. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/pyproject.toml +0 -0
  186. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/capability-registry-1.0.schema.json +0 -0
  187. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/capability.schema.json +0 -0
  188. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/common.schema.json +0 -0
  189. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/decision-evidence-1.0.schema.json +0 -0
  190. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/engineering-goal-0.5.schema.json +0 -0
  191. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/engineering-increment-proposal-0.5.schema.json +0 -0
  192. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/engineering-mode.schema.json +0 -0
  193. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/engineering-plan-0.5.schema.json +0 -0
  194. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/engineering-prompt-artifact-0.7.schema.json +0 -0
  195. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/engineering-proposal-0.6.schema.json +0 -0
  196. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/evidence-reference-0.5.schema.json +0 -0
  197. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/foundation-document.schema.json +0 -0
  198. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/governance-profile.schema.json +0 -0
  199. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/knowledge-source-0.4.schema.json +0 -0
  200. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/knowledge-source.schema.json +0 -0
  201. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/mission-candidate-1.0.schema.json +0 -0
  202. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/mission-candidate-1.1.schema.json +0 -0
  203. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/phase-completion-1.0.schema.json +0 -0
  204. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/planning-document-0.5.schema.json +0 -0
  205. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/repository-catalog.schema.json +0 -0
  206. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/repository.schema.json +0 -0
  207. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/solution-template-1.0.schema.json +0 -0
  208. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/schemas/workspace.schema.json +0 -0
  209. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/setup.cfg +0 -0
  210. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_action_derivation.py +0 -0
  211. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_action_derivation_canary_closure.py +0 -0
  212. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_action_derivation_evidence.py +0 -0
  213. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_action_derivation_qualification.py +0 -0
  214. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_adaptive_action_sizing_design.py +0 -0
  215. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_agent_policy.py +0 -0
  216. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_aggregate_health_roadmap.py +0 -0
  217. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_ai_architect_provider.py +0 -0
  218. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_ai_architect_session.py +0 -0
  219. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_ai_development_projection.py +0 -0
  220. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_ai_provider_registry.py +0 -0
  221. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_architecture_reasoning.py +0 -0
  222. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_architecture_review_engine.py +0 -0
  223. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_architecture_workspace.py +0 -0
  224. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_autonomous_orchestrator.py +0 -0
  225. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_bootstrap_adapter.py +0 -0
  226. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_bootstrap_mission_canary.py +0 -0
  227. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_bootstrap_mission_runner.py +0 -0
  228. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_bootstrap_mission_scheduler.py +0 -0
  229. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_bootstrap_sequence_qualification.py +0 -0
  230. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_business_governance_ingress.py +0 -0
  231. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_business_workspace.py +0 -0
  232. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_canonical_data_root.py +0 -0
  233. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_capability_delegation.py +0 -0
  234. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_codex_cli_runtime_prompt.py +0 -0
  235. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_constitutional_validation.py +0 -0
  236. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_criterion_assessment_contract.py +0 -0
  237. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_criterion_ep_http_boundary.py +0 -0
  238. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_criterion_planning_context.py +0 -0
  239. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_decision_evidence.py +0 -0
  240. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_default_project_quality_policy.py +0 -0
  241. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_distribution_identity.py +0 -0
  242. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_durable_action_derivation.py +0 -0
  243. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_dynamic_mission_capability.py +0 -0
  244. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_engineering_action_architecture.py +0 -0
  245. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_engineering_intent_authoring.py +0 -0
  246. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_engineering_intent_lifecycle.py +0 -0
  247. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_engineering_mission.py +0 -0
  248. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_engineering_planning.py +0 -0
  249. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_engineering_prompt_artifacts.py +0 -0
  250. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_engineering_proposals.py +0 -0
  251. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_ep_http_adapter.py +0 -0
  252. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_execution_context.py +0 -0
  253. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_execution_host_configuration.py +0 -0
  254. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_execution_host_contract.py +0 -0
  255. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_execution_loop.py +0 -0
  256. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_existing_release_reconciliation.py +0 -0
  257. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_forge_console_admin_parity_contract.py +0 -0
  258. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_forge_console_configuration_contract.py +0 -0
  259. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_forge_console_hosting_contract.py +0 -0
  260. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_forge_operations_console_roadmap.py +0 -0
  261. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_forge_outer_loop_ci_roadmap.py +0 -0
  262. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_forge_v1_bootstrap_scheduler_contract.py +0 -0
  263. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_forge_v1_implementation_dag.py +0 -0
  264. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_foundation_loader.py +0 -0
  265. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_foundation_models.py +0 -0
  266. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_generation_one_bootstrap_qualification.py +0 -0
  267. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_generation_two_execution.py +0 -0
  268. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_generation_two_mission_intake.py +0 -0
  269. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_governance_authority.py +0 -0
  270. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_governed_coverage.py +0 -0
  271. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_historical_engineering_intent.py +0 -0
  272. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_host_control_completion.py +0 -0
  273. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_inner_loop_ci_contract.py +0 -0
  274. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_installed_dynamic_mission_runtime.py +0 -0
  275. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_integration_coordination.py +0 -0
  276. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_knowledge_consumption.py +0 -0
  277. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_live_project_roadmap_contract.py +0 -0
  278. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_completion_evaluator.py +0 -0
  279. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_controller.py +0 -0
  280. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_dispatcher.py +0 -0
  281. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_planner.py +0 -0
  282. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_recommendation_engine.py +0 -0
  283. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_recommendation_lifecycle.py +0 -0
  284. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_runtime_projection.py +0 -0
  285. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_runtime_scheduler.py +0 -0
  286. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_state_store.py +0 -0
  287. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_mission_status.py +0 -0
  288. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_openai_action_derivation.py +0 -0
  289. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_operational_reset.py +0 -0
  290. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_operations_read_api.py +0 -0
  291. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_operator_identity.py +0 -0
  292. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_phase_completion.py +0 -0
  293. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_platform_contract_documents.py +0 -0
  294. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_portfolio_intelligence_operation.py +0 -0
  295. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_producer_contract.py +0 -0
  296. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_product_version_operations.py +0 -0
  297. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_production_release_workflow.py +0 -0
  298. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_productization_reconciliation.py +0 -0
  299. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_programme_authorization.py +0 -0
  300. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_provider_security.py +0 -0
  301. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_pypi_distribution_readback.py +0 -0
  302. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_recovered_partial_completion.py +0 -0
  303. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_release_operation.py +0 -0
  304. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_repository_truth.py +0 -0
  305. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_role_aware_conversations_contract.py +0 -0
  306. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_runtime_bootstrap.py +0 -0
  307. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_runtime_database.py +0 -0
  308. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_runtime_evidence.py +0 -0
  309. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_runtime_health.py +0 -0
  310. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_runtime_instance_persistence.py +0 -0
  311. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_runtime_prompt_generation.py +0 -0
  312. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_runtime_service.py +0 -0
  313. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_runtime_status_projection.py +0 -0
  314. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_scheduler_dependency_boundary.py +0 -0
  315. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_schemas.py +0 -0
  316. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_secure_store.py +0 -0
  317. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_solution_templates.py +0 -0
  318. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_substantive_mission_completion.py +0 -0
  319. {forge_autonomy-2.7.28 → forge_autonomy-2.7.30}/tests/test_terminal_continuation_replay.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forge-autonomy
3
- Version: 2.7.28
3
+ Version: 2.7.30
4
4
  Summary: Forge mission planning, producer contracts, and evidence interpretation runtime.
5
5
  Author: Forge maintainers
6
6
  License-Expression: Apache-2.0
@@ -769,15 +769,21 @@ def _proposal(request: ProviderDerivationRequest, item: object,
769
769
  if not isinstance(item["postponed"], bool):
770
770
  raise ValueError("proposal postponed flag is invalid")
771
771
  return DerivedActionProposal(
772
- item["logical_action_id"], item["scope"], item["objective"], tuple(item["dependencies"]),
773
- tuple(item["write_scopes"]), tuple(item["expected_evidence"]), tuple(item["validation_strategy"]),
774
- item["priority"], item["postponed"], tuple(item["human_gates"]), tuple(item["risk_inputs"]),
772
+ item["logical_action_id"], item["scope"], item["objective"], _unique_strings(item["dependencies"]),
773
+ _unique_strings(item["write_scopes"]), _unique_strings(item["expected_evidence"]),
774
+ _unique_strings(item["validation_strategy"]), item["priority"], item["postponed"],
775
+ _unique_strings(item["human_gates"]), _unique_strings(item["risk_inputs"]),
775
776
  ProposalProvenance(request.derivation_id, request.snapshot.id, request.snapshot.digest, adapter_version,
776
- request.provider_id, request.model, tuple(item["source_evidence_refs"])),
777
+ request.provider_id, request.model, _unique_strings(item["source_evidence_refs"])),
777
778
  _mission_gap(item["mission_gap"]),
778
779
  )
779
780
 
780
781
 
782
+ def _unique_strings(values: list[str]) -> tuple[str, ...]:
783
+ """Remove repetition without adding authority or changing string content."""
784
+ return tuple(dict.fromkeys(values))
785
+
786
+
781
787
  def _refinement(snapshot: PlanningSnapshot, reason: str) -> GovernanceRefinementRequired:
782
788
  return GovernanceRefinementRequired(tuple(item.source_id for item in snapshot.evidence),
783
789
  "deterministic validation required", "provider-output", "blocked", reason)
@@ -668,6 +668,14 @@ def _schema_for_approved_contract(scopes: tuple[str, ...], write_scopes: tuple[s
668
668
  raise ValueError("canonical derivation policy is required")
669
669
  schema = json.loads(json.dumps(_SCHEMA))
670
670
  properties = schema["properties"]["proposals"]["items"]["properties"]
671
+ # Keep Structured Outputs at least as strict as the parser that consumes
672
+ # them. Evidence, validation, and provenance are required by the typed
673
+ # proposal model, so their arrays must contain at least one non-empty
674
+ # value. Dependencies may be empty for the first executable proposal.
675
+ for key in ("dependencies", "expected_evidence", "validation_strategy", "source_evidence_refs"):
676
+ properties[key]["items"]["minLength"] = 1
677
+ for key in ("expected_evidence", "validation_strategy", "source_evidence_refs"):
678
+ properties[key]["minItems"] = 1
671
679
  properties["scope"] = {
672
680
  "type": "string", "enum": list(scopes),
673
681
  }
@@ -694,7 +702,9 @@ def _schema_for_approved_contract(scopes: tuple[str, ...], write_scopes: tuple[s
694
702
  "items": {"type": "string", "enum": [item.source_id for item in snapshot.evidence]}},
695
703
  "planning_snapshot_digest": {"type": "string", "enum": [snapshot.digest]},
696
704
  "causal_objective": {"type": "string", "minLength": 1},
697
- "mission_caused_by_action_ids": {"type": "array", "items": {"type": "string"}},
705
+ "mission_caused_by_action_ids": {
706
+ "type": "array", "items": {"type": "string", "minLength": 1},
707
+ },
698
708
  }},
699
709
  {"type": "null"},
700
710
  ]}
@@ -708,9 +718,10 @@ def _mission_gap(document: object) -> MissionGapBinding | None:
708
718
  raise ValueError("Mission-gap binding is malformed")
709
719
  return MissionGapBinding(
710
720
  MissionGapClassification(str(document["classification"])),
711
- tuple(document["criterion_ids"]), tuple(document["triggering_evidence_refs"]),
721
+ tuple(dict.fromkeys(document["criterion_ids"])),
722
+ tuple(dict.fromkeys(document["triggering_evidence_refs"])),
712
723
  str(document["planning_snapshot_digest"]), str(document["causal_objective"]),
713
- tuple(document["mission_caused_by_action_ids"]),
724
+ tuple(dict.fromkeys(document["mission_caused_by_action_ids"])),
714
725
  )
715
726
 
716
727
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forge-autonomy
3
- Version: 2.7.28
3
+ Version: 2.7.30
4
4
  Summary: Forge mission planning, producer contracts, and evidence interpretation runtime.
5
5
  Author: Forge maintainers
6
6
  License-Expression: Apache-2.0
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "product": "forge",
3
3
  "schema_version": 1,
4
- "version": "2.7.28"
4
+ "version": "2.7.30"
5
5
  }
@@ -250,6 +250,13 @@ class CodexCliSessionTests(unittest.TestCase):
250
250
  self.assertEqual(runner.schemas[0]["required"], ["result"])
251
251
  self.assertEqual(runner.schemas[0]["properties"]["result"]["anyOf"][0]["properties"]["proposals"]["items"]["properties"]["write_scopes"]["items"]["enum"],
252
252
  ["forge/planner"])
253
+ proposal_properties = runner.schemas[0]["properties"]["result"]["anyOf"][0]["properties"]["proposals"]["items"]["properties"]
254
+ for key in ("dependencies", "expected_evidence", "validation_strategy", "source_evidence_refs"):
255
+ self.assertEqual(proposal_properties[key]["items"]["minLength"], 1)
256
+ for key in ("expected_evidence", "validation_strategy", "source_evidence_refs"):
257
+ self.assertEqual(proposal_properties[key]["minItems"], 1)
258
+ gap_properties = proposal_properties["mission_gap"]["anyOf"][0]["properties"]
259
+ self.assertEqual(gap_properties["mission_caused_by_action_ids"]["items"]["minLength"], 1)
253
260
  evidence = self.invocation_documents()
254
261
  self.assertEqual([item["state"] for item in evidence], ["STARTED", "HAPPENED_AND_CONFIRMED"])
255
262
  self.assertEqual(evidence[-1]["diagnostic"]["classification"], "COMPLETED_VALID")
@@ -317,6 +324,21 @@ class CodexCliSessionTests(unittest.TestCase):
317
324
  self.assertEqual(response.evidence.status, "contract_invalid")
318
325
  self.assertEqual(self.invocation_documents()[-1]["diagnostic"]["classification"], "COMPLETED_CONTRACT_INVALID")
319
326
 
327
+ def test_schema_valid_repeated_array_values_are_canonicalized(self):
328
+ self.configure()
329
+ repeated = document()
330
+ proposal = repeated["result"]["proposals"][0]
331
+ proposal["expected_evidence"] = ["unit test", "unit test"]
332
+ proposal["validation_strategy"] = ["unit test", "unit test"]
333
+ proposal["source_evidence_refs"] = ["mission_state", "mission_state"]
334
+ response = self.provider(Runner(repeated)).invoke(
335
+ self.request(), approved_scopes=("planner-contract",), derivation_policy=self.policy,
336
+ )
337
+ self.assertEqual(response.evidence.status, "completed")
338
+ self.assertEqual(response.proposals[0].expected_evidence, ("unit test",))
339
+ self.assertEqual(response.proposals[0].validation_strategy, ("unit test",))
340
+ self.assertEqual(response.proposals[0].provenance.source_evidence_refs, ("mission_state",))
341
+
320
342
  def test_object_root_preserves_governance_refinement_without_permitting_mixed_variants(self):
321
343
  self.configure()
322
344
  refinement = {"result": {"kind": "governance_refinement", "reason": "needs architecture"}}
@@ -295,7 +295,7 @@ class InstalledForgeUpdateTests(unittest.TestCase):
295
295
  "github_release": {"draft": False},
296
296
  },
297
297
  }, sort_keys=True), encoding="utf-8")
298
- if version in {"2.7.25", "2.7.26", "2.7.27"}:
298
+ if version in {"2.7.25", "2.7.26", "2.7.27", "2.7.28", "2.7.29", "2.7.30"}:
299
299
  # Captured from the actual installed-composition command used by
300
300
  # both workflow stages; only the synthetic wheel binding changes.
301
301
  summary = json.loads((Path(__file__).parent / "fixtures" /
@@ -1447,6 +1447,75 @@ class InstalledForgeUpdateTests(unittest.TestCase):
1447
1447
  with self.assertRaisesRegex(update.InstalledForgeUpdateError, "noncanonical"):
1448
1448
  update.validate_qualified_artifact(changed)
1449
1449
 
1450
+ def test_2727_to_2728_same_schema_release_preserves_history_and_requires_composition(self):
1451
+ before = self._same_schema39_transition(existing_version="2.7.27", target_version="2.7.28")
1452
+ self.assertEqual(update.transition_schemas(self.request), (39, 39))
1453
+ self.assertEqual(update.validate_qualified_artifact(self.request)["release_route"], "NORMAL")
1454
+ controller = self._controller()
1455
+ self.assertEqual(controller.backup_path.name, "forge-schema39.sqlite3")
1456
+ after = self._qualified_schema39_copy(controller, before)
1457
+ for table, evidence in before["tables"].items():
1458
+ if table != "runtime_metadata":
1459
+ self.assertEqual(after["tables"][table], evidence, table)
1460
+ self.assertEqual(after["protected_metadata_digest"], before["protected_metadata_digest"])
1461
+ self.assertEqual(after["schema_digest"], before["schema_digest"])
1462
+ update.verify_preservation(before, after, self.request)
1463
+ receipt = Path(self.request.qualification_receipt)
1464
+ document = json.loads(receipt.read_text())
1465
+ del document["publication_receipt"]["criterion_completion"]
1466
+ receipt.write_text(json.dumps(document, sort_keys=True))
1467
+ changed = update.UpdateRequest(**{
1468
+ **self.request.__dict__, "qualification_receipt_sha256": update.file_digest(receipt),
1469
+ })
1470
+ with self.assertRaisesRegex(update.InstalledForgeUpdateError, "noncanonical"):
1471
+ update.validate_qualified_artifact(changed)
1472
+
1473
+ def test_2728_to_2729_same_schema_release_preserves_history_and_requires_composition(self):
1474
+ before = self._same_schema39_transition(existing_version="2.7.28", target_version="2.7.29")
1475
+ self.assertEqual(update.transition_schemas(self.request), (39, 39))
1476
+ self.assertEqual(update.validate_qualified_artifact(self.request)["release_route"], "NORMAL")
1477
+ controller = self._controller()
1478
+ self.assertEqual(controller.backup_path.name, "forge-schema39.sqlite3")
1479
+ after = self._qualified_schema39_copy(controller, before)
1480
+ for table, evidence in before["tables"].items():
1481
+ if table != "runtime_metadata":
1482
+ self.assertEqual(after["tables"][table], evidence, table)
1483
+ self.assertEqual(after["protected_metadata_digest"], before["protected_metadata_digest"])
1484
+ self.assertEqual(after["schema_digest"], before["schema_digest"])
1485
+ update.verify_preservation(before, after, self.request)
1486
+ receipt = Path(self.request.qualification_receipt)
1487
+ document = json.loads(receipt.read_text())
1488
+ del document["qualification"]["criterion_completion"]
1489
+ receipt.write_text(json.dumps(document, sort_keys=True))
1490
+ changed = update.UpdateRequest(**{
1491
+ **self.request.__dict__, "qualification_receipt_sha256": update.file_digest(receipt),
1492
+ })
1493
+ with self.assertRaisesRegex(update.InstalledForgeUpdateError, "noncanonical"):
1494
+ update.validate_qualified_artifact(changed)
1495
+
1496
+ def test_2729_to_2730_same_schema_release_preserves_history_and_requires_composition(self):
1497
+ before = self._same_schema39_transition(existing_version="2.7.29", target_version="2.7.30")
1498
+ self.assertEqual(update.transition_schemas(self.request), (39, 39))
1499
+ self.assertEqual(update.validate_qualified_artifact(self.request)["release_route"], "NORMAL")
1500
+ controller = self._controller()
1501
+ self.assertEqual(controller.backup_path.name, "forge-schema39.sqlite3")
1502
+ after = self._qualified_schema39_copy(controller, before)
1503
+ for table, evidence in before["tables"].items():
1504
+ if table != "runtime_metadata":
1505
+ self.assertEqual(after["tables"][table], evidence, table)
1506
+ self.assertEqual(after["protected_metadata_digest"], before["protected_metadata_digest"])
1507
+ self.assertEqual(after["schema_digest"], before["schema_digest"])
1508
+ update.verify_preservation(before, after, self.request)
1509
+ receipt = Path(self.request.qualification_receipt)
1510
+ document = json.loads(receipt.read_text())
1511
+ del document["qualification"]["criterion_completion"]
1512
+ receipt.write_text(json.dumps(document, sort_keys=True))
1513
+ changed = update.UpdateRequest(**{
1514
+ **self.request.__dict__, "qualification_receipt_sha256": update.file_digest(receipt),
1515
+ })
1516
+ with self.assertRaisesRegex(update.InstalledForgeUpdateError, "noncanonical"):
1517
+ update.validate_qualified_artifact(changed)
1518
+
1450
1519
  def test_schema39_same_schema_replay_preserves_database_and_fences_after_activation_boundary(self):
1451
1520
  before = self._same_schema39_transition()
1452
1521
  controller = self._controller()
@@ -1512,8 +1581,11 @@ class InstalledForgeUpdateTests(unittest.TestCase):
1512
1581
  receipt = Path(receipt_value).resolve()
1513
1582
  release = json.loads(receipt.read_text(encoding="utf-8"))
1514
1583
  target_version = release["version"]
1515
- target_schema = 39 if target_version in {"2.7.25", "2.7.26", "2.7.27"} else 38
1516
- previous_version = {"2.7.26": "2.7.25", "2.7.27": "2.7.26"}.get(target_version)
1584
+ target_schema = 39 if target_version in {"2.7.25", "2.7.26", "2.7.27", "2.7.28", "2.7.29", "2.7.30"} else 38
1585
+ previous_version = {
1586
+ "2.7.26": "2.7.25", "2.7.27": "2.7.26", "2.7.28": "2.7.27",
1587
+ "2.7.29": "2.7.28", "2.7.30": "2.7.29",
1588
+ }.get(target_version)
1517
1589
  if previous_version is not None:
1518
1590
  RuntimeBootstrap(data_root=self.data_root, forge_version=previous_version).open().close()
1519
1591
  legacy_interpreter = Path(os.environ.get("FORGE_LEGACY_INTERPRETER", sys.executable))