devagent-physical-engine 1.4.0__tar.gz → 1.4.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 (197) hide show
  1. {devagent_physical_engine-1.4.0/src/devagent_physical_engine.egg-info → devagent_physical_engine-1.4.1}/PKG-INFO +6 -6
  2. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/README.md +5 -5
  3. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/pyproject.toml +2 -2
  4. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/__init__.py +4 -1
  5. devagent_physical_engine-1.4.1/src/devagent_physical_engine/one_command_runtime.py +114 -0
  6. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1/src/devagent_physical_engine.egg-info}/PKG-INFO +6 -6
  7. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine.egg-info/SOURCES.txt +2 -0
  8. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine.egg-info/entry_points.txt +1 -1
  9. devagent_physical_engine-1.4.1/tests/test_one_command_regression_v141.py +141 -0
  10. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/NOTICE +0 -0
  11. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/setup.cfg +0 -0
  12. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/__init__.py +0 -0
  13. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/compiler.py +0 -0
  14. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/contracts.py +0 -0
  15. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/coordinator.py +0 -0
  16. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/critic.py +0 -0
  17. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/evidence.py +0 -0
  18. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/interpreter.py +0 -0
  19. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/planner.py +0 -0
  20. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/recovery.py +0 -0
  21. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/routing.py +0 -0
  22. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/runtime.py +0 -0
  23. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/semantic.py +0 -0
  24. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/agent/structured.py +0 -0
  25. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ai_cli.py +0 -0
  26. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/cli.py +0 -0
  27. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/commercial.py +0 -0
  28. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/commercial_campaign.py +0 -0
  29. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/commercial_cli.py +0 -0
  30. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/commercial_importer.py +0 -0
  31. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/commercial_readiness.py +0 -0
  32. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/commercial_repository.py +0 -0
  33. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/continuous_clearance.py +0 -0
  34. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/doctor.py +0 -0
  35. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/engineering_agent.py +0 -0
  36. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/engineering_request.py +0 -0
  37. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/evidence_replay.py +0 -0
  38. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/evidence_trust.py +0 -0
  39. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/execution.py +0 -0
  40. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/models.py +0 -0
  41. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/one_command.py +0 -0
  42. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/operating_envelope.py +0 -0
  43. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/__init__.py +0 -0
  44. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/benchmark.py +0 -0
  45. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/candidates.py +0 -0
  46. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/contracts.py +0 -0
  47. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/evaluator.py +0 -0
  48. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/evidence.py +0 -0
  49. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/experience.py +0 -0
  50. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/measured.py +0 -0
  51. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/optimizer.py +0 -0
  52. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/optimization/orchestrator.py +0 -0
  53. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/physical_campaign.py +0 -0
  54. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/physical_evidence.py +0 -0
  55. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/physical_motion.py +0 -0
  56. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/planning.py +0 -0
  57. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/pose_math.py +0 -0
  58. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/preexecution_contract.py +0 -0
  59. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/production_authority.py +0 -0
  60. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/production_grade.py +0 -0
  61. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/project.py +0 -0
  62. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/provider_adapters/__init__.py +0 -0
  63. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/provider_adapters/anthropic.py +0 -0
  64. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/provider_adapters/common.py +0 -0
  65. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/provider_adapters/factory.py +0 -0
  66. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/provider_adapters/gemini.py +0 -0
  67. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/provider_adapters/openai.py +0 -0
  68. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/provider_qualification.py +0 -0
  69. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/providers.py +0 -0
  70. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/qualification.py +0 -0
  71. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/qualification_cli.py +0 -0
  72. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/qualification_harness.py +0 -0
  73. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/reference_workcell.py +0 -0
  74. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/robot_platform.py +0 -0
  75. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/robots.py +0 -0
  76. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/__init__.py +0 -0
  77. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/acceptance.py +0 -0
  78. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/commands.py +0 -0
  79. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/continuous_clearance_probe.py +0 -0
  80. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/doctor.py +0 -0
  81. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/fk_pose.py +0 -0
  82. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/fk_probe.py +0 -0
  83. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/frame_alignment.py +0 -0
  84. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/gazebo_cli.py +0 -0
  85. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/gazebo_pose.py +0 -0
  86. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/gazebo_world.py +0 -0
  87. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/joint_state_probe.py +0 -0
  88. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/joint_state_recorder.py +0 -0
  89. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/measured_motion.py +0 -0
  90. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/moveit_joint_plan_probe.py +0 -0
  91. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/moveit_scene.py +0 -0
  92. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/moveit_task_planner.py +0 -0
  93. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/preexecution.py +0 -0
  94. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/qualification.py +0 -0
  95. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/qualification_v10.py +0 -0
  96. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/qualification_v11.py +0 -0
  97. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/qualification_v12.py +0 -0
  98. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/scene_probe.py +0 -0
  99. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/state_validity_probe.py +0 -0
  100. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/task_adapter.py +0 -0
  101. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/task_visualization.py +0 -0
  102. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/tf_probe.py +0 -0
  103. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/tool_scene.py +0 -0
  104. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/tool_scene_probe.py +0 -0
  105. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/trajectory.py +0 -0
  106. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/trajectory_action_probe.py +0 -0
  107. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/trajectory_tracking.py +0 -0
  108. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/ur5e.py +0 -0
  109. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/ur5e_adapter.py +0 -0
  110. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/ur5e_v10_adapter.py +0 -0
  111. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/workpiece_follow.py +0 -0
  112. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/workpiece_gazebo_follower.py +0 -0
  113. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/workpiece_scene.py +0 -0
  114. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/ros2/workpiece_scene_probe.py +0 -0
  115. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/selective_verification.py +0 -0
  116. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/setup_profile.py +0 -0
  117. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/sim_real_qualification.py +0 -0
  118. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/simulation.py +0 -0
  119. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/simulation_platform.py +0 -0
  120. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/tool_collision.py +0 -0
  121. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/trajectory_qualification.py +0 -0
  122. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/twin.py +0 -0
  123. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/twin_builder.py +0 -0
  124. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/twin_materialization.py +0 -0
  125. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/user_cli.py +0 -0
  126. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/verification.py +0 -0
  127. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine/workpiece_lifecycle.py +0 -0
  128. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine.egg-info/dependency_links.txt +0 -0
  129. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine.egg-info/requires.txt +0 -0
  130. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/src/devagent_physical_engine.egg-info/top_level.txt +0 -0
  131. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_agent_core.py +0 -0
  132. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_agent_semantic_hardening.py +0 -0
  133. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_ai_cli.py +0 -0
  134. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_ai_cli_v07.py +0 -0
  135. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_commercial_importer_v1.py +0 -0
  136. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_commercial_readiness_v1.py +0 -0
  137. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_commercial_v1.py +0 -0
  138. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_continuous_clearance_v011.py +0 -0
  139. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_core.py +0 -0
  140. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_engineering_request_v07.py +0 -0
  141. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_evidence_replay_v12.py +0 -0
  142. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_evidence_trust_coverage_v12.py +0 -0
  143. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_evidence_trust_transport_v12.py +0 -0
  144. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_evidence_trust_v12.py +0 -0
  145. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_evidence_viewer_palette_v130.py +0 -0
  146. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_gazebo_cli_v0122.py +0 -0
  147. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_interpreter_profiles_v08.py +0 -0
  148. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_joint_state_probe_v0125.py +0 -0
  149. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_live_provider_qualification.py +0 -0
  150. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_measured_motion_v10.py +0 -0
  151. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_moveit_planning_diagnostics_v0125.py +0 -0
  152. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_moveit_scene_v0123.py +0 -0
  153. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_natural_language_agent_v07.py +0 -0
  154. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_one_command_hardening_v13.py +0 -0
  155. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_one_command_v13.py +0 -0
  156. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_openai_strict_schema_v0113.py +0 -0
  157. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_optimization_v05.py +0 -0
  158. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_physical_campaign_v09.py +0 -0
  159. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_physical_evidence_v09.py +0 -0
  160. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_physical_motion_v09.py +0 -0
  161. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_planning_fallback_v012.py +0 -0
  162. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_pose_math_v0125.py +0 -0
  163. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_preexecution_contract_v10.py +0 -0
  164. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_production_authority_v11.py +0 -0
  165. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_production_grade_coverage_v11.py +0 -0
  166. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_production_grade_v11.py +0 -0
  167. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_project_spine_v013.py +0 -0
  168. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_provider_and_qualification.py +0 -0
  169. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_qualification_cli_lifecycle_v06.py +0 -0
  170. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_qualification_harness_v06.py +0 -0
  171. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_readme_pypi.py +0 -0
  172. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_real_provider_adapters.py +0 -0
  173. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_reference_workcell_ros_frames_v0125.py +0 -0
  174. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_reference_workcell_v012.py +0 -0
  175. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_robot_platform_v08.py +0 -0
  176. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_ros2_production_receipts_v011.py +0 -0
  177. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_ros2_simulation.py +0 -0
  178. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_ros_trajectory_v09.py +0 -0
  179. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_selective_verification_v14.py +0 -0
  180. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_setup_profile.py +0 -0
  181. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_sim_real_qualification_v011.py +0 -0
  182. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_simulation_platform_v08.py +0 -0
  183. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_tool_collision_v011.py +0 -0
  184. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_tool_scene_v0124.py +0 -0
  185. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_trajectory_action_probe_v0125.py +0 -0
  186. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_trajectory_qualification_v09.py +0 -0
  187. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_trajectory_tracking_v0125.py +0 -0
  188. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_twin_materialization_v10.py +0 -0
  189. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_twin_v08.py +0 -0
  190. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_ur5e_adapter_scopes_v09.py +0 -0
  191. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_ur5e_v10_adapter_scopes.py +0 -0
  192. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_user_cli_interactive_v131.py +0 -0
  193. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_user_cli_progress_v131.py +0 -0
  194. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_user_cli_selective_v14.py +0 -0
  195. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_v052_stabilization.py +0 -0
  196. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.1}/tests/test_v08_catalog_mapping_regression.py +0 -0
  197. {devagent_physical_engine-1.4.0 → devagent_physical_engine-1.4.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.4.0
3
+ Version: 1.4.1
4
4
  Summary: Production-grade verification-first robotics evidence runtime with one-command customer intake, selective verification execution, deterministic Twin lineage, measured physical verification, replay inspection, regression, and FAT evidence.
5
5
  Author: Tom Ha
6
6
  License: All Rights Reserved
@@ -80,7 +80,7 @@ DevAgent is designed to answer: **What can be proven about this cell, what faile
80
80
  Python 3.11+ is required.
81
81
 
82
82
  ```bash
83
- python -m pip install --upgrade devagent-physical-engine==1.4.0
83
+ python -m pip install --upgrade devagent-physical-engine==1.4.1
84
84
  ```
85
85
 
86
86
  Verify the package:
@@ -92,7 +92,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
92
92
  Expected:
93
93
 
94
94
  ```text
95
- 1.4.0
95
+ 1.4.1
96
96
  ```
97
97
 
98
98
  Run the normal customer workflow:
@@ -720,9 +720,9 @@ Existing certified controllers execute.
720
720
 
721
721
  # Project status
722
722
 
723
- **v1.4.0 — Production/Stable software workflow**
723
+ **v1.4.1 — Production/Stable software workflow**
724
724
 
725
- v1.4.0 adds selective verification execution while preserving the existing fail-closed authority model.
725
+ v1.4.1 preserves v1.4 selective verification and fixes repeated full `devagent verify` runs by automatically binding exact previous-campaign current-campaign regression evidence before FAT generation. The original FAT regression scope validation remains authoritative and fail-closed.
726
726
 
727
727
  Production-oriented software capabilities include:
728
728
 
@@ -745,7 +745,7 @@ change impact + regression
745
745
  provider-neutral optional AI front end
746
746
  ```
747
747
 
748
- Quality gates include Python 3.11/3.12/3.13 regression, package clean-install, dependency audit, global branch coverage, One-Command coverage, **Selective Verification coverage**, Production Authority coverage, and Evidence Trust/Replay coverage.
748
+ Quality gates include Python 3.11/3.12/3.13 regression, package clean-install, dependency audit, global branch coverage, One-Command coverage, repeat-run regression qualification, **Selective Verification coverage**, Production Authority coverage, and Evidence Trust/Replay coverage.
749
749
 
750
750
  Production/Stable describes the bounded software workflow. It does not claim arbitrary customer cells are physically qualified, site-qualified, or safe for autonomous real execution.
751
751
 
@@ -39,7 +39,7 @@ DevAgent is designed to answer: **What can be proven about this cell, what faile
39
39
  Python 3.11+ is required.
40
40
 
41
41
  ```bash
42
- python -m pip install --upgrade devagent-physical-engine==1.4.0
42
+ python -m pip install --upgrade devagent-physical-engine==1.4.1
43
43
  ```
44
44
 
45
45
  Verify the package:
@@ -51,7 +51,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
51
51
  Expected:
52
52
 
53
53
  ```text
54
- 1.4.0
54
+ 1.4.1
55
55
  ```
56
56
 
57
57
  Run the normal customer workflow:
@@ -679,9 +679,9 @@ Existing certified controllers execute.
679
679
 
680
680
  # Project status
681
681
 
682
- **v1.4.0 — Production/Stable software workflow**
682
+ **v1.4.1 — Production/Stable software workflow**
683
683
 
684
- v1.4.0 adds selective verification execution while preserving the existing fail-closed authority model.
684
+ v1.4.1 preserves v1.4 selective verification and fixes repeated full `devagent verify` runs by automatically binding exact previous-campaign current-campaign regression evidence before FAT generation. The original FAT regression scope validation remains authoritative and fail-closed.
685
685
 
686
686
  Production-oriented software capabilities include:
687
687
 
@@ -704,7 +704,7 @@ change impact + regression
704
704
  provider-neutral optional AI front end
705
705
  ```
706
706
 
707
- Quality gates include Python 3.11/3.12/3.13 regression, package clean-install, dependency audit, global branch coverage, One-Command coverage, **Selective Verification coverage**, Production Authority coverage, and Evidence Trust/Replay coverage.
707
+ Quality gates include Python 3.11/3.12/3.13 regression, package clean-install, dependency audit, global branch coverage, One-Command coverage, repeat-run regression qualification, **Selective Verification coverage**, Production Authority coverage, and Evidence Trust/Replay coverage.
708
708
 
709
709
  Production/Stable describes the bounded software workflow. It does not claim arbitrary customer cells are physically qualified, site-qualified, or safe for autonomous real execution.
710
710
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devagent-physical-engine"
7
- version = "1.4.0"
7
+ version = "1.4.1"
8
8
  description = "Production-grade verification-first robotics evidence runtime with one-command customer intake, selective verification execution, 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"
@@ -47,7 +47,7 @@ Repository = "https://github.com/tomha85/devagent-physical-engine"
47
47
  Issues = "https://github.com/tomha85/devagent-physical-engine/issues"
48
48
 
49
49
  [project.scripts]
50
- devagent = "devagent_physical_engine.user_cli:main"
50
+ devagent = "devagent_physical_engine.one_command_runtime:main"
51
51
  devagent-physical = "devagent_physical_engine.cli:main"
52
52
  devagent-physical-ai = "devagent_physical_engine.ai_cli:main"
53
53
  devagent-commercial = "devagent_physical_engine.commercial_cli:main"
@@ -50,6 +50,7 @@ from .production_grade import (
50
50
  VerificationCase,
51
51
  load_verification_spec,
52
52
  )
53
+ from .one_command_runtime import install_one_command_runtime
53
54
  from .project import (
54
55
  EvidenceArtifactRecord,
55
56
  ProjectError,
@@ -149,4 +150,6 @@ __all__ = [
149
150
  "VerificationTestMappingRecorder",
150
151
  ]
151
152
 
152
- __version__ = "1.4.0"
153
+ install_one_command_runtime()
154
+
155
+ __version__ = "1.4.1"
@@ -0,0 +1,114 @@
1
+ """Runtime hardening for the one-command customer workflow.
2
+
3
+ This module keeps the production FAT builder fail-closed while making repeated
4
+ ``devagent verify`` runs lineage-complete. A second or later full campaign must
5
+ carry an exact previous-campaign -> current-campaign regression artifact before
6
+ FAT generation. The runtime creates that artifact automatically, then delegates
7
+ back to :class:`ProductionFATReportBuilder` so the existing scope checks remain
8
+ authoritative.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import sys
15
+ from typing import Sequence
16
+
17
+ from .commercial import CommercialError
18
+ from .production_grade import ProductionFATReportBuilder, ProductionRegressionAnalyzer
19
+
20
+
21
+ class OneCommandFATReportBuilder(ProductionFATReportBuilder):
22
+ """FAT builder adapter that supplies exact repeat-run regression lineage."""
23
+
24
+ def build(
25
+ self,
26
+ *,
27
+ project_id: str,
28
+ campaign_artifact_id: str,
29
+ regression_artifact_id: str | None = None,
30
+ ):
31
+ resolved_regression_id = regression_artifact_id
32
+ campaigns = self.repository.list_artifacts(
33
+ project_id,
34
+ artifact_type="commercial_campaign",
35
+ )
36
+ campaign_ids = [item.artifact_id for item in campaigns]
37
+
38
+ if campaign_artifact_id in campaign_ids and resolved_regression_id is None:
39
+ position = campaign_ids.index(campaign_artifact_id)
40
+ if position > 0:
41
+ baseline = campaigns[position - 1]
42
+ current = campaigns[position]
43
+
44
+ # Reuse an already-recorded exact lineage if a caller retries FAT
45
+ # generation. Otherwise create the immutable regression artifact.
46
+ regressions = self.repository.list_artifacts(
47
+ project_id,
48
+ artifact_type="commercial_regression",
49
+ )
50
+ for regression in reversed(regressions):
51
+ if (
52
+ regression.payload.get("baseline_campaign") == baseline.artifact_id
53
+ and regression.payload.get("current_campaign") == current.artifact_id
54
+ ):
55
+ resolved_regression_id = regression.artifact_id
56
+ break
57
+
58
+ if resolved_regression_id is None:
59
+ regression = ProductionRegressionAnalyzer(self.repository).compare(
60
+ project_id=project_id,
61
+ baseline_artifact_id=baseline.artifact_id,
62
+ current_artifact_id=current.artifact_id,
63
+ )
64
+ resolved_regression_id = regression.artifact_id
65
+
66
+ # Do not bypass or weaken ProductionFATReportBuilder._scoped_regression.
67
+ # It still validates the exact previous/current campaign relationship.
68
+ return super().build(
69
+ project_id=project_id,
70
+ campaign_artifact_id=campaign_artifact_id,
71
+ regression_artifact_id=resolved_regression_id,
72
+ )
73
+
74
+
75
+ def install_one_command_runtime() -> None:
76
+ """Install the repeat-run-aware FAT adapter into Simple Mode idempotently."""
77
+
78
+ from . import one_command as one_command_module
79
+
80
+ if one_command_module.ProductionFATReportBuilder is not OneCommandFATReportBuilder:
81
+ one_command_module.ProductionFATReportBuilder = OneCommandFATReportBuilder
82
+
83
+
84
+ def _bounded_failure(code: str, *, json_only: bool) -> int:
85
+ if not json_only:
86
+ print(f"[DevAgent] FAILED ERROR {code}", file=sys.stderr, flush=True)
87
+ print(
88
+ json.dumps(
89
+ {
90
+ "passed": False,
91
+ "failure_code": code,
92
+ "real_execution_allowed": False,
93
+ },
94
+ indent=2,
95
+ sort_keys=True,
96
+ )
97
+ )
98
+ return 10
99
+
100
+
101
+ def main(argv: Sequence[str] | None = None) -> int:
102
+ """Public ``devagent`` entry point with bounded commercial-error handling."""
103
+
104
+ install_one_command_runtime()
105
+ from . import user_cli
106
+
107
+ effective_argv = list(sys.argv[1:] if argv is None else argv)
108
+ try:
109
+ return user_cli.main(effective_argv)
110
+ except CommercialError as exc:
111
+ # Expected engineering/business-state failures must not leak a Python
112
+ # traceback to a customer-facing CLI. Unexpected exception classes are
113
+ # intentionally not swallowed here.
114
+ return _bounded_failure(str(exc), json_only="--json" in effective_argv)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devagent-physical-engine
3
- Version: 1.4.0
3
+ Version: 1.4.1
4
4
  Summary: Production-grade verification-first robotics evidence runtime with one-command customer intake, selective verification execution, deterministic Twin lineage, measured physical verification, replay inspection, regression, and FAT evidence.
5
5
  Author: Tom Ha
6
6
  License: All Rights Reserved
@@ -80,7 +80,7 @@ DevAgent is designed to answer: **What can be proven about this cell, what faile
80
80
  Python 3.11+ is required.
81
81
 
82
82
  ```bash
83
- python -m pip install --upgrade devagent-physical-engine==1.4.0
83
+ python -m pip install --upgrade devagent-physical-engine==1.4.1
84
84
  ```
85
85
 
86
86
  Verify the package:
@@ -92,7 +92,7 @@ python -c "import devagent_physical_engine as d; print(d.__version__)"
92
92
  Expected:
93
93
 
94
94
  ```text
95
- 1.4.0
95
+ 1.4.1
96
96
  ```
97
97
 
98
98
  Run the normal customer workflow:
@@ -720,9 +720,9 @@ Existing certified controllers execute.
720
720
 
721
721
  # Project status
722
722
 
723
- **v1.4.0 — Production/Stable software workflow**
723
+ **v1.4.1 — Production/Stable software workflow**
724
724
 
725
- v1.4.0 adds selective verification execution while preserving the existing fail-closed authority model.
725
+ v1.4.1 preserves v1.4 selective verification and fixes repeated full `devagent verify` runs by automatically binding exact previous-campaign current-campaign regression evidence before FAT generation. The original FAT regression scope validation remains authoritative and fail-closed.
726
726
 
727
727
  Production-oriented software capabilities include:
728
728
 
@@ -745,7 +745,7 @@ change impact + regression
745
745
  provider-neutral optional AI front end
746
746
  ```
747
747
 
748
- Quality gates include Python 3.11/3.12/3.13 regression, package clean-install, dependency audit, global branch coverage, One-Command coverage, **Selective Verification coverage**, Production Authority coverage, and Evidence Trust/Replay coverage.
748
+ Quality gates include Python 3.11/3.12/3.13 regression, package clean-install, dependency audit, global branch coverage, One-Command coverage, repeat-run regression qualification, **Selective Verification coverage**, Production Authority coverage, and Evidence Trust/Replay coverage.
749
749
 
750
750
  Production/Stable describes the bounded software workflow. It does not claim arbitrary customer cells are physically qualified, site-qualified, or safe for autonomous real execution.
751
751
 
@@ -19,6 +19,7 @@ src/devagent_physical_engine/evidence_trust.py
19
19
  src/devagent_physical_engine/execution.py
20
20
  src/devagent_physical_engine/models.py
21
21
  src/devagent_physical_engine/one_command.py
22
+ src/devagent_physical_engine/one_command_runtime.py
22
23
  src/devagent_physical_engine/operating_envelope.py
23
24
  src/devagent_physical_engine/physical_campaign.py
24
25
  src/devagent_physical_engine/physical_evidence.py
@@ -148,6 +149,7 @@ tests/test_moveit_planning_diagnostics_v0125.py
148
149
  tests/test_moveit_scene_v0123.py
149
150
  tests/test_natural_language_agent_v07.py
150
151
  tests/test_one_command_hardening_v13.py
152
+ tests/test_one_command_regression_v141.py
151
153
  tests/test_one_command_v13.py
152
154
  tests/test_openai_strict_schema_v0113.py
153
155
  tests/test_optimization_v05.py
@@ -1,5 +1,5 @@
1
1
  [console_scripts]
2
- devagent = devagent_physical_engine.user_cli:main
2
+ devagent = devagent_physical_engine.one_command_runtime:main
3
3
  devagent-commercial = devagent_physical_engine.commercial_cli:main
4
4
  devagent-physical = devagent_physical_engine.cli:main
5
5
  devagent-physical-ai = devagent_physical_engine.ai_cli:main
@@ -0,0 +1,141 @@
1
+ from __future__ import annotations
2
+
3
+ from contextlib import redirect_stderr, redirect_stdout
4
+ import io
5
+ import json
6
+ from pathlib import Path
7
+ import tempfile
8
+ import unittest
9
+ from unittest.mock import patch
10
+
11
+ import yaml
12
+
13
+ from devagent_physical_engine.commercial import CommercialError
14
+ from devagent_physical_engine.commercial_repository import CommercialProjectRepository
15
+ from devagent_physical_engine.one_command import OneCommandVerifier
16
+ from devagent_physical_engine.one_command_runtime import main as runtime_main
17
+
18
+ from test_one_command_v13 import _write_fixture
19
+
20
+
21
+ def _write_complete_fixture(root: Path, project_id: str) -> None:
22
+ _write_fixture(root, complete_request=True)
23
+ project_path = root / "project.yaml"
24
+ payload = yaml.safe_load(project_path.read_text(encoding="utf-8"))
25
+ payload["project_id"] = project_id
26
+ payload["name"] = f"{project_id} project"
27
+ payload["workcell_id"] = f"{project_id}-cell"
28
+ payload["robot_base_pose"] = {
29
+ "x": 0,
30
+ "y": 0,
31
+ "z": 0,
32
+ "roll": 0,
33
+ "pitch": 0,
34
+ "yaw": 0,
35
+ }
36
+ project_path.write_text(yaml.safe_dump(payload), encoding="utf-8")
37
+
38
+
39
+ class OneCommandRegressionV141Tests(unittest.TestCase):
40
+ def test_three_consecutive_runs_use_immediately_previous_campaign(self) -> None:
41
+ with tempfile.TemporaryDirectory() as tmp:
42
+ root = Path(tmp) / "cell"
43
+ _write_complete_fixture(root, "repeat-cell")
44
+ db = Path(tmp) / "projects.db"
45
+ verifier = OneCommandVerifier(db)
46
+
47
+ results = [
48
+ verifier.verify(root, output_dir=Path(tmp) / f"run-{index}")
49
+ for index in range(1, 4)
50
+ ]
51
+ self.assertTrue(all(result.fat_artifact_id for result in results))
52
+ self.assertTrue(all(result.campaign_artifact_id for result in results))
53
+
54
+ repository = CommercialProjectRepository(db)
55
+ campaigns = repository.list_artifacts(
56
+ "repeat-cell",
57
+ artifact_type="commercial_campaign",
58
+ )
59
+ regressions = repository.list_artifacts(
60
+ "repeat-cell",
61
+ artifact_type="commercial_regression",
62
+ )
63
+ fat_reports = repository.list_artifacts(
64
+ "repeat-cell",
65
+ artifact_type="fat_report",
66
+ )
67
+
68
+ self.assertEqual(len(campaigns), 3)
69
+ self.assertEqual(len(regressions), 2)
70
+ self.assertEqual(len(fat_reports), 3)
71
+ self.assertEqual(
72
+ regressions[0].payload["baseline_campaign"],
73
+ campaigns[0].artifact_id,
74
+ )
75
+ self.assertEqual(
76
+ regressions[0].payload["current_campaign"],
77
+ campaigns[1].artifact_id,
78
+ )
79
+ self.assertEqual(
80
+ regressions[1].payload["baseline_campaign"],
81
+ campaigns[1].artifact_id,
82
+ )
83
+ self.assertEqual(
84
+ regressions[1].payload["current_campaign"],
85
+ campaigns[2].artifact_id,
86
+ )
87
+
88
+ def test_campaign_history_is_scoped_to_each_project(self) -> None:
89
+ with tempfile.TemporaryDirectory() as tmp:
90
+ db = Path(tmp) / "projects.db"
91
+ first = Path(tmp) / "first"
92
+ second = Path(tmp) / "second"
93
+ _write_complete_fixture(first, "first-cell")
94
+ _write_complete_fixture(second, "second-cell")
95
+ verifier = OneCommandVerifier(db)
96
+
97
+ verifier.verify(first, output_dir=Path(tmp) / "first-run-1")
98
+ verifier.verify(first, output_dir=Path(tmp) / "first-run-2")
99
+ second_result = verifier.verify(second, output_dir=Path(tmp) / "second-run-1")
100
+ self.assertIsNotNone(second_result.fat_artifact_id)
101
+
102
+ repository = CommercialProjectRepository(db)
103
+ self.assertEqual(
104
+ len(repository.list_artifacts("first-cell", artifact_type="commercial_regression")),
105
+ 1,
106
+ )
107
+ self.assertEqual(
108
+ len(repository.list_artifacts("second-cell", artifact_type="commercial_regression")),
109
+ 0,
110
+ )
111
+ self.assertEqual(
112
+ len(repository.list_artifacts("second-cell", artifact_type="commercial_campaign")),
113
+ 1,
114
+ )
115
+
116
+ def test_customer_cli_bounds_commercial_error_without_traceback(self) -> None:
117
+ stdout = io.StringIO()
118
+ stderr = io.StringIO()
119
+ with (
120
+ patch(
121
+ "devagent_physical_engine.user_cli.main",
122
+ side_effect=CommercialError("fat_report_regression_scope_mismatch"),
123
+ ),
124
+ redirect_stdout(stdout),
125
+ redirect_stderr(stderr),
126
+ ):
127
+ rc = runtime_main(["verify", "/tmp/customer", "--json"])
128
+
129
+ self.assertEqual(rc, 10)
130
+ self.assertEqual(stderr.getvalue(), "")
131
+ payload = json.loads(stdout.getvalue())
132
+ self.assertFalse(payload["passed"])
133
+ self.assertEqual(
134
+ payload["failure_code"],
135
+ "fat_report_regression_scope_mismatch",
136
+ )
137
+ self.assertFalse(payload["real_execution_allowed"])
138
+
139
+
140
+ if __name__ == "__main__":
141
+ unittest.main()