devagent-physical-engine 1.6.0__tar.gz → 1.6.1__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 (223) hide show
  1. {devagent_physical_engine-1.6.0/src/devagent_physical_engine.egg-info → devagent_physical_engine-1.6.1}/PKG-INFO +15 -5
  2. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/README.md +14 -4
  3. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/pyproject.toml +2 -2
  4. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/__init__.py +3 -1
  5. devagent_physical_engine-1.6.1/src/devagent_physical_engine/ros2/moveit_joint_plan_v161_probe.py +154 -0
  6. devagent_physical_engine-1.6.1/src/devagent_physical_engine/ros2/support_contact_runner_v161.py +41 -0
  7. devagent_physical_engine-1.6.1/src/devagent_physical_engine/ros2/support_contact_v161.py +165 -0
  8. devagent_physical_engine-1.6.1/src/devagent_physical_engine/support_contact_hotfix_v161.py +12 -0
  9. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1/src/devagent_physical_engine.egg-info}/PKG-INFO +15 -5
  10. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine.egg-info/SOURCES.txt +6 -0
  11. devagent_physical_engine-1.6.1/tests/test_golden_abb_showcase.py +102 -0
  12. devagent_physical_engine-1.6.1/tests/test_support_contact_hotfix_v161.py +169 -0
  13. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/NOTICE +0 -0
  14. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/setup.cfg +0 -0
  15. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/__init__.py +0 -0
  16. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/compiler.py +0 -0
  17. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/contracts.py +0 -0
  18. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/coordinator.py +0 -0
  19. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/critic.py +0 -0
  20. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/evidence.py +0 -0
  21. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/interpreter.py +0 -0
  22. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/planner.py +0 -0
  23. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/recovery.py +0 -0
  24. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/routing.py +0 -0
  25. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/runtime.py +0 -0
  26. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/semantic.py +0 -0
  27. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/agent/structured.py +0 -0
  28. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ai_cli.py +0 -0
  29. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/cli.py +0 -0
  30. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/commercial.py +0 -0
  31. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/commercial_campaign.py +0 -0
  32. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/commercial_cli.py +0 -0
  33. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/commercial_importer.py +0 -0
  34. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/commercial_intelligence.py +0 -0
  35. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/commercial_readiness.py +0 -0
  36. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/commercial_repository.py +0 -0
  37. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/continuous_clearance.py +0 -0
  38. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/doctor.py +0 -0
  39. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/engineering_agent.py +0 -0
  40. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/engineering_request.py +0 -0
  41. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/evidence_replay.py +0 -0
  42. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/evidence_trust.py +0 -0
  43. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/execution.py +0 -0
  44. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/models.py +0 -0
  45. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/one_command.py +0 -0
  46. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/one_command_runtime.py +0 -0
  47. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/one_command_v15.py +0 -0
  48. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/one_command_v16.py +0 -0
  49. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/operating_envelope.py +0 -0
  50. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/__init__.py +0 -0
  51. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/benchmark.py +0 -0
  52. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/candidates.py +0 -0
  53. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/contracts.py +0 -0
  54. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/evaluator.py +0 -0
  55. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/evidence.py +0 -0
  56. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/experience.py +0 -0
  57. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/measured.py +0 -0
  58. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/optimizer.py +0 -0
  59. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/optimization/orchestrator.py +0 -0
  60. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/physical_campaign.py +0 -0
  61. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/physical_evidence.py +0 -0
  62. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/physical_motion.py +0 -0
  63. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/planning.py +0 -0
  64. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/pose_math.py +0 -0
  65. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/preexecution_contract.py +0 -0
  66. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/production_authority.py +0 -0
  67. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/production_grade.py +0 -0
  68. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/project.py +0 -0
  69. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/provider_adapters/__init__.py +0 -0
  70. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/provider_adapters/anthropic.py +0 -0
  71. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/provider_adapters/common.py +0 -0
  72. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/provider_adapters/factory.py +0 -0
  73. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/provider_adapters/gemini.py +0 -0
  74. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/provider_adapters/openai.py +0 -0
  75. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/provider_criterion.py +0 -0
  76. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/provider_qualification.py +0 -0
  77. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/providers.py +0 -0
  78. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/qualification.py +0 -0
  79. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/qualification_cli.py +0 -0
  80. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/qualification_harness.py +0 -0
  81. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/reference_workcell.py +0 -0
  82. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/report_test_execution.py +0 -0
  83. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/report_test_execution_strict.py +0 -0
  84. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/robot_platform.py +0 -0
  85. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/robots.py +0 -0
  86. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/__init__.py +0 -0
  87. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/acceptance.py +0 -0
  88. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/commands.py +0 -0
  89. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/continuous_clearance_probe.py +0 -0
  90. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/doctor.py +0 -0
  91. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/fk_pose.py +0 -0
  92. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/fk_probe.py +0 -0
  93. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/frame_alignment.py +0 -0
  94. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/gazebo_cli.py +0 -0
  95. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/gazebo_pose.py +0 -0
  96. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/gazebo_world.py +0 -0
  97. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/joint_state_probe.py +0 -0
  98. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/joint_state_recorder.py +0 -0
  99. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/measured_motion.py +0 -0
  100. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/moveit_joint_plan_probe.py +0 -0
  101. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/moveit_scene.py +0 -0
  102. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/moveit_task_planner.py +0 -0
  103. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/preexecution.py +0 -0
  104. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/qualification.py +0 -0
  105. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/qualification_v10.py +0 -0
  106. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/qualification_v11.py +0 -0
  107. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/qualification_v12.py +0 -0
  108. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/report_test_visualization.py +0 -0
  109. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/scene_probe.py +0 -0
  110. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/state_validity_probe.py +0 -0
  111. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/task_adapter.py +0 -0
  112. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/task_visualization.py +0 -0
  113. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/tf_probe.py +0 -0
  114. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/tool_scene.py +0 -0
  115. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/tool_scene_probe.py +0 -0
  116. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/trajectory.py +0 -0
  117. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/trajectory_action_probe.py +0 -0
  118. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/trajectory_tracking.py +0 -0
  119. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/ur5e.py +0 -0
  120. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/ur5e_adapter.py +0 -0
  121. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/ur5e_v10_adapter.py +0 -0
  122. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/workpiece_follow.py +0 -0
  123. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/workpiece_gazebo_follower.py +0 -0
  124. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/workpiece_scene.py +0 -0
  125. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/ros2/workpiece_scene_probe.py +0 -0
  126. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/selective_verification.py +0 -0
  127. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/selective_verification_v16.py +0 -0
  128. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/setup_profile.py +0 -0
  129. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/sim_real_qualification.py +0 -0
  130. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/simulation.py +0 -0
  131. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/simulation_platform.py +0 -0
  132. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/tool_collision.py +0 -0
  133. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/trajectory_qualification.py +0 -0
  134. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/twin.py +0 -0
  135. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/twin_builder.py +0 -0
  136. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/twin_codec.py +0 -0
  137. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/twin_materialization.py +0 -0
  138. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/user_cli.py +0 -0
  139. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/user_cli_v15.py +0 -0
  140. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/user_cli_v16.py +0 -0
  141. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/verification.py +0 -0
  142. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine/workpiece_lifecycle.py +0 -0
  143. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine.egg-info/dependency_links.txt +0 -0
  144. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine.egg-info/entry_points.txt +0 -0
  145. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine.egg-info/requires.txt +0 -0
  146. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/src/devagent_physical_engine.egg-info/top_level.txt +0 -0
  147. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_agent_core.py +0 -0
  148. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_agent_semantic_hardening.py +0 -0
  149. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_ai_cli.py +0 -0
  150. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_ai_cli_v07.py +0 -0
  151. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_commercial_importer_v1.py +0 -0
  152. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_commercial_intelligence_v15.py +0 -0
  153. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_commercial_readiness_v1.py +0 -0
  154. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_commercial_v1.py +0 -0
  155. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_continuous_clearance_v011.py +0 -0
  156. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_core.py +0 -0
  157. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_engineering_request_v07.py +0 -0
  158. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_evidence_replay_v12.py +0 -0
  159. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_evidence_trust_coverage_v12.py +0 -0
  160. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_evidence_trust_transport_v12.py +0 -0
  161. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_evidence_trust_v12.py +0 -0
  162. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_evidence_viewer_palette_v130.py +0 -0
  163. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_gazebo_cli_v0122.py +0 -0
  164. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_interpreter_profiles_v08.py +0 -0
  165. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_joint_state_probe_v0125.py +0 -0
  166. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_live_provider_qualification.py +0 -0
  167. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_measured_motion_v10.py +0 -0
  168. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_moveit_planning_diagnostics_v0125.py +0 -0
  169. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_moveit_scene_v0123.py +0 -0
  170. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_natural_language_agent_v07.py +0 -0
  171. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_one_command_hardening_v13.py +0 -0
  172. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_one_command_pose_hardening_v15.py +0 -0
  173. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_one_command_regression_v141.py +0 -0
  174. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_one_command_v13.py +0 -0
  175. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_openai_strict_schema_v0113.py +0 -0
  176. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_optimization_v05.py +0 -0
  177. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_physical_campaign_v09.py +0 -0
  178. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_physical_evidence_v09.py +0 -0
  179. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_physical_motion_v09.py +0 -0
  180. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_planning_fallback_v012.py +0 -0
  181. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_pose_math_v0125.py +0 -0
  182. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_preexecution_contract_v10.py +0 -0
  183. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_production_authority_v11.py +0 -0
  184. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_production_grade_coverage_v11.py +0 -0
  185. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_production_grade_v11.py +0 -0
  186. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_project_spine_v013.py +0 -0
  187. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_provider_and_qualification.py +0 -0
  188. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_provider_criterion_v15.py +0 -0
  189. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_qualification_cli_lifecycle_v06.py +0 -0
  190. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_qualification_harness_v06.py +0 -0
  191. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_readme_pypi.py +0 -0
  192. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_real_provider_adapters.py +0 -0
  193. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_reference_workcell_ros_frames_v0125.py +0 -0
  194. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_reference_workcell_v012.py +0 -0
  195. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_report_test_contract_coverage_v16.py +0 -0
  196. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_report_test_lineage_v16.py +0 -0
  197. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_report_test_visual_execution_v16.py +0 -0
  198. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_robot_platform_v08.py +0 -0
  199. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_ros2_production_receipts_v011.py +0 -0
  200. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_ros2_simulation.py +0 -0
  201. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_ros_trajectory_v09.py +0 -0
  202. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_selective_verification_v14.py +0 -0
  203. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_setup_profile.py +0 -0
  204. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_sim_real_qualification_v011.py +0 -0
  205. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_simulation_platform_v08.py +0 -0
  206. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_tool_collision_v011.py +0 -0
  207. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_tool_scene_v0124.py +0 -0
  208. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_trajectory_action_probe_v0125.py +0 -0
  209. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_trajectory_qualification_v09.py +0 -0
  210. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_trajectory_tracking_v0125.py +0 -0
  211. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_twin_materialization_v10.py +0 -0
  212. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_twin_v08.py +0 -0
  213. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_ur5e_adapter_scopes_v09.py +0 -0
  214. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_ur5e_v10_adapter_scopes.py +0 -0
  215. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_user_cli_interactive_v131.py +0 -0
  216. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_user_cli_progress_v131.py +0 -0
  217. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_user_cli_report_visual_v16.py +0 -0
  218. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_user_cli_selective_v14.py +0 -0
  219. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_user_cli_v15.py +0 -0
  220. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_user_cli_v15_hotfix_inheritance.py +0 -0
  221. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_v052_stabilization.py +0 -0
  222. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_v08_catalog_mapping_regression.py +0 -0
  223. {devagent_physical_engine-1.6.0 → devagent_physical_engine-1.6.1}/tests/test_workpiece_lifecycle_v011.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devagent-physical-engine
