forge-autonomy 2.7.36__tar.gz → 2.7.37__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 (337) hide show
  1. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/PKG-INFO +1 -1
  2. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/installed_lifecycle.py +13 -0
  3. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/preserved_lifecycle.py +3 -2
  4. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/qualification/server_runtime.py +47 -0
  5. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge_autonomy.egg-info/PKG-INFO +1 -1
  6. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/product-version.json +1 -1
  7. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_installed_lifecycle.py +29 -0
  8. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_preserved_lifecycle.py +42 -0
  9. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/MANIFEST.in +0 -0
  10. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/README.md +0 -0
  11. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/__init__.py +0 -0
  12. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/__main__.py +0 -0
  13. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/_version.py +0 -0
  14. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/action_derivation_canary_closure.py +0 -0
  15. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/action_derivation_evidence.py +0 -0
  16. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/action_derivation_qualification.py +0 -0
  17. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/action_derivation_reattempt.py +0 -0
  18. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/ai_architect/__init__.py +0 -0
  19. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/ai_architect/provider_registry.py +0 -0
  20. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/api/installed-health-component-registry-1.0.json +0 -0
  21. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/api/operations-read-openapi-v1.json +0 -0
  22. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/api/operations-read-postman-v1.json +0 -0
  23. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/api/server-openapi-v1.json +0 -0
  24. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/api/server-postman-v1.json +0 -0
  25. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/architecture/__init__.py +0 -0
  26. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/architecture/advisor.py +0 -0
  27. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/architecture/presentation.py +0 -0
  28. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/architecture/workspace.py +0 -0
  29. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/autonomous_orchestrator.py +0 -0
  30. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/business/__init__.py +0 -0
  31. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/business/advisor.py +0 -0
  32. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/business/ingress.py +0 -0
  33. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/business/presentation.py +0 -0
  34. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/business/workspace.py +0 -0
  35. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/canary.py +0 -0
  36. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/capabilities/__init__.py +0 -0
  37. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/capabilities/delegation.py +0 -0
  38. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/completion/__init__.py +0 -0
  39. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/completion/assessor.py +0 -0
  40. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/completion/host_control_observer.py +0 -0
  41. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/completion/mission.py +0 -0
  42. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/completion/repository_observer.py +0 -0
  43. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/constitutional/__init__.py +0 -0
  44. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/constitutional/assessor.py +0 -0
  45. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/core/__init__.py +0 -0
  46. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/core/json_store.py +0 -0
  47. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/decision_evidence/__init__.py +0 -0
  48. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/decision_evidence/repository.py +0 -0
  49. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/dispatcher/__init__.py +0 -0
  50. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/dispatcher/dispatcher.py +0 -0
  51. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/ep_simulator.py +0 -0
  52. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/execution/__init__.py +0 -0
  53. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/execution/loop.py +0 -0
  54. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/execution/presentation.py +0 -0
  55. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/execution_host_configuration.py +0 -0
  56. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/foundation/__init__.py +0 -0
  57. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/foundation/loader.py +0 -0
  58. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/generation_two.py +0 -0
  59. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/generation_two_execution.py +0 -0
  60. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/governance/__init__.py +0 -0
  61. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/governance/execution_policy.py +0 -0
  62. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/governance/profiles.py +0 -0
  63. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/governance_authority.py +0 -0
  64. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/installed_health.py +0 -0
  65. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/intake.py +0 -0
  66. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/integration/__init__.py +0 -0
  67. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/integration/coordinator.py +0 -0
  68. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/integration/repository.py +0 -0
  69. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/knowledge/__init__.py +0 -0
  70. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/knowledge/consumer.py +0 -0
  71. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/knowledge/registry.py +0 -0
  72. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/lifecycle/__init__.py +0 -0
  73. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/lifecycle/store.py +0 -0
  74. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/mission_amendment.py +0 -0
  75. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/mission_cli.py +0 -0
  76. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/mission_scheduler.py +0 -0
  77. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/__init__.py +0 -0
  78. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/action.py +0 -0
  79. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/action_derivation.py +0 -0
  80. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/agent_policy.py +0 -0
  81. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/ai_architect_provider.py +0 -0
  82. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/ai_architect_session.py +0 -0
  83. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/ai_provider_registry.py +0 -0
  84. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/architecture_mission.py +0 -0
  85. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/architecture_reasoning.py +0 -0
  86. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/architecture_review.py +0 -0
  87. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/codex_runtime_prompt.py +0 -0
  88. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/constitutional_validation.py +0 -0
  89. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/criterion_assessment.py +0 -0
  90. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/criterion_observation.py +0 -0
  91. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/decision_evidence.py +0 -0
  92. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/execution_host.py +0 -0
  93. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/foundation.py +0 -0
  94. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/historical_intent.py +0 -0
  95. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/integration.py +0 -0
  96. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/intent.py +0 -0
  97. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/intent_authoring.py +0 -0
  98. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/mission.py +0 -0
  99. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/mission_candidate.py +0 -0
  100. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/mission_completion.py +0 -0
  101. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/mission_planner.py +0 -0
  102. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/mission_recommendation.py +0 -0
  103. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/phase_completion.py +0 -0
  104. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/planning.py +0 -0
  105. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/producer.py +0 -0
  106. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/prompt_artifact.py +0 -0
  107. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/proposal.py +0 -0
  108. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/runtime_prompt.py +0 -0
  109. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/models/solution_template.py +0 -0
  110. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/operations_read_api.py +0 -0
  111. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/operator_identity.py +0 -0
  112. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planner/__init__.py +0 -0
  113. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planner/action_derivation.py +0 -0
  114. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planner/codex_cli_session.py +0 -0
  115. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planner/durable_derivation.py +0 -0
  116. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planner/engine.py +0 -0
  117. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planner/openai_responses.py +0 -0
  118. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planner/provider_adapter.py +0 -0
  119. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planning/__init__.py +0 -0
  120. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planning/loader.py +0 -0
  121. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/planning/registry.py +0 -0
  122. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/portfolio_intelligence.py +0 -0
  123. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/programme_authorization.py +0 -0
  124. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/prompts/__init__.py +0 -0
  125. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/prompts/codex_cli.py +0 -0
  126. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/prompts/generator.py +0 -0
  127. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/proposals/__init__.py +0 -0
  128. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/proposals/generator.py +0 -0
  129. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/provider_context.py +0 -0
  130. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/provider_security.py +0 -0
  131. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/qualification/__init__.py +0 -0
  132. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/qualification/bootstrap_sequence.py +0 -0
  133. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/qualification/criterion_completion.py +0 -0
  134. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/qualification/generation_one.py +0 -0
  135. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/qualification/installed_smoke.py +0 -0
  136. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/recommendations/__init__.py +0 -0
  137. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/recommendations/engine.py +0 -0
  138. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/repository_truth.py +0 -0
  139. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/review/__init__.py +0 -0
  140. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/review/engine.py +0 -0
  141. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/__init__.py +0 -0
  142. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/bootstrap.py +0 -0
  143. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/data_root.py +0 -0
  144. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/database.py +0 -0
  145. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/dynamic_mission.py +0 -0
  146. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/evidence.py +0 -0
  147. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/execution_context.py +0 -0
  148. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/health.py +0 -0
  149. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/mission_controller.py +0 -0
  150. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/operational_reset.py +0 -0
  151. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/runner.py +0 -0
  152. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/runtime/service.py +0 -0
  153. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/scheduler/__init__.py +0 -0
  154. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/scheduler/adapter.py +0 -0
  155. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/scheduler/ep_http_adapter.py +0 -0
  156. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/scheduler/ep_v12.py +0 -0
  157. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/scheduler/scheduler.py +0 -0
  158. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/capability-registry-1.0.schema.json +0 -0
  159. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/capability.schema.json +0 -0
  160. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/common.schema.json +0 -0
  161. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/decision-evidence-1.0.schema.json +0 -0
  162. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/engineering-goal-0.5.schema.json +0 -0
  163. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/engineering-increment-proposal-0.5.schema.json +0 -0
  164. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/engineering-mode.schema.json +0 -0
  165. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/engineering-plan-0.5.schema.json +0 -0
  166. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/engineering-platform-peer-configuration-1.0.schema.json +0 -0
  167. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/engineering-platform-peer-configuration-1.1.schema.json +0 -0
  168. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/engineering-prompt-artifact-0.7.schema.json +0 -0
  169. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/engineering-proposal-0.6.schema.json +0 -0
  170. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/evidence-reference-0.5.schema.json +0 -0
  171. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/foundation-document.schema.json +0 -0
  172. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/governance-profile.schema.json +0 -0
  173. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/knowledge-source-0.4.schema.json +0 -0
  174. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/knowledge-source.schema.json +0 -0
  175. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/mission-candidate-1.0.schema.json +0 -0
  176. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/mission-candidate-1.1.schema.json +0 -0
  177. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/phase-completion-1.0.schema.json +0 -0
  178. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/planning-document-0.5.schema.json +0 -0
  179. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/repository-catalog.schema.json +0 -0
  180. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/repository.schema.json +0 -0
  181. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/solution-template-1.0.schema.json +0 -0
  182. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/schemas/workspace.schema.json +0 -0
  183. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/secure_store.py +0 -0
  184. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/server_runtime.py +0 -0
  185. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/solutions/__init__.py +0 -0
  186. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/solutions/catalogue.py +0 -0
  187. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/solutions/generator.py +0 -0
  188. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/state/__init__.py +0 -0
  189. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/state/mission_state.py +0 -0
  190. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge/workspace/__init__.py +0 -0
  191. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge_autonomy.egg-info/SOURCES.txt +0 -0
  192. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge_autonomy.egg-info/dependency_links.txt +0 -0
  193. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge_autonomy.egg-info/entry_points.txt +0 -0
  194. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/forge_autonomy.egg-info/top_level.txt +0 -0
  195. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/pyproject.toml +0 -0
  196. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/capability-registry-1.0.schema.json +0 -0
  197. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/capability.schema.json +0 -0
  198. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/common.schema.json +0 -0
  199. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/decision-evidence-1.0.schema.json +0 -0
  200. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/engineering-goal-0.5.schema.json +0 -0
  201. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/engineering-increment-proposal-0.5.schema.json +0 -0
  202. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/engineering-mode.schema.json +0 -0
  203. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/engineering-plan-0.5.schema.json +0 -0
  204. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/engineering-prompt-artifact-0.7.schema.json +0 -0
  205. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/engineering-proposal-0.6.schema.json +0 -0
  206. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/evidence-reference-0.5.schema.json +0 -0
  207. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/foundation-document.schema.json +0 -0
  208. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/governance-profile.schema.json +0 -0
  209. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/knowledge-source-0.4.schema.json +0 -0
  210. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/knowledge-source.schema.json +0 -0
  211. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/mission-candidate-1.0.schema.json +0 -0
  212. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/mission-candidate-1.1.schema.json +0 -0
  213. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/phase-completion-1.0.schema.json +0 -0
  214. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/planning-document-0.5.schema.json +0 -0
  215. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/repository-catalog.schema.json +0 -0
  216. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/repository.schema.json +0 -0
  217. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/solution-template-1.0.schema.json +0 -0
  218. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/schemas/workspace.schema.json +0 -0
  219. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/setup.cfg +0 -0
  220. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_action_derivation.py +0 -0
  221. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_action_derivation_canary_closure.py +0 -0
  222. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_action_derivation_evidence.py +0 -0
  223. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_action_derivation_qualification.py +0 -0
  224. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_adaptive_action_sizing_design.py +0 -0
  225. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_agent_policy.py +0 -0
  226. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_aggregate_health_roadmap.py +0 -0
  227. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_ai_architect_provider.py +0 -0
  228. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_ai_architect_session.py +0 -0
  229. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_ai_development_projection.py +0 -0
  230. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_ai_provider_registry.py +0 -0
  231. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_architecture_reasoning.py +0 -0
  232. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_architecture_review_engine.py +0 -0
  233. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_architecture_workspace.py +0 -0
  234. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_autonomous_orchestrator.py +0 -0
  235. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_bootstrap_adapter.py +0 -0
  236. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_bootstrap_mission_canary.py +0 -0
  237. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_bootstrap_mission_runner.py +0 -0
  238. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_bootstrap_mission_scheduler.py +0 -0
  239. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_bootstrap_sequence_qualification.py +0 -0
  240. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_business_governance_ingress.py +0 -0
  241. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_business_workspace.py +0 -0
  242. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_canonical_data_root.py +0 -0
  243. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_capability_delegation.py +0 -0
  244. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_codex_cli_runtime_prompt.py +0 -0
  245. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_codex_cli_session.py +0 -0
  246. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_constitutional_validation.py +0 -0
  247. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_criterion_assessment_contract.py +0 -0
  248. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_criterion_ep_http_boundary.py +0 -0
  249. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_criterion_planning_context.py +0 -0
  250. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_decision_evidence.py +0 -0
  251. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_default_project_quality_policy.py +0 -0
  252. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_distribution_identity.py +0 -0
  253. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_durable_action_derivation.py +0 -0
  254. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_dynamic_mission_capability.py +0 -0
  255. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_engineering_action_architecture.py +0 -0
  256. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_engineering_intent_authoring.py +0 -0
  257. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_engineering_intent_lifecycle.py +0 -0
  258. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_engineering_mission.py +0 -0
  259. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_engineering_planning.py +0 -0
  260. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_engineering_prompt_artifacts.py +0 -0
  261. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_engineering_proposals.py +0 -0
  262. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_ep_http_adapter.py +0 -0
  263. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_ep_simulator.py +0 -0
  264. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_ep_simulator_rolling_planning.py +0 -0
  265. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_execution_context.py +0 -0
  266. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_execution_host_configuration.py +0 -0
  267. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_execution_host_contract.py +0 -0
  268. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_execution_loop.py +0 -0
  269. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_existing_release_reconciliation.py +0 -0
  270. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_forge_console_admin_parity_contract.py +0 -0
  271. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_forge_console_configuration_contract.py +0 -0
  272. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_forge_console_hosting_contract.py +0 -0
  273. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_forge_operations_console_roadmap.py +0 -0
  274. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_forge_outer_loop_ci_roadmap.py +0 -0
  275. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_forge_v1_bootstrap_scheduler_contract.py +0 -0
  276. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_forge_v1_implementation_dag.py +0 -0
  277. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_foundation_loader.py +0 -0
  278. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_foundation_models.py +0 -0
  279. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_generation_one_bootstrap_qualification.py +0 -0
  280. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_generation_two_execution.py +0 -0
  281. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_generation_two_mission_intake.py +0 -0
  282. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_governance_authority.py +0 -0
  283. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_governed_coverage.py +0 -0
  284. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_historical_engineering_intent.py +0 -0
  285. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_host_control_completion.py +0 -0
  286. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_inner_loop_ci_contract.py +0 -0
  287. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_installed_dynamic_mission_runtime.py +0 -0
  288. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_installed_forge_update.py +0 -0
  289. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_integration_coordination.py +0 -0
  290. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_knowledge_consumption.py +0 -0
  291. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_live_project_roadmap_contract.py +0 -0
  292. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_completion_evaluator.py +0 -0
  293. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_controller.py +0 -0
  294. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_dispatcher.py +0 -0
  295. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_planner.py +0 -0
  296. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_recommendation_engine.py +0 -0
  297. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_recommendation_lifecycle.py +0 -0
  298. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_runtime_projection.py +0 -0
  299. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_runtime_scheduler.py +0 -0
  300. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_state_store.py +0 -0
  301. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_mission_status.py +0 -0
  302. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_openai_action_derivation.py +0 -0
  303. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_operational_reset.py +0 -0
  304. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_operations_health.py +0 -0
  305. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_operations_read_api.py +0 -0
  306. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_operator_identity.py +0 -0
  307. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_phase_completion.py +0 -0
  308. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_platform_contract_documents.py +0 -0
  309. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_portfolio_intelligence_operation.py +0 -0
  310. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_producer_contract.py +0 -0
  311. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_product_version_operations.py +0 -0
  312. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_production_release_workflow.py +0 -0
  313. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_productization_reconciliation.py +0 -0
  314. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_programme_authorization.py +0 -0
  315. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_provider_context.py +0 -0
  316. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_provider_security.py +0 -0
  317. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_pypi_distribution_readback.py +0 -0
  318. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_recovered_partial_completion.py +0 -0
  319. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_release_operation.py +0 -0
  320. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_repository_truth.py +0 -0
  321. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_role_aware_conversations_contract.py +0 -0
  322. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_runtime_bootstrap.py +0 -0
  323. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_runtime_database.py +0 -0
  324. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_runtime_evidence.py +0 -0
  325. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_runtime_health.py +0 -0
  326. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_runtime_instance_persistence.py +0 -0
  327. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_runtime_prompt_generation.py +0 -0
  328. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_runtime_service.py +0 -0
  329. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_runtime_status_projection.py +0 -0
  330. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_scheduler_dependency_boundary.py +0 -0
  331. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_schemas.py +0 -0
  332. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_secure_store.py +0 -0
  333. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_server_api_contract.py +0 -0
  334. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_server_runtime.py +0 -0
  335. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_solution_templates.py +0 -0
  336. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/tests/test_substantive_mission_completion.py +0 -0
  337. {forge_autonomy-2.7.36 → forge_autonomy-2.7.37}/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.36
