devagent-physical-engine 1.8.4__tar.gz → 1.8.5__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 (253) hide show
  1. {devagent_physical_engine-1.8.4/src/devagent_physical_engine.egg-info → devagent_physical_engine-1.8.5}/PKG-INFO +14 -5
  2. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/README.md +13 -4
  3. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/pyproject.toml +1 -1
  4. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/__init__.py +1 -1
  5. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/workpiece_scene_probe.py +44 -1
  6. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5/src/devagent_physical_engine.egg-info}/PKG-INFO +14 -5
  7. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/SOURCES.txt +2 -1
  8. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_industrial_motion_v170.py +2 -2
  9. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_package_metadata_v184.py +2 -2
  10. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_transfer_place_diagnostic_v172.py +2 -2
  11. devagent_physical_engine-1.8.5/tests/test_workpiece_scene_probe_v185.py +52 -0
  12. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/NOTICE +0 -0
  13. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/setup.cfg +0 -0
  14. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/__init__.py +0 -0
  15. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/compiler.py +0 -0
  16. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/contracts.py +0 -0
  17. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/coordinator.py +0 -0
  18. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/critic.py +0 -0
  19. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/evidence.py +0 -0
  20. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/interpreter.py +0 -0
  21. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/planner.py +0 -0
  22. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/recovery.py +0 -0
  23. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/routing.py +0 -0
  24. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/runtime.py +0 -0
  25. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/semantic.py +0 -0
  26. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/agent/structured.py +0 -0
  27. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ai_cli.py +0 -0
  28. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/cli.py +0 -0
  29. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial.py +0 -0
  30. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_campaign.py +0 -0
  31. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_cli.py +0 -0
  32. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_importer.py +0 -0
  33. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_intelligence.py +0 -0
  34. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_readiness.py +0 -0
  35. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/commercial_repository.py +0 -0
  36. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/continuous_clearance.py +0 -0
  37. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/controller_runtime_hotfix_v181.py +0 -0
  38. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/doctor.py +0 -0
  39. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/engineering_agent.py +0 -0
  40. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/engineering_request.py +0 -0
  41. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/evidence_replay.py +0 -0
  42. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/evidence_trust.py +0 -0
  43. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/execution.py +0 -0
  44. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/industrial_motion_hotfix_v170.py +0 -0
  45. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/industrial_motion_v170.py +0 -0
  46. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/industrial_motion_v182.py +0 -0
  47. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/models.py +0 -0
  48. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/one_command.py +0 -0
  49. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/one_command_runtime.py +0 -0
  50. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/one_command_v15.py +0 -0
  51. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/one_command_v16.py +0 -0
  52. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/operating_envelope.py +0 -0
  53. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/__init__.py +0 -0
  54. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/benchmark.py +0 -0
  55. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/candidates.py +0 -0
  56. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/contracts.py +0 -0
  57. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/evaluator.py +0 -0
  58. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/evidence.py +0 -0
  59. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/experience.py +0 -0
  60. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/measured.py +0 -0
  61. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/optimizer.py +0 -0
  62. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/optimization/orchestrator.py +0 -0
  63. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/physical_campaign.py +0 -0
  64. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/physical_evidence.py +0 -0
  65. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/physical_motion.py +0 -0
  66. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/planning.py +0 -0
  67. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/pose_math.py +0 -0
  68. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/preexecution_contract.py +0 -0
  69. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/production_authority.py +0 -0
  70. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/production_grade.py +0 -0
  71. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/project.py +0 -0
  72. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/__init__.py +0 -0
  73. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/anthropic.py +0 -0
  74. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/common.py +0 -0
  75. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/factory.py +0 -0
  76. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/gemini.py +0 -0
  77. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_adapters/openai.py +0 -0
  78. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_criterion.py +0 -0
  79. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/provider_qualification.py +0 -0
  80. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/providers.py +0 -0
  81. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/qualification.py +0 -0
  82. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/qualification_cli.py +0 -0
  83. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/qualification_harness.py +0 -0
  84. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/reference_workcell.py +0 -0
  85. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/report_test_execution.py +0 -0
  86. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/report_test_execution_strict.py +0 -0
  87. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/robot_platform.py +0 -0
  88. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/robot_support_v18.py +0 -0
  89. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/robots.py +0 -0
  90. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/__init__.py +0 -0
  91. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/abb_irb1200.py +0 -0
  92. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/abb_irb1200_preview.py +0 -0
  93. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/acceptance.py +0 -0
  94. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/commands.py +0 -0
  95. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/continuous_clearance_probe.py +0 -0
  96. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/controller_action_probe.py +0 -0
  97. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/destination_support_contact_v182.py +0 -0
  98. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/doctor.py +0 -0
  99. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/fk_pose.py +0 -0
  100. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/fk_probe.py +0 -0
  101. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/frame_alignment.py +0 -0
  102. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/gazebo_cli.py +0 -0
  103. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/gazebo_pose.py +0 -0
  104. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/gazebo_world.py +0 -0
  105. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/industrial_sequence_planner_v170.py +0 -0
  106. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/industrial_sequence_planner_v171.py +0 -0
  107. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/industrial_sequence_planner_v172.py +0 -0
  108. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/industrial_sequence_planner_v182.py +0 -0
  109. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/joint_state_probe.py +0 -0
  110. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/joint_state_recorder.py +0 -0
  111. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/measured_motion.py +0 -0
  112. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/moveit_joint_plan_probe.py +0 -0
  113. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/moveit_joint_plan_v161_probe.py +0 -0
  114. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/moveit_scene.py +0 -0
  115. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/moveit_task_planner.py +0 -0
  116. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/pilz_sequence_plan_probe.py +0 -0
  117. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/pilz_sequence_plan_probe_v182.py +0 -0
  118. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/preexecution.py +0 -0
  119. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/qualification.py +0 -0
  120. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/qualification_v10.py +0 -0
  121. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/qualification_v11.py +0 -0
  122. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/qualification_v12.py +0 -0
  123. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/report_test_visualization.py +0 -0
  124. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/report_test_visualization_v170.py +0 -0
  125. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/scene_probe.py +0 -0
  126. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/state_validity_probe.py +0 -0
  127. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/support_contact_acm_probe_v170.py +0 -0
  128. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/support_contact_lease_v170.py +0 -0
  129. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/support_contact_runner_v161.py +0 -0
  130. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/support_contact_v161.py +0 -0
  131. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/task_adapter.py +0 -0
  132. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/task_visualization.py +0 -0
  133. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/tf_probe.py +0 -0
  134. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/tool_scene.py +0 -0
  135. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/tool_scene_probe.py +0 -0
  136. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/trajectory.py +0 -0
  137. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/trajectory_action_probe.py +0 -0
  138. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/trajectory_tracking.py +0 -0
  139. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/ur5e.py +0 -0
  140. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/ur5e_adapter.py +0 -0
  141. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/ur5e_v10_adapter.py +0 -0
  142. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/workpiece_follow.py +0 -0
  143. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/workpiece_gazebo_follower.py +0 -0
  144. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/ros2/workpiece_scene.py +0 -0
  145. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/selective_verification.py +0 -0
  146. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/selective_verification_v16.py +0 -0
  147. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/setup_profile.py +0 -0
  148. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/sim_real_qualification.py +0 -0
  149. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/simulation.py +0 -0
  150. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/simulation_platform.py +0 -0
  151. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/smooth_motion_hotfix_v162.py +0 -0
  152. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/support_contact_hotfix_v161.py +0 -0
  153. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/tool_collision.py +0 -0
  154. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/trajectory_qualification.py +0 -0
  155. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/twin.py +0 -0
  156. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/twin_builder.py +0 -0
  157. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/twin_codec.py +0 -0
  158. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/twin_materialization.py +0 -0
  159. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/user_cli.py +0 -0
  160. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/user_cli_v15.py +0 -0
  161. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/user_cli_v16.py +0 -0
  162. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/user_cli_v18.py +0 -0
  163. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/verification.py +0 -0
  164. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine/workpiece_lifecycle.py +0 -0
  165. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/dependency_links.txt +0 -0
  166. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/entry_points.txt +0 -0
  167. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/requires.txt +0 -0
  168. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/src/devagent_physical_engine.egg-info/top_level.txt +0 -0
  169. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_abb_irb1200_visual_v18.py +0 -0
  170. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_agent_core.py +0 -0
  171. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_agent_semantic_hardening.py +0 -0
  172. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_ai_cli.py +0 -0
  173. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_ai_cli_v07.py +0 -0
  174. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_commercial_importer_v1.py +0 -0
  175. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_commercial_intelligence_v15.py +0 -0
  176. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_commercial_readiness_v1.py +0 -0
  177. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_commercial_v1.py +0 -0
  178. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_continuous_clearance_v011.py +0 -0
  179. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_controller_runtime_hotfix_v181.py +0 -0
  180. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_core.py +0 -0
  181. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_destination_support_contact_v182.py +0 -0
  182. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_engineering_request_v07.py +0 -0
  183. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_evidence_replay_v12.py +0 -0
  184. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_evidence_trust_coverage_v12.py +0 -0
  185. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_evidence_trust_transport_v12.py +0 -0
  186. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_evidence_trust_v12.py +0 -0
  187. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_evidence_viewer_palette_v130.py +0 -0
  188. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_gazebo_cli_v0122.py +0 -0
  189. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_golden_abb_runner_v171.py +0 -0
  190. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_golden_abb_showcase.py +0 -0
  191. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_interpreter_profiles_v08.py +0 -0
  192. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_joint_state_probe_v0125.py +0 -0
  193. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_live_provider_qualification.py +0 -0
  194. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_measured_motion_v10.py +0 -0
  195. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_moveit_planning_diagnostics_v0125.py +0 -0
  196. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_moveit_scene_v0123.py +0 -0
  197. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_natural_language_agent_v07.py +0 -0
  198. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_one_command_hardening_v13.py +0 -0
  199. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_one_command_pose_hardening_v15.py +0 -0
  200. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_one_command_regression_v141.py +0 -0
  201. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_one_command_v13.py +0 -0
  202. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_openai_strict_schema_v0113.py +0 -0
  203. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_optimization_v05.py +0 -0
  204. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_physical_campaign_v09.py +0 -0
  205. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_physical_evidence_v09.py +0 -0
  206. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_physical_motion_v09.py +0 -0
  207. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_planning_fallback_v012.py +0 -0
  208. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_pose_math_v0125.py +0 -0
  209. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_preexecution_contract_v10.py +0 -0
  210. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_production_authority_v11.py +0 -0
  211. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_production_grade_coverage_v11.py +0 -0
  212. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_production_grade_v11.py +0 -0
  213. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_project_spine_v013.py +0 -0
  214. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_provider_and_qualification.py +0 -0
  215. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_provider_criterion_v15.py +0 -0
  216. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_qualification_cli_lifecycle_v06.py +0 -0
  217. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_qualification_harness_v06.py +0 -0
  218. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_readme_pypi.py +0 -0
  219. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_real_provider_adapters.py +0 -0
  220. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_reference_workcell_ros_frames_v0125.py +0 -0
  221. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_reference_workcell_v012.py +0 -0
  222. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_report_test_contract_coverage_v16.py +0 -0
  223. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_report_test_lineage_v16.py +0 -0
  224. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_report_test_visual_execution_v16.py +0 -0
  225. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_robot_platform_v08.py +0 -0
  226. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_ros2_production_receipts_v011.py +0 -0
  227. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_ros2_simulation.py +0 -0
  228. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_ros_trajectory_v09.py +0 -0
  229. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_selective_verification_v14.py +0 -0
  230. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_setup_profile.py +0 -0
  231. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_sim_real_qualification_v011.py +0 -0
  232. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_simulation_platform_v08.py +0 -0
  233. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_smooth_motion_hotfix_v162.py +0 -0
  234. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_support_contact_hotfix_v161.py +0 -0
  235. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_tool_collision_v011.py +0 -0
  236. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_tool_scene_v0124.py +0 -0
  237. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_trajectory_action_probe_v0125.py +0 -0
  238. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_trajectory_qualification_v09.py +0 -0
  239. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_trajectory_tracking_v0125.py +0 -0
  240. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_twin_materialization_v10.py +0 -0
  241. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_twin_v08.py +0 -0
  242. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_ur5e_adapter_scopes_v09.py +0 -0
  243. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_ur5e_v10_adapter_scopes.py +0 -0
  244. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_user_cli_interactive_v131.py +0 -0
  245. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_user_cli_progress_v131.py +0 -0
  246. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_user_cli_report_visual_v16.py +0 -0
  247. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_user_cli_selective_v14.py +0 -0
  248. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_user_cli_v15.py +0 -0
  249. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_user_cli_v15_hotfix_inheritance.py +0 -0
  250. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_v052_stabilization.py +0 -0
  251. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_v08_catalog_mapping_regression.py +0 -0
  252. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/tests/test_workpiece_attach_semantics_v183.py +0 -0
  253. {devagent_physical_engine-1.8.4 → devagent_physical_engine-1.8.5}/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.8.4