3
- Version: 1.6.0
3
+ Version: 1.6.1
4
4
  Summary: Production-grade verification-first robotics evidence runtime with one-command customer intake, validated requirement mapping, report-test Gazebo visualization, requirement-driven test generation, selective verification, deterministic Twin lineage, measured physical verification, replay inspection, regression, and FAT evidence.
5
5
  Author: Tom Ha
6
6
  License: All Rights Reserved
@@ -82,7 +82,7 @@ DevAgent is designed to answer: **What can be proven about this cell, what faile
82
82
  Python 3.11+ is required.
83
83
 
84
84
  ```bash
85
- python -m pip install --upgrade devagent-physical-engine==1.6.0
85
+ python -m pip install --upgrade devagent-physical-engine==1.6.1
86
86
  ```
87
87
 
88
88
  Verify the installed package:
@@ -94,7 +94,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
94
94
  Expected:
95
95
 
96
96
  ```text
97
- 1.6.0
97
+ 1.6.1
98
98
  ```
99
99
 
100
100
  Run the normal customer workflow:
@@ -207,6 +207,16 @@ devagent-physical ros demo
207
207
 
208
208
  for report evidence.
209
209
 
210
+ ## v1.6.1 support-contact lift hotfix
211
+
212
+ The qualified reference load profile starts with the workpiece physically resting on its source support. During the first attached-object `lift` preflight, v1.6.1 preserves the complete live MoveIt Allowed Collision Matrix and enables exactly one temporary request-local pair:
213
+
214
+ ```text
215
+ attached workpiece ↔ conveyor_a support surface
216
+ ```
217
+
218
+ That allowance is scoped to lift departure only. Transfer/place keep normal collision checking, no global PlanningScene collision policy is disabled, and the live ACM is never replaced by a sparse two-object matrix.
219
+
210
220
  ## Exact lineage hardening