3
+ Version: 2.7.37
4
4
  Summary: Forge mission planning, producer contracts, and evidence interpretation runtime.
5
5
  Author: Forge maintainers
6
6
  License-Expression: Apache-2.0
@@ -498,6 +498,13 @@ def _exclusive_locks(paths: tuple[Path, ...]) -> Iterator[None]:
498
498
 
499
499
 
500
500
  def _assert_tree_has_no_links(root: Path) -> str:
501
+ """Prove one mutable instance tree is exclusively product-owned and safe."""
502
+ _assert_no_symlink_components(root)
503
+ root_info = root.lstat()
504
+ if not stat.S_ISDIR(root_info.st_mode):
505
+ raise InstalledLifecycleError("instance root is not a directory")
506
+ if stat.S_IMODE(root_info.st_mode) & 0o022:
507
+ raise InstalledLifecycleError("instance root is group/world writable")
501
508
  entries: list[dict[str, object]] = []
502
509
  for directory, names, files in os.walk(root, topdown=True, followlinks=False):
503
510
  parent = Path(directory)
@@ -508,8 +515,14 @@ def _assert_tree_has_no_links(root: Path) -> str:
508
515
  raise InstalledLifecycleError(f"instance tree contains an unsafe symbolic link: {path}")
509
516
  if not (stat.S_ISDIR(info.st_mode) or stat.S_ISREG(info.st_mode)):