3
+ Version: 1.8.5
4
4
  Summary: Verification-first robotics commissioning runtime with exact-Twin evidence, qualified UR5e Gazebo/MoveIt report execution, truthful robot support tiers, selective verification, replay, regression, and FAT reporting.
5
5
  Author: Tom Ha
6
6
  License: All Rights Reserved
@@ -76,7 +76,7 @@ regression + FAT report + Evidence Viewer
76
76
  Python 3.11+ is required.
77
77
 
78
78
  ```bash
79
- python -m pip install --upgrade devagent-physical-engine==1.8.4
79
+ python -m pip install --upgrade devagent-physical-engine==1.8.5
80
80
  ```
81
81
 
82
82
  Verify the installed package:
@@ -88,7 +88,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
88
88
  Expected:
89
89
 
90
90
  ```text
91
- 1.8.4
91
+ 1.8.5
92
92
  ```
93
93
 
94
94
  Run the normal customer workflow:
@@ -418,6 +418,14 @@ v1.8.4 carries the exact v1.8.3 runtime semantics and shortens only the package
418
418
 
419
419
  This metadata hotfix does not change the UR5e attach/detach lifecycle, collision policy, motion planning, Twin lineage, site-qualification boundary, or real-execution authority.
420
420
 
421
+ ## v1.8.5 quaternion-invariant verified workpiece attach
422
+
423
+ A clean v1.8.4 UR5e target-stack run proved that synchronous `/apply_planning_scene` attachment now succeeds, world/attached state reaches strict read-back, and the remaining GRASP blocker is `workpiece_attachment_hash_mismatch`.
424
+
425
+ MoveIt round-trips attached-object rotations through Eigen. Unit quaternions `q` and `-q` represent the same physical rotation, but a raw component hash treats those two equivalent representations as different. v1.8.5 canonicalizes equivalent quaternion signs before workpiece attachment hashing using the same deterministic positive-`w` / first-nonzero-component rule already used by the qualified tool-scene path.
426
+
427
+ Verification remains strict for attachment identity, link, geometry contract, position, and physical rotation. This is not a tolerance-based PASS and does not change target geometry, TCP, collision policy, planner types, motion speeds, controller binding, Twin lineage, site qualification, or real-execution authority. If a hash mismatch remains, DevAgent records expected and observed hashes plus canonical expected/object/primitive/effective attachment poses for target diagnosis.
428
+
421
429
  ## Qualified visual-execution scope