211
221
 
212
222
  A case ID such as `case-0001` is local to its verification plan. v1.6 therefore requires the complete lineage:
@@ -502,9 +512,9 @@ devagent-physical-ai optional provider-backed engineering front end
502
512
 
503
513
  # Project status
504
514
 
505
- **v1.6.0 — Production/Stable software workflow**
515
+ **v1.6.1 — Production/Stable software workflow**
506
516
 
507
- v1.6.0 adds exact-Twin report-test visual execution, immutable Requirement→Mapping→Verification Plan→Case lineage validation, qualified Gazebo/MoveIt execution for the packaged UR5e nominal report profile, typed simulation measurement binding, interactive report-case visualization, and fail-closed handling for unsupported or ambiguous execution scopes.
517
+ v1.6.1 hotfixes the qualified UR5e report-test lift preflight by preserving the complete live MoveIt Allowed Collision Matrix and allowing only the attached workpiece/source-support contact during lift departure. It retains v1.6 exact-Twin report execution, immutable Requirement→Mapping→Verification Plan→Case lineage, typed simulation measurements, interactive report-case visualization, and fail-closed unsupported scopes.
508
518
 
509
519
  Production-oriented software capabilities include:
510
520
 
@@ -41,7 +41,7 @@ DevAgent is designed to answer: **What can be proven about this cell, what faile
41
41
  Python 3.11+ is required.
42
42
 
43
43
  ```bash
44
- python -m pip install --upgrade devagent-physical-engine==1.6.0
44
+ python -m pip install --upgrade devagent-physical-engine==1.6.1
45
45
  ```
46
46
 
47
47
  Verify the installed package:
@@ -53,7 +53,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
53
53
  Expected:
54
54
 
55
55
  ```text
56
- 1.6.0
56
+ 1.6.1
57
57
  ```
58
58
 