510
517
  raise InstalledLifecycleError(f"instance tree contains an unsupported filesystem entry: {path}")
518
+ if stat.S_IMODE(info.st_mode) & 0o022:
519
+ raise InstalledLifecycleError(f"instance tree contains a group/world writable entry: {path}")
520
+ if stat.S_ISREG(info.st_mode) and info.st_nlink != 1:
521
+ raise InstalledLifecycleError(f"instance tree contains a non-exclusive hardlinked file: {path}")
511
522
  entries.append({
512
523
  "path": str(path.relative_to(root)), "mode": stat.S_IFMT(info.st_mode),
524
+ "permissions": stat.S_IMODE(info.st_mode),
525
+ "links": info.st_nlink if stat.S_ISREG(info.st_mode) else None,
513
526
  "size": info.st_size if stat.S_ISREG(info.st_mode) else None,
514
527
  })
515
528
  return _digest_bytes(_json_bytes(entries))
@@ -22,6 +22,7 @@ from .installed_lifecycle import (
22
22
  _assert_identity,
23
23
  _assert_no_symlink_components,
24
24
  _assert_quiescent,
25
+ _assert_tree_has_no_links,
25
26
  _atomic_json,
26
27
  _digest_bytes,
27
28
  _exclusive_locks,
@@ -41,8 +42,8 @@ PROVIDER_AUTH_PRESERVED = "PRESERVED_REQUIRES_REVERIFICATION"
41
42
 
42
43
 
43
44
  def _content_tree_digest(root: Path) -> str:
44
- """Bind every regular byte in one exact, link-free instance tree."""
45
- _assert_no_symlink_components(root)
45
+ """Bind every regular byte after shared exclusive-ownership admission."""
46
+ _assert_tree_has_no_links(root)
46
47
  entries: list[dict[str, object]] = []
47
48
  for directory, names, files in os.walk(root, topdown=True, followlinks=False):
48
49
  parent = Path(directory)
@@ -22,6 +22,7 @@ from urllib.request import Request, urlopen
22
22
  from forge._version import canonical_version
23
23
  from forge.ep_simulator import EpSimulatorServer, EpSimulatorState
24
24
  from forge.installed_lifecycle import (
25
+ InstalledLifecycleError,
25
26
  InstalledUninstallDispatcher,
26
27
  UninstallRequest,
27
28
  UpdateAssessmentRequest,
@@ -249,6 +250,7 @@ def run(*, candidate_wheel: Path | None = None, source_revision: str | None = No
249
250
  "preserve": "NOT_REQUESTED",
250
251
  "restore": "NOT_REQUESTED",
251
252
  "purge": "NOT_REQUESTED",
253
+ "filesystem_security": "NOT_REQUESTED",
252
254
  }
253
255
  if candidate_wheel is not None:
254
256
  if source_revision is None or len(source_revision) != 40:
@@ -265,6 +267,50 @@ def run(*, candidate_wheel: Path | None = None, source_revision: str | None = No
265
267
  raise RuntimeError("installed lifecycle update assessment did not bind the exact artifact")
266
268
  lifecycle["update_assessment"] = "PASS"
267
269
 
270
+ def unsafe_lifecycle_request(data_root: Path, operation_id: str) -> InstanceLifecycleRequest:
271
+ database = RuntimeBootstrap(data_root=data_root, forge_version=version).open()
272
+ try:
273
+ runtime_id = database.runtime_identity.runtime_id
274
+ installation_id = database.metadata["installation_id"]
275
+ finally:
276
+ database.close()
277
+ return InstanceLifecycleRequest(
278
+ operation_id=operation_id,
279
+ instance_id=runtime_id,
280
+ runtime_id=runtime_id,
281
+ installation_id=installation_id,
282
+ installed_version=version,
283
+ installed_source=source_revision,
284
+ installed_artifact_digest=wheel_digest,
285
+ data_root=str(data_root),
286
+ instances_root=str(root.resolve()),
287
+ )
288
+
289
+ hardlink_root = root / "unsafe-hardlink-instance"
290
+ hardlink_request = unsafe_lifecycle_request(hardlink_root, "installed-hardlink-negative")
291
+ foreign = root / "foreign-hardlink-source"
292
+ foreign.write_text("foreign", encoding="utf-8")
293
+ (hardlink_root / "unsafe-hardlink").hardlink_to(foreign)
294
+ try:
295
+ InstalledPreserveDispatcher(hardlink_request).run()
296
+ except InstalledLifecycleError as error:
297
+ if "hardlinked" not in str(error):
298
+ raise RuntimeError("installed lifecycle rejected hardlink for an unexpected reason") from error
299
+ else:
300
+ raise RuntimeError("installed lifecycle accepted a foreign hardlink")
301
+
302
+ permissive_root = root / "unsafe-permissive-instance"
303
+ permissive_request = unsafe_lifecycle_request(permissive_root, "installed-permissive-negative")
304
+ permissive_root.chmod(0o777)
305
+ try:
306
+ InstalledPreserveDispatcher(permissive_request).run()
307
+ except InstalledLifecycleError as error:
308
+ if "group/world writable" not in str(error):
309
+ raise RuntimeError("installed lifecycle rejected permissive root for an unexpected reason") from error
310
+ else:
311
+ raise RuntimeError("installed lifecycle accepted a group/world writable root")
312
+ lifecycle["filesystem_security"] = "PASS"
313
+
268
314
  preserve_request = InstanceLifecycleRequest(
269
315
  operation_id="forge-server-runtime-installed-preserve",
270
316
  instance_id=identities[0],
@@ -399,6 +445,7 @@ def run(*, candidate_wheel: Path | None = None, source_revision: str | None = No
399
445
  "lifecycle_preserve": lifecycle["preserve"],
400
446
  "lifecycle_restore": lifecycle["restore"],
401
447
  "lifecycle_purge": lifecycle["purge"],
448
+ "lifecycle_filesystem_security": lifecycle["filesystem_security"],
402
449
  }
403
450
 
404
451
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forge-autonomy
3
- Version: 2.7.36
3
+ Version: 2.7.37
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.36"
4
+ "version": "2.7.37"
5
5
  }
@@ -251,6 +251,35 @@ class UninstallDispatcherTests(InstalledLifecycleFixture):
251
251
  InstalledUninstallDispatcher(self.uninstall_request()).run()
252
252
  self.assertTrue(self.data_root.exists())
253
253
 
254
+ def test_hardlinked_file_fails_closed(self) -> None:
255
+ foreign = self.root / "foreign-hardlink-source"
256
+ foreign.write_text("foreign", encoding="utf-8")
257
+ (self.data_root / "unsafe-hardlink").hardlink_to(foreign)
258
+ self.assertEqual((self.data_root / "unsafe-hardlink").stat().st_nlink, 2)
259
+ with self.assertRaisesRegex(InstalledLifecycleError, "hardlinked"):
260
+ InstalledUninstallDispatcher(self.uninstall_request()).run()
261
+ self.assertTrue(self.data_root.exists())
262
+
263
+ def test_group_or_world_writable_tree_fails_closed(self) -> None:
264
+ self.data_root.chmod(0o777)
265
+ with self.assertRaisesRegex(InstalledLifecycleError, "group/world writable"):
266
+ InstalledUninstallDispatcher(self.uninstall_request(operation_id="unsafe-root")).run()
267
+ self.data_root.chmod(0o700)
268
+
269
+ unsafe_directory = self.data_root / "unsafe-directory"
270
+ unsafe_directory.mkdir(mode=0o700)
271
+ unsafe_directory.chmod(0o772)
272
+ with self.assertRaisesRegex(InstalledLifecycleError, "group/world writable"):
273
+ InstalledUninstallDispatcher(self.uninstall_request(operation_id="unsafe-directory")).run()
274
+ unsafe_directory.chmod(0o700)
275
+
276
+ unsafe_file = self.data_root / "unsafe-file"
277
+ unsafe_file.write_text("unsafe", encoding="utf-8")
278
+ unsafe_file.chmod(0o666)
279
+ with self.assertRaisesRegex(InstalledLifecycleError, "group/world writable"):
280
+ InstalledUninstallDispatcher(self.uninstall_request(operation_id="unsafe-file")).run()
281
+ self.assertTrue(self.data_root.exists())
282
+
254
283
  @unittest.skipIf(fcntl is None, "POSIX lock qualification")
255
284
  def test_live_server_lock_blocks_uninstall(self) -> None:
256
285
  lock = (self.data_root / "locks" / "forge-server-runtime.lock").open("a+")
@@ -96,6 +96,48 @@ class PreservedLifecycleTests(unittest.TestCase):
96
96
  self.restore_request("restore-0001", "preserve-0001")
97
97
  ).run()
98
98
 
99
+ def test_preserve_rejects_hardlinks_and_insecure_modes(self) -> None:
100
+ foreign = self.root / "foreign-hardlink-source"
101
+ foreign.write_text("foreign", encoding="utf-8")
102
+ (self.data_root / "unsafe-hardlink").hardlink_to(foreign)
103
+ with self.assertRaisesRegex(InstalledLifecycleError, "hardlinked"):
104
+ InstalledPreserveDispatcher(self.request("preserve-hardlink")).run()
105
+ (self.data_root / "unsafe-hardlink").unlink()
106
+
107
+ self.data_root.chmod(0o777)
108
+ with self.assertRaisesRegex(InstalledLifecycleError, "group/world writable"):
109
+ InstalledPreserveDispatcher(self.request("preserve-root-mode")).run()
110
+ self.data_root.chmod(0o700)
111
+
112
+ unsafe_directory = self.data_root / "unsafe-directory"
113
+ unsafe_directory.mkdir(mode=0o700)
114
+ unsafe_directory.chmod(0o772)
115
+ with self.assertRaisesRegex(InstalledLifecycleError, "group/world writable"):
116
+ InstalledPreserveDispatcher(self.request("preserve-directory-mode")).run()
117
+ unsafe_directory.chmod(0o700)
118
+
119
+ unsafe_file = self.data_root / "unsafe-file"
120
+ unsafe_file.write_text("unsafe", encoding="utf-8")
121
+ unsafe_file.chmod(0o666)
122
+ with self.assertRaisesRegex(InstalledLifecycleError, "group/world writable"):
123
+ InstalledPreserveDispatcher(self.request("preserve-file-mode")).run()
124
+
125
+ def test_restore_rejects_insecure_mode_drift_after_preserve(self) -> None:
126
+ InstalledPreserveDispatcher(self.request("preserve-mode-drift")).run()
127
+ self.data_root.chmod(0o777)
128
+ with self.assertRaisesRegex(InstalledLifecycleError, "group/world writable"):
129
+ InstalledRestoreDispatcher(
130
+ self.restore_request("restore-mode-drift", "preserve-mode-drift")
131
+ ).run()
132
+
133
+ def test_purge_rejects_unsafe_tree_before_destructive_boundary(self) -> None:
134
+ unsafe = self.data_root / "unsafe-file"
135
+ unsafe.write_text("unsafe", encoding="utf-8")
136
+ unsafe.chmod(0o666)
137
+ with self.assertRaisesRegex(InstalledLifecycleError, "group/world writable"):
138
+ InstalledPurgeDispatcher(self.request("purge-unsafe")).run()
139
+ self.assertTrue(self.data_root.exists())
140
+
99
141
  def test_restore_rejects_source_or_artifact_identity_drift(self) -> None:
100
142
  InstalledPreserveDispatcher(self.request("preserve-0001")).run()
101
143
  request = self.restore_request("restore-drift", "preserve-0001")