422
430
 
423
431
  Measured report-test execution remains intentionally narrow:
@@ -618,9 +626,9 @@ devagent-physical-ai optional provider-backed engineering front end
618
626
 
619
627
  # Project status
620
628
 
621
- **v1.8.4 — Production/Stable software workflow**
629
+ **v1.8.5 — Production/Stable software workflow**
622
630
 
623
- v1.8.4 retains the v1.8.3 synchronous verified workpiece-attach fix, the v1.8.2 scoped destination-support place contract, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and ABB IRB1200 experimental visual runtime. The only v1.8.4 behavior change is packaging metadata compliance for PyPI; physical runtime semantics are unchanged from v1.8.3.
631
+ v1.8.5 retains v1.8.4 PyPI metadata compliance, v1.8.3 synchronous service-safe workpiece attachment, v1.8.2 scoped destination-support place contact, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and the ABB IRB1200 experimental visual runtime. It makes strict workpiece attachment verification invariant to the mathematically equivalent quaternion representations `q` and `-q` and persists exact pose/hash diagnostics for any remaining mismatch.
624
632
 
625
633
  Production-oriented software capabilities include:
626
634
 
@@ -636,6 +644,7 @@ truthful robot support tiers
636
644
  qualified UR5e report-test visual execution contract
637
645
  direct UR5e controller-manager/action readiness binding