59
59
  Run the normal customer workflow:
@@ -166,6 +166,16 @@ devagent-physical ros demo
166
166
 
167
167
  for report evidence.
168
168
 
169
+ ## v1.6.1 support-contact lift hotfix
170
+
171
+ The qualified reference load profile starts with the workpiece physically resting on its source support. During the first attached-object `lift` preflight, v1.6.1 preserves the complete live MoveIt Allowed Collision Matrix and enables exactly one temporary request-local pair:
172
+
173
+ ```text
174
+ attached workpiece ↔ conveyor_a support surface
175
+ ```
176
+
177
+ That allowance is scoped to lift departure only. Transfer/place keep normal collision checking, no global PlanningScene collision policy is disabled, and the live ACM is never replaced by a sparse two-object matrix.
178
+
169
179
  ## Exact lineage hardening
170
180
 
171
181
  A case ID such as `case-0001` is local to its verification plan. v1.6 therefore requires the complete lineage:
@@ -461,9 +471,9 @@ devagent-physical-ai optional provider-backed engineering front end
461
471
 
462
472
  # Project status
463
473
 
464
- **v1.6.0 — Production/Stable software workflow**
474
+ **v1.6.1 — Production/Stable software workflow**
465
475
 
466
- v1.6.0 adds exact-Twin report-test visual execution, immutable Requirement→Mapping→Verification Plan→Case lineage validation, qualified Gazebo/MoveIt execution for the packaged UR5e nominal report profile, typed simulation measurement binding, interactive report-case visualization, and fail-closed handling for unsupported or ambiguous execution scopes.
476
+ v1.6.1 hotfixes the qualified UR5e report-test lift preflight by preserving the complete live MoveIt Allowed Collision Matrix and allowing only the attached workpiece/source-support contact during lift departure. It retains v1.6 exact-Twin report execution, immutable Requirement→Mapping→Verification Plan→Case lineage, typed simulation measurements, interactive report-case visualization, and fail-closed unsupported scopes.
467
477
 
468
478
  Production-oriented software capabilities include:
469
479
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devagent-physical-engine"
7
- version = "1.6.0"
7
+ version = "1.6.1"
8
8
  description = "Production-grade verification-first robotics evidence runtime with one-command customer intake, validated requirement mapping, report-test Gazebo visualization, requirement-driven test generation, selective verification, deterministic Twin lineage, measured physical verification, replay inspection, regression, and FAT evidence."
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.11"
@@ -81,4 +81,4 @@ omit = [
81
81
  [tool.coverage.report]
82
82
  fail_under = 75
83
83
  show_missing = true
84
- skip_covered = false
84
+ skip_covered = false
@@ -108,6 +108,7 @@ from .selective_verification import (
108
108
  VerificationTestMappingRecorder,
109
109
  )
110
110
  from .selective_verification_v16 import SelectiveVerificationServiceV16
111
+ from .support_contact_hotfix_v161 import install_support_contact_hotfix_v161
111
112
  from .twin import TwinConfidenceLevel, TwinSpec, TwinValidationReport, TwinValidator
112
113
  from .twin_codec import twin_from_dict, twin_from_revision
113
114
 
@@ -209,6 +210,7 @@ __all__ = [
209
210
  "twin_from_revision",
210
211
  ]
211
212
 
213
+ install_support_contact_hotfix_v161()
212
214
  install_one_command_runtime()
213
215
 
214
- __version__ = "1.6.0"
216
+ __version__ = "1.6.1"
@@ -0,0 +1,154 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import json
5
+ from pathlib import Path
6
+ import sys
7
+ from typing import Any, Mapping
8
+
9
+ # ROS helpers are executed by absolute file path under the distro Python rather than
10
+ # the caller's virtualenv. Add the package src root explicitly so this hotfix can reuse
11
+ # the validated v1.6 probe contract without inheriting virtualenv Python overrides.
12
+ _SRC_ROOT = Path(__file__).resolve().parents[2]
13
+ if str(_SRC_ROOT) not in sys.path:
14
+ sys.path.insert(0, str(_SRC_ROOT))
15
+
16
+ from devagent_physical_engine.ros2 import moveit_joint_plan_probe as base
17
+ from devagent_physical_engine.ros2.support_contact_v161 import (
18
+ SUPPORT_CONTACT_SCOPE,
19
+ SupportContactContractError,
20
+ allow_only_support_pair,
21
+ )
22
+
23
+
24
+ def _support_contract(path: Path) -> tuple[str, str] | None:
25
+ try:
26
+ payload = json.loads(path.read_text(encoding="utf-8"))
27
+ except (OSError, json.JSONDecodeError) as exc:
28
+ raise SupportContactContractError("support_contact_request_invalid") from exc
29
+ if not isinstance(payload, Mapping):
30
+ raise SupportContactContractError("support_contact_request_invalid")
31
+ scene = payload.get("scene_contract")
32
+ if not isinstance(scene, Mapping) or scene.get("allow_support_contact") is not True:
33
+ return None
34
+ if str(scene.get("state") or "") != "attached":
35
+ raise SupportContactContractError("support_contact_requires_attached_scene")
36
+ if str(scene.get("support_contact_scope") or "") != SUPPORT_CONTACT_SCOPE:
37
+ raise SupportContactContractError("support_contact_scope_invalid")
38
+ workpiece = scene.get("workpiece")
39
+ if not isinstance(workpiece, Mapping):
40
+ raise SupportContactContractError("support_contact_workpiece_missing")
41
+ workpiece_id = str(workpiece.get("id") or "").strip()
42
+ support_id = str(scene.get("support_surface_id") or "").strip()
43
+ if not workpiece_id or not support_id or workpiece_id == support_id:
44
+ raise SupportContactContractError("support_contact_pair_invalid")
45
+ return workpiece_id, support_id
46
+
47
+
48
+ def _read_live_acm(*, timeout_s: float) -> dict[str, Any]:
49
+ import rclpy
50
+ from moveit_msgs.msg import PlanningSceneComponents
51
+ from moveit_msgs.srv import GetPlanningScene
52
+
53
+ rclpy.init()
54
+ node = rclpy.create_node("devagent_moveit_support_acm_probe_v161")
55
+ client = node.create_client(GetPlanningScene, "/get_planning_scene")
56
+ try:
57
+ if not client.wait_for_service(timeout_sec=timeout_s):
58
+ raise SupportContactContractError("moveit_planning_scene_service_unavailable")
59
+ request = GetPlanningScene.Request()
60
+ request.components.components = PlanningSceneComponents.ALLOWED_COLLISION_MATRIX
61
+ future = client.call_async(request)
62
+ rclpy.spin_until_future_complete(node, future, timeout_sec=timeout_s)
63
+ if not future.done() or future.result() is None:
64
+ raise SupportContactContractError("moveit_planning_scene_acm_timeout")
65
+ acm = future.result().scene.allowed_collision_matrix
66
+ return {
67
+ "entry_names": [str(value) for value in acm.entry_names],
68
+ "entry_values": [list(item.enabled) for item in acm.entry_values],
69
+ "default_entry_names": [str(value) for value in acm.default_entry_names],
70
+ "default_entry_values": [bool(value) for value in acm.default_entry_values],
71
+ }
72
+ finally:
73
+ node.destroy_client(client)
74
+ node.destroy_node()
75
+ if rclpy.ok():
76
+ rclpy.shutdown()
77
+
78
+
79
+ def _install_full_acm(payload: Mapping[str, Any]):
80
+ original = base._apply_scene_contract
81
+
82
+ def apply(goal, contract):
83
+ original(goal, contract)
84
+ from moveit_msgs.msg import AllowedCollisionEntry
85
+
86
+ acm = goal.planning_options.planning_scene_diff.allowed_collision_matrix
87
+ acm.entry_names = list(payload["entry_names"])
88
+ acm.entry_values = [
89
+ AllowedCollisionEntry(enabled=list(row))
90
+ for row in payload["entry_values"]
91
+ ]
92
+ acm.default_entry_names = list(payload["default_entry_names"])
93
+ acm.default_entry_values = list(payload["default_entry_values"])
94
+
95
+ base._apply_scene_contract = apply
96
+ return original
97
+
98
+
99
+ def plan(path: Path, *, timeout_s: float) -> dict[str, Any]:
100
+ support = _support_contract(path)
101
+ if support is None:
102
+ return base.plan(path, timeout_s=timeout_s)
103
+ workpiece_id, support_id = support
104
+ live = _read_live_acm(timeout_s=timeout_s)
105
+ augmented = allow_only_support_pair(
106
+ live,
107
+ workpiece_id=workpiece_id,
108
+ support_surface_id=support_id,
109
+ )
110
+ original = _install_full_acm(augmented)
111
+ try:
112
+ result = dict(base.plan(path, timeout_s=timeout_s))
113
+ finally:
114
+ base._apply_scene_contract = original
115
+ result.update(
116
+ {
117
+ "support_contact_allowed": True,
118
+ "support_contact_scope": SUPPORT_CONTACT_SCOPE,
119
+ "support_surface_id": support_id,
120
+ "support_workpiece_id": workpiece_id,
121
+ "support_acm_entry_count": len(augmented["entry_names"]),
122
+ }
123
+ )
124
+ if (
125
+ result.get("success") is not True
126
+ and str(result.get("code") or "").startswith("move_group_action_status_")
127
+ ):
128
+ result["underlying_code"] = result.get("code")
129
+ result["code"] = "moveit_support_contact_departure_aborted"
130
+ return result
131
+
132
+
133
+ def main() -> int:
134
+ parser = argparse.ArgumentParser()
135
+ parser.add_argument("--input", required=True)
136
+ parser.add_argument("--timeout", type=float, default=15.0)
137
+ args = parser.parse_args()
138
+ try:
139
+ result = plan(
140
+ Path(args.input).expanduser().resolve(),
141
+ timeout_s=float(args.timeout),
142
+ )
143
+ except Exception as exc:
144
+ result = {
145
+ "success": False,
146
+ "code": f"moveit_support_contact_probe_error:{type(exc).__name__}",
147
+ "detail": str(exc),
148
+ }
149
+ print(json.dumps(result, sort_keys=True))
150
+ return 0 if result.get("success") else 2
151
+
152
+
153
+ if __name__ == "__main__":
154
+ raise SystemExit(main())
@@ -0,0 +1,41 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import Sequence
5
+
6
+ from .commands import CommandResult, SubprocessRosRunner
7
+ from .support_contact_v161 import prepare_lift_support_request
8
+
9
+
10
+ _LEGACY_PROBE = "moveit_joint_plan_probe.py"
11
+ _HOTFIX_PROBE = "moveit_joint_plan_v161_probe.py"
12
+
13
+
14
+ def rewrite_moveit_probe_command(command: Sequence[str]) -> tuple[str, ...]:
15
+ rewritten = [str(value) for value in command]
16
+ if len(rewritten) < 2 or Path(rewritten[1]).name != _LEGACY_PROBE:
17
+ return tuple(rewritten)
18
+ try:
19
+ input_index = rewritten.index("--input") + 1
20
+ request_path = Path(rewritten[input_index]).expanduser().resolve()
21
+ except (ValueError, IndexError):
22
+ return tuple(rewritten)
23
+ if not prepare_lift_support_request(request_path):
24
+ return tuple(rewritten)
25
+ rewritten[1] = str(Path(__file__).with_name(_HOTFIX_PROBE).resolve())
26
+ return tuple(rewritten)
27
+
28
+
29
+ class SupportContactSubprocessRosRunner(SubprocessRosRunner):
30
+ """Report-test ROS runner with a bounded lift support-contact preflight hotfix."""
31
+
32
+ def run(
33
+ self,
34
+ command: Sequence[str],
35
+ *,
36
+ timeout_s: float = 15.0,
37
+ ) -> CommandResult:
38
+ return super().run(
39
+ rewrite_moveit_probe_command(command),
40
+ timeout_s=timeout_s,
41
+ )
@@ -0,0 +1,165 @@
1
+ from __future__ import annotations
2
+
3
+ from copy import deepcopy
4
+ import json
5
+ from pathlib import Path
6
+ from typing import Any, Mapping, Sequence
7
+
8
+ from ..twin_materialization import _backend_id as _materialized_backend_id
9
+
10
+
11
+ QUALIFIED_SOURCE_ENTITY_ID = "conveyor_a"
12
+ SUPPORT_CONTACT_SCOPE = "lift_departure_only"
13
+
14
+
15
+ class SupportContactContractError(ValueError):
16
+ pass
17
+
18
+
19
+ def support_surface_backend_id(
20
+ source_entity_id: str = QUALIFIED_SOURCE_ENTITY_ID,
21
+ ) -> str:
22
+ source = str(source_entity_id).strip()
23
+ if not source:
24
+ raise SupportContactContractError("support_surface_entity_id_missing")
25
+ return _materialized_backend_id(source)
26
+
27
+
28
+ def prepare_lift_support_request(
29
+ path: Path | str,
30
+ *,
31
+ source_entity_id: str = QUALIFIED_SOURCE_ENTITY_ID,
32
+ ) -> bool:
33
+ """Annotate only the qualified lift-departure request with one support pair.
34
+
35
+ The v1.6 report profile preflights every phase before execution. The workpiece is
36
+ resting on the source fixture at the grasp pose, so the first request-local
37
+ attached-object scene must tolerate exactly that workpiece/support contact while
38
+ departing upward. Transfer/place remain untouched and therefore keep normal
39
+ collision checking.
40
+ """
41
+
42
+ target = Path(path).expanduser().resolve()
43
+ if not target.name.endswith("-lift.request.json"):
44
+ return False
45
+ try:
46
+ payload = json.loads(target.read_text(encoding="utf-8"))
47
+ except (OSError, json.JSONDecodeError) as exc:
48
+ raise SupportContactContractError("support_contact_request_invalid") from exc
49
+ if not isinstance(payload, dict):
50
+ raise SupportContactContractError("support_contact_request_invalid")
51
+ raw_scene = payload.get("scene_contract")
52
+ if not isinstance(raw_scene, Mapping) or str(raw_scene.get("state") or "") != "attached":
53
+ return False
54
+ raw_workpiece = raw_scene.get("workpiece")
55
+ if not isinstance(raw_workpiece, Mapping):
56
+ raise SupportContactContractError("support_contact_workpiece_missing")
57
+ workpiece_id = str(raw_workpiece.get("id") or "").strip()
58
+ if not workpiece_id:
59
+ raise SupportContactContractError("support_contact_workpiece_missing")
60
+ support_id = support_surface_backend_id(source_entity_id)
61
+ if support_id == workpiece_id:
62
+ raise SupportContactContractError("support_contact_pair_invalid")
63
+
64
+ scene = dict(raw_scene)
65
+ scene.update(
66
+ {
67
+ "allow_support_contact": True,
68
+ "support_contact_scope": SUPPORT_CONTACT_SCOPE,
69
+ "support_surface_id": support_id,
70
+ }
71
+ )
72
+ payload["scene_contract"] = scene
73
+ temporary = target.with_suffix(target.suffix + ".tmp")
74
+ temporary.write_text(
75
+ json.dumps(payload, sort_keys=True, separators=(",", ":"), allow_nan=False),
76
+ encoding="utf-8",
77
+ )
78
+ temporary.replace(target)
79
+ return True
80
+
81
+
82
+ def _validated_bool_rows(raw: object, *, size: int) -> list[list[bool]]:
83
+ if isinstance(raw, (str, bytes, bytearray)) or not isinstance(raw, Sequence):
84
+ raise SupportContactContractError("allowed_collision_matrix_invalid")
85
+ rows: list[list[bool]] = []
86
+ for item in raw:
87
+ if isinstance(item, (str, bytes, bytearray)) or not isinstance(item, Sequence):
88
+ raise SupportContactContractError("allowed_collision_matrix_invalid")
89
+ row = [bool(value) for value in item]
90
+ if len(row) != size:
91
+ raise SupportContactContractError("allowed_collision_matrix_invalid")
92
+ rows.append(row)
93
+ if len(rows) != size:
94
+ raise SupportContactContractError("allowed_collision_matrix_invalid")
95
+ return rows
96
+
97
+
98
+ def allow_only_support_pair(
99
+ payload: Mapping[str, Any],
100
+ *,
101
+ workpiece_id: str,
102
+ support_surface_id: str,
103
+ ) -> dict[str, Any]:
104
+ """Return a full ACM preserving every existing entry and allowing one pair.
105
+
106
+ MoveIt replaces the ACM when a PlanningScene diff contains entry_names, so a sparse
107
+ two-name matrix would accidentally discard SRDF self-collision allowances. This
108
+ function starts from the full live ACM returned by /get_planning_scene, adds names
109
+ using MoveIt's default-entry semantics, and flips only the symmetric
110
+ workpiece/support pair to True.
111
+ """
112
+
113
+ left = str(workpiece_id).strip()
114
+ right = str(support_surface_id).strip()
115
+ if not left or not right or left == right:
116
+ raise SupportContactContractError("support_contact_pair_invalid")
117
+
118
+ result = deepcopy(dict(payload))
119
+ raw_names = result.get("entry_names", [])
120
+ if isinstance(raw_names, (str, bytes, bytearray)) or not isinstance(raw_names, Sequence):
121
+ raise SupportContactContractError("allowed_collision_matrix_invalid")
122
+ names = [str(value).strip() for value in raw_names]
123
+ if any(not value for value in names) or len(set(names)) != len(names):
124
+ raise SupportContactContractError("allowed_collision_matrix_invalid")
125
+ rows = _validated_bool_rows(result.get("entry_values", []), size=len(names))
126
+
127
+ raw_default_names = result.get("default_entry_names", [])
128
+ raw_default_values = result.get("default_entry_values", [])
129
+ if (
130
+ isinstance(raw_default_names, (str, bytes, bytearray))
131
+ or not isinstance(raw_default_names, Sequence)
132
+ or isinstance(raw_default_values, (str, bytes, bytearray))
133
+ or not isinstance(raw_default_values, Sequence)
134
+ ):
135
+ raise SupportContactContractError("allowed_collision_matrix_invalid")
136
+ default_names = [str(value).strip() for value in raw_default_names]
137
+ default_values = [bool(value) for value in raw_default_values]
138
+ if len(default_names) != len(default_values) or any(not value for value in default_names):
139
+ raise SupportContactContractError("allowed_collision_matrix_invalid")
140
+ default_by_name = dict(zip(default_names, default_values))
141
+
142
+ def add_name(name: str) -> None:
143
+ if name in names:
144
+ return
145
+ if name in default_by_name:
146
+ new_values = [default_by_name[name]] * len(names)
147
+ else:
148
+ new_values = [default_by_name.get(existing, False) for existing in names]
149
+ for row, enabled in zip(rows, (*new_values, False)):
150
+ row.append(bool(enabled))
151
+ names.append(name)
152
+ rows.append([*new_values, False])
153
+
154
+ add_name(left)
155
+ add_name(right)
156
+ left_index = names.index(left)
157
+ right_index = names.index(right)
158
+ rows[left_index][right_index] = True
159
+ rows[right_index][left_index] = True
160
+
161
+ result["entry_names"] = names
162
+ result["entry_values"] = rows
163
+ result["default_entry_names"] = default_names
164
+ result["default_entry_values"] = default_values
165
+ return result
@@ -0,0 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ def install_support_contact_hotfix_v161() -> None:
5
+ """Install the v1.6.1 report-test ROS runner without changing other ROS paths."""
6
+
7
+ from . import report_test_execution
8
+ from .ros2.support_contact_runner_v161 import SupportContactSubprocessRosRunner
9
+
10
+ if report_test_execution.SubprocessRosRunner is SupportContactSubprocessRosRunner:
11
+ return
12
+ report_test_execution.SubprocessRosRunner = SupportContactSubprocessRosRunner
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devagent-physical-engine
3
- Version: 1.6.0
3
+ Version: 1.6.1
4
4
  Summary: Production-grade verification-first robotics evidence runtime with one-command customer intake, validated requirement mapping, report-test Gazebo visualization, requirement-driven test generation, selective verification, deterministic Twin lineage, measured physical verification, replay inspection, regression, and FAT evidence.
5
5
  Author: Tom Ha
6
6
  License: All Rights Reserved
@@ -82,7 +82,7 @@ DevAgent is designed to answer: **What can be proven about this cell, what faile
82
82
  Python 3.11+ is required.
83
83
 
84
84
  ```bash
85
- python -m pip install --upgrade devagent-physical-engine==1.6.0
85
+ python -m pip install --upgrade devagent-physical-engine==1.6.1
86
86
  ```
87
87
 
88
88
  Verify the installed package:
@@ -94,7 +94,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
94
94
  Expected:
95
95
 
96
96
  ```text
97
- 1.6.0
97
+ 1.6.1
98
98
  ```
99
99
 
100
100
  Run the normal customer workflow:
@@ -207,6 +207,16 @@ devagent-physical ros demo
207
207
 
208
208
  for report evidence.
209
209
 
210
+ ## v1.6.1 support-contact lift hotfix
211
+
212
+ The qualified reference load profile starts with the workpiece physically resting on its source support. During the first attached-object `lift` preflight, v1.6.1 preserves the complete live MoveIt Allowed Collision Matrix and enables exactly one temporary request-local pair:
213
+
214
+ ```text
215
+ attached workpiece ↔ conveyor_a support surface
216
+ ```
217
+
218
+ That allowance is scoped to lift departure only. Transfer/place keep normal collision checking, no global PlanningScene collision policy is disabled, and the live ACM is never replaced by a sparse two-object matrix.
219
+
210
220
  ## Exact lineage hardening
211
221
 
212
222
  A case ID such as `case-0001` is local to its verification plan. v1.6 therefore requires the complete lineage:
@@ -502,9 +512,9 @@ devagent-physical-ai optional provider-backed engineering front end
502
512
 
503
513
  # Project status
504
514
 
505
- **v1.6.0 — Production/Stable software workflow**
515
+ **v1.6.1 — Production/Stable software workflow**
506
516
 
507
- v1.6.0 adds exact-Twin report-test visual execution, immutable Requirement→Mapping→Verification Plan→Case lineage validation, qualified Gazebo/MoveIt execution for the packaged UR5e nominal report profile, typed simulation measurement binding, interactive report-case visualization, and fail-closed handling for unsupported or ambiguous execution scopes.
517
+ v1.6.1 hotfixes the qualified UR5e report-test lift preflight by preserving the complete live MoveIt Allowed Collision Matrix and allowing only the attached workpiece/source-support contact during lift departure. It retains v1.6 exact-Twin report execution, immutable Requirement→Mapping→Verification Plan→Case lineage, typed simulation measurements, interactive report-case visualization, and fail-closed unsupported scopes.
508
518
 
509
519
  Production-oriented software capabilities include:
510
520
 
@@ -50,6 +50,7 @@ src/devagent_physical_engine/setup_profile.py
50
50
  src/devagent_physical_engine/sim_real_qualification.py
51
51
  src/devagent_physical_engine/simulation.py
52
52
  src/devagent_physical_engine/simulation_platform.py
53
+ src/devagent_physical_engine/support_contact_hotfix_v161.py
53
54
  src/devagent_physical_engine/tool_collision.py
54
55
  src/devagent_physical_engine/trajectory_qualification.py
55
56
  src/devagent_physical_engine/twin.py
@@ -111,6 +112,7 @@ src/devagent_physical_engine/ros2/joint_state_probe.py
111
112
  src/devagent_physical_engine/ros2/joint_state_recorder.py
112
113
  src/devagent_physical_engine/ros2/measured_motion.py
113
114
  src/devagent_physical_engine/ros2/moveit_joint_plan_probe.py
115
+ src/devagent_physical_engine/ros2/moveit_joint_plan_v161_probe.py
114
116
  src/devagent_physical_engine/ros2/moveit_scene.py
115
117
  src/devagent_physical_engine/ros2/moveit_task_planner.py
116
118
  src/devagent_physical_engine/ros2/preexecution.py
@@ -121,6 +123,8 @@ src/devagent_physical_engine/ros2/qualification_v12.py
121
123
  src/devagent_physical_engine/ros2/report_test_visualization.py
122
124
  src/devagent_physical_engine/ros2/scene_probe.py
123
125
  src/devagent_physical_engine/ros2/state_validity_probe.py
126
+ src/devagent_physical_engine/ros2/support_contact_runner_v161.py
127
+ src/devagent_physical_engine/ros2/support_contact_v161.py
124
128
  src/devagent_physical_engine/ros2/task_adapter.py
125
129
  src/devagent_physical_engine/ros2/task_visualization.py
126
130
  src/devagent_physical_engine/ros2/tf_probe.py
@@ -153,6 +157,7 @@ tests/test_evidence_trust_transport_v12.py
153
157
  tests/test_evidence_trust_v12.py
154
158
  tests/test_evidence_viewer_palette_v130.py
155
159
  tests/test_gazebo_cli_v0122.py
160
+ tests/test_golden_abb_showcase.py
156
161
  tests/test_interpreter_profiles_v08.py
157
162
  tests/test_joint_state_probe_v0125.py
158
163
  tests/test_live_provider_qualification.py
@@ -195,6 +200,7 @@ tests/test_selective_verification_v14.py
195
200
  tests/test_setup_profile.py
196
201
  tests/test_sim_real_qualification_v011.py
197
202
  tests/test_simulation_platform_v08.py
203
+ tests/test_support_contact_hotfix_v161.py
198
204
  tests/test_tool_collision_v011.py
199
205
  tests/test_tool_scene_v0124.py
200
206
  tests/test_trajectory_action_probe_v0125.py