638
646
  synchronous verified workpiece attach/detach lifecycle
647
+ quaternion-invariant strict attachment hashing
639
648
  scoped destination-support place contact
640
649
  experimental exact ABB IRB1200 Gazebo/MoveIt/RViz preview
641
650
  industrial Pilz PTP / LIN planning
@@ -35,7 +35,7 @@ regression + FAT report + Evidence Viewer
35
35
  Python 3.11+ is required.
36
36
 
37
37
  ```bash
38
- python -m pip install --upgrade devagent-physical-engine==1.8.4
38
+ python -m pip install --upgrade devagent-physical-engine==1.8.5
39
39
  ```
40
40
 
41
41
  Verify the installed package:
@@ -47,7 +47,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
47
47
  Expected:
48
48
 
49
49
  ```text
50
- 1.8.4
50
+ 1.8.5
51
51
  ```
52
52
 
53
53
  Run the normal customer workflow:
@@ -377,6 +377,14 @@ v1.8.4 carries the exact v1.8.3 runtime semantics and shortens only the package
377
377
 
378
378
  This metadata hotfix does not change the UR5e attach/detach lifecycle, collision policy, motion planning, Twin lineage, site-qualification boundary, or real-execution authority.
379
379
 
380
+ ## v1.8.5 quaternion-invariant verified workpiece attach
381
+
382
+ A clean v1.8.4 UR5e target-stack run proved that synchronous `/apply_planning_scene` attachment now succeeds, world/attached state reaches strict read-back, and the remaining GRASP blocker is `workpiece_attachment_hash_mismatch`.
383
+
384
+ MoveIt round-trips attached-object rotations through Eigen. Unit quaternions `q` and `-q` represent the same physical rotation, but a raw component hash treats those two equivalent representations as different. v1.8.5 canonicalizes equivalent quaternion signs before workpiece attachment hashing using the same deterministic positive-`w` / first-nonzero-component rule already used by the qualified tool-scene path.
385
+
386
+ Verification remains strict for attachment identity, link, geometry contract, position, and physical rotation. This is not a tolerance-based PASS and does not change target geometry, TCP, collision policy, planner types, motion speeds, controller binding, Twin lineage, site qualification, or real-execution authority. If a hash mismatch remains, DevAgent records expected and observed hashes plus canonical expected/object/primitive/effective attachment poses for target diagnosis.
387
+
380
388
  ## Qualified visual-execution scope
381
389
 
382
390
  Measured report-test execution remains intentionally narrow:
@@ -577,9 +585,9 @@ devagent-physical-ai optional provider-backed engineering front end
577
585
 
578
586
  # Project status
579
587
 
580
- **v1.8.4 — Production/Stable software workflow**
588
+ **v1.8.5 — Production/Stable software workflow**
581
589
 
582
- v1.8.4 retains the v1.8.3 synchronous verified workpiece-attach fix, the v1.8.2 scoped destination-support place contract, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and ABB IRB1200 experimental visual runtime. The only v1.8.4 behavior change is packaging metadata compliance for PyPI; physical runtime semantics are unchanged from v1.8.3.
590
+ v1.8.5 retains v1.8.4 PyPI metadata compliance, v1.8.3 synchronous service-safe workpiece attachment, v1.8.2 scoped destination-support place contact, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and the ABB IRB1200 experimental visual runtime. It makes strict workpiece attachment verification invariant to the mathematically equivalent quaternion representations `q` and `-q` and persists exact pose/hash diagnostics for any remaining mismatch.
583
591
 
584
592
  Production-oriented software capabilities include:
585
593
 
@@ -595,6 +603,7 @@ truthful robot support tiers
595
603
  qualified UR5e report-test visual execution contract
596
604
  direct UR5e controller-manager/action readiness binding
597
605
  synchronous verified workpiece attach/detach lifecycle
606
+ quaternion-invariant strict attachment hashing
598
607
  scoped destination-support place contact
599
608
  experimental exact ABB IRB1200 Gazebo/MoveIt/RViz preview
600
609
  industrial Pilz PTP / LIN planning
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devagent-physical-engine"
7
- version = "1.8.4"
7
+ version = "1.8.5"
8
8
  description = "Verification-first robotics commissioning runtime with exact-Twin evidence, qualified UR5e Gazebo/MoveIt report execution, truthful robot support tiers, selective verification, replay, regression, and FAT reporting."
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.11"
@@ -219,4 +219,4 @@ install_industrial_motion_v170()
219
219
  install_controller_runtime_hotfix_v181()
220
220
  install_one_command_runtime()
221
221
 
222
- __version__ = "1.8.4"
222
+ __version__ = "1.8.5"
@@ -26,6 +26,24 @@ def _qnorm(q):
26
26
  return tuple(float(value) / norm for value in q)
27
27
 
28
28
 
29
+ def _qcanonical(q):
30
+ """Canonicalize equivalent q/-q rotations to one deterministic form."""
31
+
32
+ quaternion = _qnorm(q)
33
+ # A quaternion and its negation represent the same physical rotation. MoveIt
34
+ # round-trips poses through Eigen, which may legitimately return the opposite
35
+ # quaternion sign. Hash the rotation, not an arbitrary representation of it.
36
+ # Prefer positive w; for exact 180-degree rotations use the first non-zero xyz
37
+ # component as the deterministic sign discriminator.
38
+ for component in (quaternion[3], quaternion[0], quaternion[1], quaternion[2]):
39
+ if abs(component) <= 1e-15:
40
+ continue
41
+ if component < 0.0:
42
+ quaternion = tuple(-value for value in quaternion)
43
+ break
44
+ return tuple(_canon_float(value) for value in quaternion)
45
+
46
+
29
47
  def _qmul(first, second):
30
48
  ax, ay, az, aw = first
31
49
  bx, by, bz, bw = second
@@ -69,6 +87,13 @@ def _pose_from_msg(pose):
69
87
  )
70
88
 
71
89
 
90
+ def _pose_payload(position, quaternion) -> dict[str, list[float]]:
91
+ return {
92
+ "position_m": [_canon_float(value) for value in position],
93
+ "quaternion_xyzw": list(_qcanonical(quaternion)),
94
+ }
95
+
96
+
72
97
  def _pose_to_msg(position, quaternion, Pose):
73
98
  pose = Pose()
74
99
  pose.position.x, pose.position.y, pose.position.z = (float(value) for value in position)
@@ -90,7 +115,7 @@ def _canonical_attachment(
90
115
  "geometry_kind": str(item["geometry_kind"]),
91
116
  "dimensions_m": [_canon_float(value) for value in item["dimensions_m"]],
92
117
  "position_m": [_canon_float(value) for value in position],
93
- "quaternion_xyzw": [_canon_float(value) for value in _qnorm(quaternion)],
118
+ "quaternion_xyzw": list(_qcanonical(quaternion)),
94
119
  }
95
120
 
96
121
 
@@ -224,6 +249,7 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
224
249
  scene.is_diff = True
225
250
  scene.robot_state.is_diff = True
226
251
  attachment_hash = None
252
+ expected_attachment_pose = None
227
253
 
228
254
  if operation == "attach":
229
255
  transform = _lookup_transform(
@@ -279,6 +305,10 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
279
305
  relative_quaternion,
280
306
  )
281
307
  attachment_hash = _hash(expected_attachment)
308
+ expected_attachment_pose = _pose_payload(
309
+ relative_position,
310
+ relative_quaternion,
311
+ )
282
312
  elif operation == "detach":
283
313
  attached = AttachedCollisionObject()
284
314
  attached.link_name = tool_link
@@ -361,6 +391,18 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
361
391
  "code": "workpiece_attachment_hash_mismatch",
362
392
  "observed_world_present": world_present,
363
393
  "observed_attached_link": observed_attached_link,
394
+ "expected_attachment_hash": attachment_hash,
395
+ "observed_attachment_hash": observed_attachment_hash,
396
+ "expected_attachment_pose": expected_attachment_pose,
397
+ "observed_object_pose": _pose_payload(object_position, object_q),
398
+ "observed_primitive_pose": _pose_payload(
399
+ primitive_position,
400
+ primitive_q,
401
+ ),
402
+ "observed_attachment_pose": _pose_payload(
403
+ observed_position,
404
+ observed_q,
405
+ ),
364
406
  }
365
407
  return {
366
408
  "success": True,
@@ -370,6 +412,7 @@ def transition(path: Path, *, operation: str, timeout_s: float) -> dict[str, Any
370
412
  "observed_world_present": False,
371
413
  "observed_attached_link": tool_link,
372
414
  "attachment_hash": attachment_hash,
415
+ "attachment_pose": expected_attachment_pose,
373
416
  }
374
417
 
375
418
  success = world_present and not attached_items
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devagent-physical-engine
3
- Version: 1.8.4
3
+ Version: 1.8.5
4
4
  Summary: Verification-first robotics commissioning runtime with exact-Twin evidence, qualified UR5e Gazebo/MoveIt report execution, truthful robot support tiers, selective verification, replay, regression, and FAT reporting.
5
5
  Author: Tom Ha
6
6
  License: All Rights Reserved
@@ -76,7 +76,7 @@ regression + FAT report + Evidence Viewer
76
76
  Python 3.11+ is required.
77
77
 
78
78
  ```bash
79
- python -m pip install --upgrade devagent-physical-engine==1.8.4
79
+ python -m pip install --upgrade devagent-physical-engine==1.8.5
80
80
  ```
81
81
 
82
82
  Verify the installed package:
@@ -88,7 +88,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
88
88
  Expected:
89
89
 
90
90
  ```text
91
- 1.8.4
91
+ 1.8.5
92
92
  ```
93
93
 
94
94
  Run the normal customer workflow:
@@ -418,6 +418,14 @@ v1.8.4 carries the exact v1.8.3 runtime semantics and shortens only the package
418
418
 
419
419
  This metadata hotfix does not change the UR5e attach/detach lifecycle, collision policy, motion planning, Twin lineage, site-qualification boundary, or real-execution authority.
420
420
 
421
+ ## v1.8.5 quaternion-invariant verified workpiece attach
422
+
423
+ A clean v1.8.4 UR5e target-stack run proved that synchronous `/apply_planning_scene` attachment now succeeds, world/attached state reaches strict read-back, and the remaining GRASP blocker is `workpiece_attachment_hash_mismatch`.
424
+
425
+ MoveIt round-trips attached-object rotations through Eigen. Unit quaternions `q` and `-q` represent the same physical rotation, but a raw component hash treats those two equivalent representations as different. v1.8.5 canonicalizes equivalent quaternion signs before workpiece attachment hashing using the same deterministic positive-`w` / first-nonzero-component rule already used by the qualified tool-scene path.
426
+
427
+ Verification remains strict for attachment identity, link, geometry contract, position, and physical rotation. This is not a tolerance-based PASS and does not change target geometry, TCP, collision policy, planner types, motion speeds, controller binding, Twin lineage, site qualification, or real-execution authority. If a hash mismatch remains, DevAgent records expected and observed hashes plus canonical expected/object/primitive/effective attachment poses for target diagnosis.
428
+
421
429
  ## Qualified visual-execution scope
422
430
 
423
431
  Measured report-test execution remains intentionally narrow:
@@ -618,9 +626,9 @@ devagent-physical-ai optional provider-backed engineering front end
618
626
 
619
627
  # Project status
620
628
 
621
- **v1.8.4 — Production/Stable software workflow**
629
+ **v1.8.5 — Production/Stable software workflow**
622
630
 
623
- v1.8.4 retains the v1.8.3 synchronous verified workpiece-attach fix, the v1.8.2 scoped destination-support place contract, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and ABB IRB1200 experimental visual runtime. The only v1.8.4 behavior change is packaging metadata compliance for PyPI; physical runtime semantics are unchanged from v1.8.3.
631
+ v1.8.5 retains v1.8.4 PyPI metadata compliance, v1.8.3 synchronous service-safe workpiece attachment, v1.8.2 scoped destination-support place contact, v1.8.1 direct UR5e controller/action binding, truthful robot support tiers, and the ABB IRB1200 experimental visual runtime. It makes strict workpiece attachment verification invariant to the mathematically equivalent quaternion representations `q` and `-q` and persists exact pose/hash diagnostics for any remaining mismatch.
624
632
 
625
633
  Production-oriented software capabilities include:
626
634
 
@@ -636,6 +644,7 @@ truthful robot support tiers
636
644
  qualified UR5e report-test visual execution contract
637
645
  direct UR5e controller-manager/action readiness binding
638
646
  synchronous verified workpiece attach/detach lifecycle
647
+ quaternion-invariant strict attachment hashing
639
648
  scoped destination-support place contact
640
649
  experimental exact ABB IRB1200 Gazebo/MoveIt/RViz preview
641
650
  industrial Pilz PTP / LIN planning
@@ -247,4 +247,5 @@ tests/test_user_cli_v15_hotfix_inheritance.py
247
247
  tests/test_v052_stabilization.py
248
248
  tests/test_v08_catalog_mapping_regression.py
249
249
  tests/test_workpiece_attach_semantics_v183.py
250
- tests/test_workpiece_lifecycle_v011.py
250
+ tests/test_workpiece_lifecycle_v011.py
251
+ tests/test_workpiece_scene_probe_v185.py
@@ -34,8 +34,8 @@ from devagent_physical_engine.ros2.report_test_visualization_v170 import (
34
34
 
35
35
 
36
36
  class IndustrialMotionV170Tests(unittest.TestCase):
37
- def test_release_version_is_v184(self) -> None:
38
- self.assertEqual(package.__version__, "1.8.4")
37
+ def test_release_version_is_v185(self) -> None:
38
+ self.assertEqual(package.__version__, "1.8.5")
39
39
 
40
40
  def test_reference_groups_cover_every_task_phase_once_in_order(self) -> None:
41
41
  groups = reference_industrial_groups()
@@ -13,10 +13,10 @@ class PackageMetadataV184Tests(unittest.TestCase):
13
13
  self.assertTrue(summary.strip())
14
14
  self.assertLessEqual(len(summary), 512)
15
15
 
16
- def test_package_version_is_v184(self) -> None:
16
+ def test_package_version_is_v185(self) -> None:
17
17
  root = Path(__file__).resolve().parents[1]
18
18
  metadata = tomllib.loads((root / "pyproject.toml").read_text(encoding="utf-8"))
19
- self.assertEqual(metadata["project"]["version"], "1.8.4")
19
+ self.assertEqual(metadata["project"]["version"], "1.8.5")
20
20
 
21
21
 
22
22
  if __name__ == "__main__":
@@ -153,8 +153,8 @@ class TransferPlaceDiagnosticV172Tests(unittest.TestCase):
153
153
  self.assertTrue(payload["plan_only"])
154
154
  self.assertEqual(payload["result_code"], "pilz_place_segment_planning_failed")
155
155
 
156
- def test_v184_release_preserves_v172_diagnostics_and_v182_planner(self) -> None:
157
- self.assertEqual(package.__version__, "1.8.4")
156
+ def test_v185_release_preserves_v172_diagnostics_and_v182_planner(self) -> None:
157
+ self.assertEqual(package.__version__, "1.8.5")
158
158
  self.assertTrue(
159
159
  issubclass(PilzIndustrialSequencePlannerV182, PilzIndustrialSequencePlannerV172)
160
160
  )
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+
3
+ import unittest
4
+
5
+ from devagent_physical_engine.ros2.workpiece_scene_probe import (
6
+ _canonical_attachment,
7
+ _hash,
8
+ _pose_payload,
9
+ _qcanonical,
10
+ )
11
+
12
+
13
+ class WorkpieceSceneProbeV185Tests(unittest.TestCase):
14
+ def setUp(self) -> None:
15
+ self.item = {
16
+ "id": "devagent_box_101_test",
17
+ "geometry_kind": "box",
18
+ "dimensions_m": [0.1, 0.08, 0.06],
19
+ }
20
+ self.position = (0.03125, -0.125, 0.07)
21
+
22
+ def test_equivalent_quaternion_signs_have_identical_canonical_form(self) -> None:
23
+ q = (0.2, -0.3, 0.4, -0.5)
24
+ negated = tuple(-value for value in q)
25
+ self.assertEqual(_qcanonical(q), _qcanonical(negated))
26
+
27
+ def test_equivalent_quaternion_signs_have_identical_attachment_hash(self) -> None:
28
+ q = (0.2, -0.3, 0.4, -0.5)
29
+ negated = tuple(-value for value in q)
30
+ first = _hash(
31
+ _canonical_attachment("tool0", self.item, self.position, q)
32
+ )
33
+ second = _hash(
34
+ _canonical_attachment("tool0", self.item, self.position, negated)
35
+ )
36
+ self.assertEqual(first, second)
37
+
38
+ def test_exact_180_degree_rotation_is_sign_invariant(self) -> None:
39
+ q = (-1.0, 0.0, 0.0, 0.0)
40
+ self.assertEqual(_qcanonical(q), (1.0, 0.0, 0.0, 0.0))
41
+ self.assertEqual(_qcanonical(q), _qcanonical(tuple(-value for value in q)))
42
+
43
+ def test_pose_payload_is_quaternion_sign_invariant(self) -> None:
44
+ q = (0.0, 0.7071067811865476, 0.0, -0.7071067811865476)
45
+ self.assertEqual(
46
+ _pose_payload(self.position, q),
47
+ _pose_payload(self.position, tuple(-value for value in q)),
48
+ )
49
+
50
+
51
+ if __name__ == "__main__":
52
+ unittest.main()