loopx 0.4.8__py3-none-any.whl

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 (811) hide show
  1. loopx/__init__.py +5 -0
  2. loopx/agent_onboarding.py +654 -0
  3. loopx/agent_registry.py +112 -0
  4. loopx/ark_managed_agent_host.py +59 -0
  5. loopx/authority.py +805 -0
  6. loopx/benchmark.py +2875 -0
  7. loopx/benchmark_adapters/__init__.py +1 -0
  8. loopx/benchmark_adapters/agentissue.py +2644 -0
  9. loopx/benchmark_adapters/agents_last_exam.py +3998 -0
  10. loopx/benchmark_adapters/edgebench.py +322 -0
  11. loopx/benchmark_adapters/skillsbench.py +5978 -0
  12. loopx/benchmark_adapters/skillsbench_acp_failure_policy.py +143 -0
  13. loopx/benchmark_adapters/skillsbench_acp_process.py +31 -0
  14. loopx/benchmark_adapters/skillsbench_acp_relay.py +4832 -0
  15. loopx/benchmark_adapters/skillsbench_batch.py +124 -0
  16. loopx/benchmark_adapters/skillsbench_bridge_guard.py +209 -0
  17. loopx/benchmark_adapters/skillsbench_bridge_summary.py +203 -0
  18. loopx/benchmark_adapters/skillsbench_codex_goal_recovery.py +271 -0
  19. loopx/benchmark_adapters/skillsbench_codex_goal_trace.py +81 -0
  20. loopx/benchmark_adapters/skillsbench_codex_runtime.py +339 -0
  21. loopx/benchmark_adapters/skillsbench_dockerfile_runtime.py +467 -0
  22. loopx/benchmark_adapters/skillsbench_failure_signals.py +652 -0
  23. loopx/benchmark_adapters/skillsbench_proxy_runtime.py +327 -0
  24. loopx/benchmark_adapters/skillsbench_remote_bridge.py +402 -0
  25. loopx/benchmark_adapters/skillsbench_result_discovery.py +143 -0
  26. loopx/benchmark_adapters/skillsbench_runner_profile.py +436 -0
  27. loopx/benchmark_adapters/skillsbench_runner_source.py +99 -0
  28. loopx/benchmark_adapters/skillsbench_setup_preflight.py +771 -0
  29. loopx/benchmark_adapters/skillsbench_signals.py +15 -0
  30. loopx/benchmark_adapters/skillsbench_task_source.py +141 -0
  31. loopx/benchmark_adapters/skillsbench_turn_route.py +723 -0
  32. loopx/benchmark_adapters/skillsbench_turn_runtime.py +1069 -0
  33. loopx/benchmark_adapters/skillsbench_typed_repair.py +689 -0
  34. loopx/benchmark_adapters/skillsbench_uv_cache.py +111 -0
  35. loopx/benchmark_adapters/skillsbench_verifier_bootstrap.py +227 -0
  36. loopx/benchmark_adapters/skillsbench_verifier_cache.py +138 -0
  37. loopx/benchmark_adapters/terminal_bench.py +10078 -0
  38. loopx/benchmark_case_analysis.py +1276 -0
  39. loopx/benchmark_case_state.py +1079 -0
  40. loopx/benchmark_core/__init__.py +239 -0
  41. loopx/benchmark_core/adapter.py +84 -0
  42. loopx/benchmark_core/artifacts.py +517 -0
  43. loopx/benchmark_core/attempts.py +199 -0
  44. loopx/benchmark_core/container_exec.py +216 -0
  45. loopx/benchmark_core/io.py +68 -0
  46. loopx/benchmark_core/lifecycle.py +211 -0
  47. loopx/benchmark_core/loop_protocol.py +689 -0
  48. loopx/benchmark_core/observable_handles.py +348 -0
  49. loopx/benchmark_core/parity.py +256 -0
  50. loopx/benchmark_core/remote_closeout.py +482 -0
  51. loopx/benchmark_core/rounds.py +215 -0
  52. loopx/benchmark_core/route_profile.py +509 -0
  53. loopx/benchmark_core/run_permissions.py +206 -0
  54. loopx/benchmark_core/split_control.py +925 -0
  55. loopx/benchmark_core/turn_fidelity.py +326 -0
  56. loopx/benchmark_ledger.py +3793 -0
  57. loopx/benchmark_ledger_countability.py +372 -0
  58. loopx/benchmark_ledger_current.py +724 -0
  59. loopx/benchmark_trajectory.py +405 -0
  60. loopx/benchmarks/__init__.py +1 -0
  61. loopx/benchmarks/qualification/__init__.py +1 -0
  62. loopx/benchmarks/qualification/release_outcome_baseline.py +360 -0
  63. loopx/benchmarks/read_models/__init__.py +1 -0
  64. loopx/benchmarks/read_models/benchmark_attempt_accounting.py +53 -0
  65. loopx/benchmarks/read_models/benchmark_comparison.py +414 -0
  66. loopx/benchmarks/read_models/benchmark_event_timeline.py +113 -0
  67. loopx/benchmarks/read_models/benchmark_experiment_report.py +475 -0
  68. loopx/benchmarks/read_models/benchmark_learning_ledger.py +137 -0
  69. loopx/benchmarks/read_models/benchmark_lifecycle_contracts.py +228 -0
  70. loopx/benchmarks/read_models/benchmark_projection.py +723 -0
  71. loopx/benchmarks/read_models/benchmark_result.py +146 -0
  72. loopx/benchmarks/read_models/benchmark_run_execution_contract.py +116 -0
  73. loopx/benchmarks/read_models/benchmark_run_failure.py +157 -0
  74. loopx/benchmarks/read_models/benchmark_run_metrics.py +213 -0
  75. loopx/benchmarks/read_models/benchmark_run_post_execution.py +635 -0
  76. loopx/benchmarks/read_models/benchmark_run_pre_execution.py +541 -0
  77. loopx/benchmarks/read_models/benchmark_status_compaction.py +1255 -0
  78. loopx/benchmarks/read_models/benchmark_status_runner.py +780 -0
  79. loopx/benchmarks/read_models/goal_start_control_score.py +857 -0
  80. loopx/benchmarks/read_models/skillsbench_post_run_debug.py +746 -0
  81. loopx/benchmarks/read_models/skillsbench_verifier_attribution.py +269 -0
  82. loopx/bootstrap.py +1116 -0
  83. loopx/bootstrap_command_pack.py +2167 -0
  84. loopx/boundary_authority.py +199 -0
  85. loopx/canary/__init__.py +1 -0
  86. loopx/canary/maintainability_ratchet.py +800 -0
  87. loopx/canary/planner.py +1984 -0
  88. loopx/canary/premerge.py +1130 -0
  89. loopx/canary/qualification_profiles.py +309 -0
  90. loopx/canary/quality_surface_catalog.py +838 -0
  91. loopx/canary/release_profiles.py +51 -0
  92. loopx/canary/runner.py +1107 -0
  93. loopx/canary/smoke_health.py +581 -0
  94. loopx/canary/smoke_profiles.py +212 -0
  95. loopx/capabilities/__init__.py +0 -0
  96. loopx/capabilities/agent_turn_recall/__init__.py +17 -0
  97. loopx/capabilities/agent_turn_recall/cli.py +369 -0
  98. loopx/capabilities/agent_turn_recall/core.py +296 -0
  99. loopx/capabilities/auto_research/__init__.py +16 -0
  100. loopx/capabilities/auto_research/bootstrap_contract.py +157 -0
  101. loopx/capabilities/auto_research/cli.py +1468 -0
  102. loopx/capabilities/auto_research/core.py +11 -0
  103. loopx/capabilities/auto_research/defaults.py +79 -0
  104. loopx/capabilities/auto_research/demo_e2e.py +1848 -0
  105. loopx/capabilities/auto_research/demo_supervisor.py +186 -0
  106. loopx/capabilities/auto_research/evidence_packet.py +767 -0
  107. loopx/capabilities/auto_research/human_view.py +794 -0
  108. loopx/capabilities/auto_research/kernel.py +191 -0
  109. loopx/capabilities/auto_research/knn_demo_workspace.py +322 -0
  110. loopx/capabilities/auto_research/live_evidence.py +248 -0
  111. loopx/capabilities/auto_research/preset.py +176 -0
  112. loopx/capabilities/auto_research/research_state.py +1085 -0
  113. loopx/capabilities/auto_research/role_profiles.py +394 -0
  114. loopx/capabilities/auto_research/rollout_append.py +97 -0
  115. loopx/capabilities/auto_research/terminal_result_contract.py +422 -0
  116. loopx/capabilities/auto_research/terminal_result_projection.py +171 -0
  117. loopx/capabilities/auto_research/terminal_result_query.py +233 -0
  118. loopx/capabilities/auto_research/terminal_results.py +349 -0
  119. loopx/capabilities/auto_research/user_contract.py +190 -0
  120. loopx/capabilities/auto_research/worker_loop.py +163 -0
  121. loopx/capabilities/auto_research/worker_runtime.py +777 -0
  122. loopx/capabilities/auto_research/worker_skill/SKILL.md +343 -0
  123. loopx/capabilities/benchmark_toolkit/__init__.py +19 -0
  124. loopx/capabilities/benchmark_toolkit/integrity.py +387 -0
  125. loopx/capabilities/catalog.py +1875 -0
  126. loopx/capabilities/change_quality/__init__.py +19 -0
  127. loopx/capabilities/change_quality/cli.py +171 -0
  128. loopx/capabilities/change_quality/context.py +156 -0
  129. loopx/capabilities/change_quality/oracles.py +269 -0
  130. loopx/capabilities/change_quality/policy.py +34 -0
  131. loopx/capabilities/change_quality/receipt.py +482 -0
  132. loopx/capabilities/change_quality/result.py +493 -0
  133. loopx/capabilities/change_quality/scope.py +171 -0
  134. loopx/capabilities/change_quality/shadow.py +680 -0
  135. loopx/capabilities/content_ops/__init__.py +0 -0
  136. loopx/capabilities/content_ops/cli.py +649 -0
  137. loopx/capabilities/content_ops/connector_packets.py +164 -0
  138. loopx/capabilities/content_ops/item_lifecycle.py +1000 -0
  139. loopx/capabilities/content_ops/layout.py +451 -0
  140. loopx/capabilities/content_ops/markdown.py +456 -0
  141. loopx/capabilities/content_ops/schemas.py +51 -0
  142. loopx/capabilities/content_ops/social_browser_x.py +107 -0
  143. loopx/capabilities/content_ops/surface.py +1956 -0
  144. loopx/capabilities/content_ops/templates/layout-catalog-v0.json +72 -0
  145. loopx/capabilities/context_providers/__init__.py +36 -0
  146. loopx/capabilities/context_providers/base.py +189 -0
  147. loopx/capabilities/context_providers/factory.py +32 -0
  148. loopx/capabilities/context_providers/openviking.py +702 -0
  149. loopx/capabilities/context_providers/service_ownership.py +185 -0
  150. loopx/capabilities/decision_context/__init__.py +129 -0
  151. loopx/capabilities/decision_context/architecture.py +83 -0
  152. loopx/capabilities/decision_context/assembler.py +849 -0
  153. loopx/capabilities/decision_context/catalog_entry.py +195 -0
  154. loopx/capabilities/decision_context/cli.py +310 -0
  155. loopx/capabilities/decision_context/cursor_commit.py +535 -0
  156. loopx/capabilities/decision_context/outcome_feedback.py +352 -0
  157. loopx/capabilities/decision_context/packets.py +654 -0
  158. loopx/capabilities/decision_context/private_state.py +189 -0
  159. loopx/capabilities/decision_context/profile.py +453 -0
  160. loopx/capabilities/decision_context/providers.py +228 -0
  161. loopx/capabilities/decision_context/review_settlement.py +136 -0
  162. loopx/capabilities/decision_context/runtime.py +273 -0
  163. loopx/capabilities/decision_context/sources.py +415 -0
  164. loopx/capabilities/explore/__init__.py +1 -0
  165. loopx/capabilities/explore/activation.py +198 -0
  166. loopx/capabilities/explore/adaptive_replay_planner.py +221 -0
  167. loopx/capabilities/explore/child_replay_runtime.py +463 -0
  168. loopx/capabilities/explore/composition_frontier.py +291 -0
  169. loopx/capabilities/explore/counterfactual_runtime.py +578 -0
  170. loopx/capabilities/explore/episode_runtime.py +647 -0
  171. loopx/capabilities/explore/harness_checkpoint.py +171 -0
  172. loopx/capabilities/explore/harness_gate.py +115 -0
  173. loopx/capabilities/explore/harness_runtime.py +1124 -0
  174. loopx/capabilities/explore/replay_metrics.py +206 -0
  175. loopx/capabilities/explore/replay_runtime.py +1271 -0
  176. loopx/capabilities/explore/resource_portfolio.py +173 -0
  177. loopx/capabilities/explore/result_log.py +974 -0
  178. loopx/capabilities/explore/router_state.py +432 -0
  179. loopx/capabilities/explore/source_history_reconcile.py +255 -0
  180. loopx/capabilities/explore/speculative_scheduler.py +498 -0
  181. loopx/capabilities/explore/todo_branch_plan.py +650 -0
  182. loopx/capabilities/explore/todo_evidence.py +141 -0
  183. loopx/capabilities/explore/trace_runtime.py +284 -0
  184. loopx/capabilities/explore/worker_branch_plan.py +1257 -0
  185. loopx/capabilities/integration_branch/__init__.py +13 -0
  186. loopx/capabilities/integration_branch/cli.py +148 -0
  187. loopx/capabilities/integration_branch/core.py +916 -0
  188. loopx/capabilities/issue_fix/__init__.py +19 -0
  189. loopx/capabilities/issue_fix/acceptance_loop.py +1050 -0
  190. loopx/capabilities/issue_fix/candidate_evidence.py +503 -0
  191. loopx/capabilities/issue_fix/candidate_preflight.py +676 -0
  192. loopx/capabilities/issue_fix/cli.py +1822 -0
  193. loopx/capabilities/issue_fix/cli_input.py +87 -0
  194. loopx/capabilities/issue_fix/content_ops_cli.py +148 -0
  195. loopx/capabilities/issue_fix/discovered_issue_promotion.py +947 -0
  196. loopx/capabilities/issue_fix/explore_projection.py +710 -0
  197. loopx/capabilities/issue_fix/feasibility.py +542 -0
  198. loopx/capabilities/issue_fix/github_public.py +661 -0
  199. loopx/capabilities/issue_fix/intake_surface.py +832 -0
  200. loopx/capabilities/issue_fix/metadata_preview.py +218 -0
  201. loopx/capabilities/issue_fix/metrics_projection.py +1340 -0
  202. loopx/capabilities/issue_fix/metrics_supplement.py +634 -0
  203. loopx/capabilities/issue_fix/metrics_supplement_cli.py +127 -0
  204. loopx/capabilities/issue_fix/outcome_projection.py +1235 -0
  205. loopx/capabilities/issue_fix/periodic_report.py +189 -0
  206. loopx/capabilities/issue_fix/pr_description.py +418 -0
  207. loopx/capabilities/issue_fix/pr_gate_reconcile.py +496 -0
  208. loopx/capabilities/issue_fix/pr_gate_reconcile_cli.py +464 -0
  209. loopx/capabilities/issue_fix/pr_lifecycle.py +1327 -0
  210. loopx/capabilities/issue_fix/pr_lifecycle_rollout.py +85 -0
  211. loopx/capabilities/issue_fix/pr_monitor_materialization.py +257 -0
  212. loopx/capabilities/issue_fix/pr_review_ack.py +439 -0
  213. loopx/capabilities/issue_fix/provider_hooks.py +24 -0
  214. loopx/capabilities/issue_fix/repository_commit_evidence.py +186 -0
  215. loopx/capabilities/issue_fix/repository_context.py +457 -0
  216. loopx/capabilities/issue_fix/repository_memory.py +459 -0
  217. loopx/capabilities/issue_fix/repository_memory_provider.py +1454 -0
  218. loopx/capabilities/issue_fix/repository_snapshot.py +454 -0
  219. loopx/capabilities/issue_fix/reviewer_cli.py +917 -0
  220. loopx/capabilities/issue_fix/reviewer_notification.py +882 -0
  221. loopx/capabilities/issue_fix/reviewer_notification_drain.py +942 -0
  222. loopx/capabilities/issue_fix/reviewer_recommendation.py +1057 -0
  223. loopx/capabilities/issue_fix/reviewer_request.py +1282 -0
  224. loopx/capabilities/issue_fix/reward_memory.py +879 -0
  225. loopx/capabilities/issue_fix/workflow_plan.py +1286 -0
  226. loopx/capabilities/material_lifecycle/__init__.py +161 -0
  227. loopx/capabilities/material_lifecycle/_validation.py +183 -0
  228. loopx/capabilities/material_lifecycle/apply.py +672 -0
  229. loopx/capabilities/material_lifecycle/architecture.py +122 -0
  230. loopx/capabilities/material_lifecycle/cli.py +161 -0
  231. loopx/capabilities/material_lifecycle/decision_planning.py +470 -0
  232. loopx/capabilities/material_lifecycle/explore_execution.py +306 -0
  233. loopx/capabilities/material_lifecycle/intake.py +869 -0
  234. loopx/capabilities/material_lifecycle/inventory.py +147 -0
  235. loopx/capabilities/material_lifecycle/lifecycle.py +98 -0
  236. loopx/capabilities/material_lifecycle/preparation.py +147 -0
  237. loopx/capabilities/material_lifecycle/project_skill.py +83 -0
  238. loopx/capabilities/material_lifecycle/ranking.py +267 -0
  239. loopx/capabilities/material_lifecycle/readable_projection.py +500 -0
  240. loopx/capabilities/material_lifecycle/rebuild.py +480 -0
  241. loopx/capabilities/material_lifecycle/settlement.py +238 -0
  242. loopx/capabilities/periodic_report/__init__.py +71 -0
  243. loopx/capabilities/periodic_report/adapters.py +939 -0
  244. loopx/capabilities/periodic_report/archive.py +422 -0
  245. loopx/capabilities/periodic_report/bindings.py +705 -0
  246. loopx/capabilities/periodic_report/cli.py +277 -0
  247. loopx/capabilities/periodic_report/core.py +691 -0
  248. loopx/capabilities/periodic_report/extension_envelope.py +66 -0
  249. loopx/capabilities/periodic_report/presets.py +103 -0
  250. loopx/capabilities/periodic_report/profile.py +235 -0
  251. loopx/capabilities/periodic_report/project_progress.py +179 -0
  252. loopx/capabilities/periodic_report/triggers.py +452 -0
  253. loopx/capabilities/pr_review_queue/__init__.py +17 -0
  254. loopx/capabilities/pr_review_queue/core.py +506 -0
  255. loopx/capabilities/pr_review_queue/review_contract.py +506 -0
  256. loopx/capabilities/registry.py +192 -0
  257. loopx/capabilities/reward_memory/__init__.py +75 -0
  258. loopx/capabilities/reward_memory/application.py +819 -0
  259. loopx/capabilities/reward_memory/architecture.py +572 -0
  260. loopx/capabilities/reward_memory/candidate_review.py +511 -0
  261. loopx/capabilities/reward_memory/cli.py +469 -0
  262. loopx/capabilities/reward_memory/dogfood.py +574 -0
  263. loopx/capabilities/reward_memory/evaluation.py +296 -0
  264. loopx/capabilities/reward_memory/evaluation_fixtures.py +362 -0
  265. loopx/capabilities/reward_memory/experiment.py +567 -0
  266. loopx/capabilities/reward_memory/health.py +222 -0
  267. loopx/capabilities/reward_memory/ingestion.py +519 -0
  268. loopx/capabilities/reward_memory/registry.py +600 -0
  269. loopx/capabilities/reward_memory/runtime_hooks.py +312 -0
  270. loopx/capabilities/reward_memory/scoped_feedback.py +173 -0
  271. loopx/capabilities/semantic_preference/__init__.py +12 -0
  272. loopx/capabilities/semantic_preference/cli.py +189 -0
  273. loopx/capabilities/semantic_preference/contract.py +592 -0
  274. loopx/capabilities/semantic_preference/reward_memory.py +62 -0
  275. loopx/capabilities/value_connectors/__init__.py +1 -0
  276. loopx/capabilities/value_connectors/cli.py +401 -0
  277. loopx/capabilities/value_connectors/finance_extension_migration.py +108 -0
  278. loopx/capabilities/value_connectors/install_check.py +147 -0
  279. loopx/capabilities/value_connectors/planner.py +733 -0
  280. loopx/capabilities/value_connectors/source_map.py +446 -0
  281. loopx/claude_goal_baseline.py +138 -0
  282. loopx/claude_goal_mode/__init__.py +23 -0
  283. loopx/claude_goal_mode/hooks/goal_policy.py +212 -0
  284. loopx/claude_goal_mode/hooks/goal_state.py +139 -0
  285. loopx/claude_goal_mode/mcp/loopx_mcp.py +167 -0
  286. loopx/claude_goal_mode/scripts/connect.py +103 -0
  287. loopx/claude_goal_mode/scripts/goalmode_cmd.py +241 -0
  288. loopx/claude_goal_mode/scripts/install.py +328 -0
  289. loopx/claude_goal_mode/statusline/goal_status.py +97 -0
  290. loopx/cli.py +836 -0
  291. loopx/cli_commands/__init__.py +334 -0
  292. loopx/cli_commands/_host_thread.py +13 -0
  293. loopx/cli_commands/agentissue_runner_flow.py +447 -0
  294. loopx/cli_commands/agents_last_exam.py +160 -0
  295. loopx/cli_commands/agents_last_exam_baked_input.py +302 -0
  296. loopx/cli_commands/agents_last_exam_host_codex.py +374 -0
  297. loopx/cli_commands/agents_last_exam_launch_dry_run.py +372 -0
  298. loopx/cli_commands/agents_last_exam_local_plan.py +322 -0
  299. loopx/cli_commands/agents_last_exam_runner_source.py +352 -0
  300. loopx/cli_commands/agents_last_exam_task_material.py +335 -0
  301. loopx/cli_commands/agents_last_exam_validation_gate.py +236 -0
  302. loopx/cli_commands/benchmark_boundary.py +499 -0
  303. loopx/cli_commands/benchmark_dispatch.py +161 -0
  304. loopx/cli_commands/benchmark_release_outcome.py +123 -0
  305. loopx/cli_commands/benchmark_review_lifecycle.py +1275 -0
  306. loopx/cli_commands/benchmark_run_ledger.py +763 -0
  307. loopx/cli_commands/benchmark_run_ledger_case_analysis.py +249 -0
  308. loopx/cli_commands/benchmark_run_ledger_classification.py +45 -0
  309. loopx/cli_commands/benchmark_run_ledger_maintenance.py +486 -0
  310. loopx/cli_commands/benchmark_run_ledger_maintenance_registration.py +342 -0
  311. loopx/cli_commands/benchmark_run_ledger_maintenance_rendering.py +233 -0
  312. loopx/cli_commands/benchmark_run_ledger_parity.py +92 -0
  313. loopx/cli_commands/bootstrap_connect.py +238 -0
  314. loopx/cli_commands/canary.py +707 -0
  315. loopx/cli_commands/canary_release_qualification.py +79 -0
  316. loopx/cli_commands/capability.py +96 -0
  317. loopx/cli_commands/doctor.py +43 -0
  318. loopx/cli_commands/dreaming.py +143 -0
  319. loopx/cli_commands/edgebench.py +205 -0
  320. loopx/cli_commands/evidence_log.py +275 -0
  321. loopx/cli_commands/explore.py +989 -0
  322. loopx/cli_commands/explore_planning_commands.py +157 -0
  323. loopx/cli_commands/extension.py +271 -0
  324. loopx/cli_commands/first_run_report.py +73 -0
  325. loopx/cli_commands/goal_channel.py +656 -0
  326. loopx/cli_commands/handoff_mode.py +158 -0
  327. loopx/cli_commands/history.py +622 -0
  328. loopx/cli_commands/host_mode_plan.py +113 -0
  329. loopx/cli_commands/lark_inbox.py +431 -0
  330. loopx/cli_commands/lark_kanban.py +629 -0
  331. loopx/cli_commands/ml_experiment.py +321 -0
  332. loopx/cli_commands/multi_agent.py +211 -0
  333. loopx/cli_commands/opencode2_goal_worker.py +217 -0
  334. loopx/cli_commands/pr_review.py +167 -0
  335. loopx/cli_commands/presentation.py +218 -0
  336. loopx/cli_commands/preset.py +96 -0
  337. loopx/cli_commands/project.py +150 -0
  338. loopx/cli_commands/project_lifecycle.py +915 -0
  339. loopx/cli_commands/quota.py +859 -0
  340. loopx/cli_commands/quota_registration.py +241 -0
  341. loopx/cli_commands/quota_request.py +113 -0
  342. loopx/cli_commands/ready_score.py +110 -0
  343. loopx/cli_commands/registry_admin.py +975 -0
  344. loopx/cli_commands/registry_admin_configure.py +344 -0
  345. loopx/cli_commands/registry_admin_peer.py +84 -0
  346. loopx/cli_commands/registry_authority.py +218 -0
  347. loopx/cli_commands/review_batch.py +146 -0
  348. loopx/cli_commands/slash_commands.py +145 -0
  349. loopx/cli_commands/start_goal.py +251 -0
  350. loopx/cli_commands/starter.py +175 -0
  351. loopx/cli_commands/starter_bootstrap.py +179 -0
  352. loopx/cli_commands/starter_bootstrap_registration.py +198 -0
  353. loopx/cli_commands/starter_runtime_idle.py +107 -0
  354. loopx/cli_commands/starter_scheduler.py +207 -0
  355. loopx/cli_commands/starter_session_runtime.py +152 -0
  356. loopx/cli_commands/starter_visible_common.py +54 -0
  357. loopx/cli_commands/starter_visible_driver.py +161 -0
  358. loopx/cli_commands/starter_visible_pilot.py +278 -0
  359. loopx/cli_commands/status.py +867 -0
  360. loopx/cli_commands/status_registration.py +239 -0
  361. loopx/cli_commands/summary_all.py +222 -0
  362. loopx/cli_commands/support_control.py +809 -0
  363. loopx/cli_commands/support_control_registry.py +68 -0
  364. loopx/cli_commands/support_control_supervisor.py +289 -0
  365. loopx/cli_commands/task_lease.py +306 -0
  366. loopx/cli_commands/terminal_bench_adapter.py +717 -0
  367. loopx/cli_commands/terminal_bench_environment_result.py +1246 -0
  368. loopx/cli_commands/todo.py +940 -0
  369. loopx/cli_commands/todo_argument_validation.py +572 -0
  370. loopx/cli_commands/todo_event.py +114 -0
  371. loopx/cli_commands/turn.py +804 -0
  372. loopx/cli_commands/version.py +46 -0
  373. loopx/cli_commands/worker_bridge.py +659 -0
  374. loopx/cli_rollout.py +314 -0
  375. loopx/codex_cli_goal_tui.py +672 -0
  376. loopx/codex_cli_probe.py +1530 -0
  377. loopx/codex_cli_probe_markdown.py +935 -0
  378. loopx/codex_cli_runtime_probe.py +733 -0
  379. loopx/codex_cli_scheduler.py +564 -0
  380. loopx/codex_goal_baseline.py +620 -0
  381. loopx/configuration_catalog.py +617 -0
  382. loopx/configure_goal.py +1375 -0
  383. loopx/contract.py +996 -0
  384. loopx/control_plane/__init__.py +71 -0
  385. loopx/control_plane/agents/__init__.py +1 -0
  386. loopx/control_plane/agents/agent_lane_recommendation.py +516 -0
  387. loopx/control_plane/agents/agent_scope.py +1578 -0
  388. loopx/control_plane/agents/agent_scope_frontier.py +60 -0
  389. loopx/control_plane/agents/capability_gate.py +531 -0
  390. loopx/control_plane/agents/identity.py +140 -0
  391. loopx/control_plane/agents/legacy_migration.py +169 -0
  392. loopx/control_plane/agents/management_projection.py +658 -0
  393. loopx/control_plane/agents/material_frontier.py +608 -0
  394. loopx/control_plane/agents/material_handoff.py +156 -0
  395. loopx/control_plane/agents/multi_agent/__init__.py +1 -0
  396. loopx/control_plane/agents/multi_agent/codex_executable.py +207 -0
  397. loopx/control_plane/agents/multi_agent/collective_round_ledger.py +387 -0
  398. loopx/control_plane/agents/multi_agent/contract.py +474 -0
  399. loopx/control_plane/agents/multi_agent/recipe.py +110 -0
  400. loopx/control_plane/agents/multi_agent/role_successor.py +297 -0
  401. loopx/control_plane/agents/multi_agent/runtime_scripts.py +426 -0
  402. loopx/control_plane/agents/multi_agent/visible_launch_policy.py +149 -0
  403. loopx/control_plane/agents/multi_agent/visible_wake_scheduler.py +392 -0
  404. loopx/control_plane/agents/profile.py +216 -0
  405. loopx/control_plane/agents/runtime_model.py +73 -0
  406. loopx/control_plane/agents/subagent_activity.py +164 -0
  407. loopx/control_plane/agents/supervisor.py +544 -0
  408. loopx/control_plane/agents/supervisor_events.py +462 -0
  409. loopx/control_plane/agents/supervisor_inject.py +204 -0
  410. loopx/control_plane/agents/work_mode.py +56 -0
  411. loopx/control_plane/agents/workspace_guard.py +364 -0
  412. loopx/control_plane/effect_program.py +644 -0
  413. loopx/control_plane/goals/__init__.py +1 -0
  414. loopx/control_plane/goals/active_state_event_projection.py +103 -0
  415. loopx/control_plane/goals/active_state_metadata.py +47 -0
  416. loopx/control_plane/goals/active_state_sections.py +58 -0
  417. loopx/control_plane/goals/configure_goal_service.py +354 -0
  418. loopx/control_plane/goals/contract_health.py +132 -0
  419. loopx/control_plane/goals/dreaming.py +152 -0
  420. loopx/control_plane/goals/global_registry_health.py +199 -0
  421. loopx/control_plane/goals/global_registry_shadow.py +33 -0
  422. loopx/control_plane/goals/goal_channel.py +34 -0
  423. loopx/control_plane/goals/goal_channel_projection.py +560 -0
  424. loopx/control_plane/goals/goal_frontier/__init__.py +1917 -0
  425. loopx/control_plane/goals/goal_frontier/ack_policy.py +149 -0
  426. loopx/control_plane/goals/goal_frontier/outcome_continuity.py +437 -0
  427. loopx/control_plane/goals/goal_frontier/replan_rules.py +210 -0
  428. loopx/control_plane/goals/goal_frontier/semantic_history.py +314 -0
  429. loopx/control_plane/goals/goal_frontier/terminal.py +180 -0
  430. loopx/control_plane/goals/goal_vision.py +443 -0
  431. loopx/control_plane/goals/goal_vision_policy.py +36 -0
  432. loopx/control_plane/goals/goal_vision_state.py +62 -0
  433. loopx/control_plane/goals/goal_vision_wait.py +290 -0
  434. loopx/control_plane/goals/path_resolution.py +20 -0
  435. loopx/control_plane/goals/start_contract.py +206 -0
  436. loopx/control_plane/goals/vision_checkpoint.py +92 -0
  437. loopx/control_plane/handoff/__init__.py +1 -0
  438. loopx/control_plane/handoff/cross_runtime_impl_review.py +311 -0
  439. loopx/control_plane/handoff/delivery_contract.py +161 -0
  440. loopx/control_plane/handoff/handoff_runs.py +71 -0
  441. loopx/control_plane/handoff/project_handoff.py +155 -0
  442. loopx/control_plane/handoff/review_batch.py +463 -0
  443. loopx/control_plane/handoff/review_packet_context.py +216 -0
  444. loopx/control_plane/heartbeat/agent.py +173 -0
  445. loopx/control_plane/heartbeat/budget.py +66 -0
  446. loopx/control_plane/heartbeat/builder.py +501 -0
  447. loopx/control_plane/heartbeat/host.py +64 -0
  448. loopx/control_plane/heartbeat/rules.py +68 -0
  449. loopx/control_plane/heartbeat/task_body.py +759 -0
  450. loopx/control_plane/heartbeat/visible_goal.py +86 -0
  451. loopx/control_plane/projects/__init__.py +1 -0
  452. loopx/control_plane/projects/contract.py +25 -0
  453. loopx/control_plane/projects/registry.py +663 -0
  454. loopx/control_plane/quota/__init__.py +1 -0
  455. loopx/control_plane/quota/cli_projection.py +704 -0
  456. loopx/control_plane/quota/decision_summary.py +431 -0
  457. loopx/control_plane/quota/effect_program.py +152 -0
  458. loopx/control_plane/quota/error_codes.py +19 -0
  459. loopx/control_plane/quota/goal_boundary.py +464 -0
  460. loopx/control_plane/quota/heartbeat_receipt.py +277 -0
  461. loopx/control_plane/quota/heartbeat_recommendation.py +718 -0
  462. loopx/control_plane/quota/host_poll_receipts.py +162 -0
  463. loopx/control_plane/quota/live_decision.py +142 -0
  464. loopx/control_plane/quota/monitor_poll.py +786 -0
  465. loopx/control_plane/quota/policy_constants.py +40 -0
  466. loopx/control_plane/quota/projection_repair.py +262 -0
  467. loopx/control_plane/quota/recent_runs.py +210 -0
  468. loopx/control_plane/quota/scheduler_ack.py +490 -0
  469. loopx/control_plane/quota/selected_todo_projection.py +139 -0
  470. loopx/control_plane/quota/settlement.py +437 -0
  471. loopx/control_plane/quota/settlement_cli.py +246 -0
  472. loopx/control_plane/quota/settlement_validation.py +64 -0
  473. loopx/control_plane/quota/settlement_workspace_causality.py +180 -0
  474. loopx/control_plane/quota/should_run.py +249 -0
  475. loopx/control_plane/quota/should_run_packet.py +1165 -0
  476. loopx/control_plane/quota/should_run_prepare.py +675 -0
  477. loopx/control_plane/quota/slot_accounting.py +1123 -0
  478. loopx/control_plane/quota/spend_sources.py +11 -0
  479. loopx/control_plane/quota/stall_repair.py +397 -0
  480. loopx/control_plane/quota/states.py +29 -0
  481. loopx/control_plane/quota/task_orchestration.py +448 -0
  482. loopx/control_plane/quota/task_orchestration_admission.py +497 -0
  483. loopx/control_plane/quota/turn_envelope.py +889 -0
  484. loopx/control_plane/quota/usage_summary.py +140 -0
  485. loopx/control_plane/reward_memory.py +43 -0
  486. loopx/control_plane/runtime/__init__.py +2 -0
  487. loopx/control_plane/runtime/active_user_assisted_pilot.py +275 -0
  488. loopx/control_plane/runtime/agent_scoped_evidence_log.py +435 -0
  489. loopx/control_plane/runtime/decision_freshness.py +203 -0
  490. loopx/control_plane/runtime/event_ledger.py +197 -0
  491. loopx/control_plane/runtime/event_store_migration_bridge.py +196 -0
  492. loopx/control_plane/runtime/goal_project_route.py +70 -0
  493. loopx/control_plane/runtime/local_state_write_correctness.py +242 -0
  494. loopx/control_plane/runtime/promotion_readiness.py +152 -0
  495. loopx/control_plane/runtime/public_safety.py +120 -0
  496. loopx/control_plane/runtime/run_artifacts.py +78 -0
  497. loopx/control_plane/runtime/run_compaction.py +397 -0
  498. loopx/control_plane/runtime/run_context_retention.py +241 -0
  499. loopx/control_plane/runtime/run_history.py +132 -0
  500. loopx/control_plane/runtime/run_index_duplicates.py +205 -0
  501. loopx/control_plane/runtime/run_index_rebuild.py +263 -0
  502. loopx/control_plane/runtime/run_ingest_health.py +336 -0
  503. loopx/control_plane/runtime/runtime_projection_route.py +624 -0
  504. loopx/control_plane/runtime/runtime_projection_writer.py +98 -0
  505. loopx/control_plane/runtime/session_runtime.py +339 -0
  506. loopx/control_plane/runtime/shared_runtime_material_projection.py +332 -0
  507. loopx/control_plane/runtime/shared_runtime_refresh_projection.py +183 -0
  508. loopx/control_plane/runtime/stale_latest_run.py +90 -0
  509. loopx/control_plane/runtime/status_classifications.py +49 -0
  510. loopx/control_plane/runtime/status_projection_cache.py +235 -0
  511. loopx/control_plane/runtime/stride_observation.py +144 -0
  512. loopx/control_plane/runtime/time.py +39 -0
  513. loopx/control_plane/runtime/trajectory_hygiene.py +149 -0
  514. loopx/control_plane/runtime/validation_command.py +69 -0
  515. loopx/control_plane/scheduler/__init__.py +1 -0
  516. loopx/control_plane/scheduler/ack.py +329 -0
  517. loopx/control_plane/scheduler/arbitration.py +188 -0
  518. loopx/control_plane/scheduler/automation_liveness.py +183 -0
  519. loopx/control_plane/scheduler/execution_context.py +555 -0
  520. loopx/control_plane/scheduler/external_evidence_observation.py +428 -0
  521. loopx/control_plane/scheduler/monitor_display.py +143 -0
  522. loopx/control_plane/scheduler/monitor_poll_policy.py +161 -0
  523. loopx/control_plane/scheduler/monitor_poll_writeback.py +351 -0
  524. loopx/control_plane/scheduler/monitor_target.py +64 -0
  525. loopx/control_plane/scheduler/monitor_todo.py +146 -0
  526. loopx/control_plane/scheduler/monitor_wait.py +237 -0
  527. loopx/control_plane/scheduler/scheduler_hint.py +1284 -0
  528. loopx/control_plane/scheduler/state.py +354 -0
  529. loopx/control_plane/scheduler/state_transition_rules.py +179 -0
  530. loopx/control_plane/scheduler/time.py +10 -0
  531. loopx/control_plane/settlement_driver.py +293 -0
  532. loopx/control_plane/status/__init__.py +6 -0
  533. loopx/control_plane/status/active_state_projection.py +105 -0
  534. loopx/control_plane/status/agent_lane_projection.py +375 -0
  535. loopx/control_plane/status/attention_projection.py +74 -0
  536. loopx/control_plane/status/autonomous_replan_projection.py +103 -0
  537. loopx/control_plane/status/collection.py +140 -0
  538. loopx/control_plane/status/contract_projection.py +31 -0
  539. loopx/control_plane/status/dreaming_projection.py +52 -0
  540. loopx/control_plane/status/goal_attention_projection.py +157 -0
  541. loopx/control_plane/status/lifecycle_projection.py +110 -0
  542. loopx/control_plane/status/monitor_display_projection.py +69 -0
  543. loopx/control_plane/status/registry_health_projection.py +75 -0
  544. loopx/control_plane/status/run_projection.py +70 -0
  545. loopx/control_plane/status/runtime_summaries.py +161 -0
  546. loopx/control_plane/testing/__init__.py +1 -0
  547. loopx/control_plane/testing/actual_default_model_behavior_portfolio.py +1371 -0
  548. loopx/control_plane/testing/canary_harness.py +182 -0
  549. loopx/control_plane/testing/capability_monitor_repair_tool_behavior.py +674 -0
  550. loopx/control_plane/testing/cli_output_budget.py +807 -0
  551. loopx/control_plane/testing/cli_output_differential.py +250 -0
  552. loopx/control_plane/testing/cli_output_semantics.py +87 -0
  553. loopx/control_plane/testing/control_plane_composition_scenarios.py +225 -0
  554. loopx/control_plane/testing/decision_replay.py +268 -0
  555. loopx/control_plane/testing/doubao_model_behavior_actor.py +559 -0
  556. loopx/control_plane/testing/model_behavior_corpus.py +344 -0
  557. loopx/control_plane/testing/model_behavior_qualification.py +769 -0
  558. loopx/control_plane/testing/model_behavior_retained_cases.py +235 -0
  559. loopx/control_plane/testing/model_tool_behavior.py +536 -0
  560. loopx/control_plane/testing/onboarding_model_behavior_qualification.py +642 -0
  561. loopx/control_plane/testing/quota_fixtures.py +208 -0
  562. loopx/control_plane/testing/quota_should_run_parity.py +57 -0
  563. loopx/control_plane/testing/release_commit_qualification.py +671 -0
  564. loopx/control_plane/testing/replan_semantic_action_behavior.py +1302 -0
  565. loopx/control_plane/testing/scoped_gate_successor_tool_behavior.py +527 -0
  566. loopx/control_plane/testing/selected_todo_tool_behavior.py +1002 -0
  567. loopx/control_plane/testing/terminal_settlement_tool_behavior.py +656 -0
  568. loopx/control_plane/todos/__init__.py +1 -0
  569. loopx/control_plane/todos/active_state_editing.py +296 -0
  570. loopx/control_plane/todos/active_state_todo_parser.py +138 -0
  571. loopx/control_plane/todos/active_state_todos.py +175 -0
  572. loopx/control_plane/todos/addition.py +103 -0
  573. loopx/control_plane/todos/claim_visibility.py +253 -0
  574. loopx/control_plane/todos/completed_archive.py +139 -0
  575. loopx/control_plane/todos/completion_fence.py +49 -0
  576. loopx/control_plane/todos/completion_policy.py +153 -0
  577. loopx/control_plane/todos/completion_validation.py +248 -0
  578. loopx/control_plane/todos/completion_validation_accountability.py +27 -0
  579. loopx/control_plane/todos/completion_validation_projection.py +57 -0
  580. loopx/control_plane/todos/contract.py +1476 -0
  581. loopx/control_plane/todos/decision_scope.py +554 -0
  582. loopx/control_plane/todos/deferred_resume.py +546 -0
  583. loopx/control_plane/todos/durable_completion.py +201 -0
  584. loopx/control_plane/todos/event_writeback.py +484 -0
  585. loopx/control_plane/todos/frontier_deadline.py +132 -0
  586. loopx/control_plane/todos/handoff_gate.py +283 -0
  587. loopx/control_plane/todos/handoff_mode.py +444 -0
  588. loopx/control_plane/todos/handoff_note.py +202 -0
  589. loopx/control_plane/todos/line_update.py +361 -0
  590. loopx/control_plane/todos/list_projection.py +205 -0
  591. loopx/control_plane/todos/markdown.py +199 -0
  592. loopx/control_plane/todos/monitor_metadata.py +88 -0
  593. loopx/control_plane/todos/mutation_authority.py +299 -0
  594. loopx/control_plane/todos/projection.py +655 -0
  595. loopx/control_plane/todos/quota_summary.py +1138 -0
  596. loopx/control_plane/todos/route_continuation.py +267 -0
  597. loopx/control_plane/todos/succession_warning.py +174 -0
  598. loopx/control_plane/todos/summary_item.py +223 -0
  599. loopx/control_plane/todos/text.py +30 -0
  600. loopx/control_plane/todos/todo_index.py +226 -0
  601. loopx/control_plane/todos/todo_summary.py +1458 -0
  602. loopx/control_plane/todos/unblock_resume.py +326 -0
  603. loopx/control_plane/todos/user_gate.py +263 -0
  604. loopx/control_plane/todos/write_hint.py +63 -0
  605. loopx/control_plane/todos/write_policy.py +135 -0
  606. loopx/control_plane/turn_driver/__init__.py +85 -0
  607. loopx/control_plane/turn_driver/codex_cli.py +502 -0
  608. loopx/control_plane/turn_driver/driver.py +355 -0
  609. loopx/control_plane/turn_driver/executor.py +1468 -0
  610. loopx/control_plane/turn_driver/loop_controller.py +669 -0
  611. loopx/control_plane/turn_driver/settlement.py +318 -0
  612. loopx/control_plane/turn_driver/transaction.py +375 -0
  613. loopx/control_plane/work_items/__init__.py +1 -0
  614. loopx/control_plane/work_items/attention_fields.py +56 -0
  615. loopx/control_plane/work_items/attention_item.py +77 -0
  616. loopx/control_plane/work_items/attention_queue.py +322 -0
  617. loopx/control_plane/work_items/attention_routing.py +213 -0
  618. loopx/control_plane/work_items/autonomous_candidates.py +135 -0
  619. loopx/control_plane/work_items/autonomous_replan_ack.py +276 -0
  620. loopx/control_plane/work_items/autonomous_replan_obligation.py +786 -0
  621. loopx/control_plane/work_items/backlog_hygiene.py +59 -0
  622. loopx/control_plane/work_items/capability_monitor_fallback.py +221 -0
  623. loopx/control_plane/work_items/delivery_batch_scale.py +66 -0
  624. loopx/control_plane/work_items/delivery_outcome.py +152 -0
  625. loopx/control_plane/work_items/delivery_signals.py +113 -0
  626. loopx/control_plane/work_items/execution_obligation.py +235 -0
  627. loopx/control_plane/work_items/goal_route_hint.py +320 -0
  628. loopx/control_plane/work_items/interaction_contract.py +1540 -0
  629. loopx/control_plane/work_items/issue_meta_surface.py +159 -0
  630. loopx/control_plane/work_items/lifecycle.py +139 -0
  631. loopx/control_plane/work_items/operator_inbox.py +266 -0
  632. loopx/control_plane/work_items/outcome_followthrough.py +69 -0
  633. loopx/control_plane/work_items/primary_action.py +326 -0
  634. loopx/control_plane/work_items/progress_observation.py +630 -0
  635. loopx/control_plane/work_items/project_asset.py +675 -0
  636. loopx/control_plane/work_items/repair_delta.py +693 -0
  637. loopx/control_plane/work_items/runtime_capability_reentry.py +168 -0
  638. loopx/control_plane/work_items/semantic_replan_writeback.py +177 -0
  639. loopx/control_plane/work_items/status_contract.py +49 -0
  640. loopx/control_plane/work_items/task_graph.py +1046 -0
  641. loopx/control_plane/work_items/task_lease.py +1254 -0
  642. loopx/control_plane/work_items/task_lease_settlement.py +422 -0
  643. loopx/control_plane/work_items/work_lane.py +510 -0
  644. loopx/control_plane/work_items/work_lane_context.py +161 -0
  645. loopx/demo.py +247 -0
  646. loopx/diagnose.py +633 -0
  647. loopx/doctor.py +1251 -0
  648. loopx/domain_packs/__init__.py +1 -0
  649. loopx/domain_packs/issue_fix.py +571 -0
  650. loopx/domain_packs/ml_experiment.py +854 -0
  651. loopx/domain_state.py +137 -0
  652. loopx/dreaming.py +706 -0
  653. loopx/entrypoint.py +16 -0
  654. loopx/event_sourced_state.py +981 -0
  655. loopx/execution_profile.py +286 -0
  656. loopx/experiments/__init__.py +1 -0
  657. loopx/experiments/planner_worker/__init__.py +1 -0
  658. loopx/experiments/planner_worker/contract.py +523 -0
  659. loopx/experiments/planner_worker/runtime.py +391 -0
  660. loopx/experiments/planner_worker/traex.py +461 -0
  661. loopx/explore_graph.py +11 -0
  662. loopx/extensions/__init__.py +1 -0
  663. loopx/extensions/bundled.py +28 -0
  664. loopx/extensions/execution_envelope.py +126 -0
  665. loopx/extensions/lark/__init__.py +11 -0
  666. loopx/extensions/lark/event_collector.py +478 -0
  667. loopx/extensions/lark/event_collector_runtime.py +506 -0
  668. loopx/extensions/lark/event_inbox.py +454 -0
  669. loopx/extensions/lark/extension.toml +88 -0
  670. loopx/extensions/lark/goal_channel.py +44 -0
  671. loopx/extensions/lark/goal_channel_contracts.py +388 -0
  672. loopx/extensions/lark/goal_channel_lifecycle.py +218 -0
  673. loopx/extensions/lark/goal_channel_runtime.py +792 -0
  674. loopx/extensions/lark/goal_channel_setup.py +805 -0
  675. loopx/extensions/lark/goal_channel_targets.py +215 -0
  676. loopx/extensions/lark/goal_channel_transport.py +281 -0
  677. loopx/extensions/lark/inbox_reactions.py +650 -0
  678. loopx/extensions/lark/inbox_reply.py +430 -0
  679. loopx/extensions/lark/presentation/__init__.py +11 -0
  680. loopx/extensions/lark/presentation/explore_results.py +2276 -0
  681. loopx/extensions/lark/presentation/explore_singleflight.py +127 -0
  682. loopx/extensions/lark/presentation/explore_source_guard.py +121 -0
  683. loopx/extensions/lark/presentation/explore_stage_document.py +703 -0
  684. loopx/extensions/lark/presentation/explore_visual_integrity.py +122 -0
  685. loopx/extensions/lark/presentation/explore_visual_readback.py +452 -0
  686. loopx/extensions/lark/presentation/explore_visual_styles.py +156 -0
  687. loopx/extensions/lark/presentation/issue_fix_surface.py +612 -0
  688. loopx/extensions/lark/presentation/kanban.py +2791 -0
  689. loopx/extensions/lark/presentation/message_card.py +112 -0
  690. loopx/extensions/lark/presentation/periodic_report.py +261 -0
  691. loopx/extensions/lark/presentation/projection_rows.py +600 -0
  692. loopx/extensions/lark/presentation/record_io.py +95 -0
  693. loopx/extensions/lark/presentation/sync_receipt.py +145 -0
  694. loopx/extensions/lark/private_json.py +40 -0
  695. loopx/extensions/lark/provider.py +86 -0
  696. loopx/extensions/lark/reviewer_notification.py +604 -0
  697. loopx/extensions/manifest.py +385 -0
  698. loopx/extensions/openviking_periodic_report/__init__.py +17 -0
  699. loopx/extensions/openviking_periodic_report/activation.py +173 -0
  700. loopx/extensions/openviking_periodic_report/extension.toml +17 -0
  701. loopx/extensions/openviking_periodic_report/provider.py +355 -0
  702. loopx/extensions/openviking_periodic_report/sink.py +117 -0
  703. loopx/extensions/openviking_semantic_preference/__init__.py +5 -0
  704. loopx/extensions/openviking_semantic_preference/extension.toml +16 -0
  705. loopx/extensions/openviking_semantic_preference/history_export.py +484 -0
  706. loopx/extensions/openviking_semantic_preference/project_peer.py +68 -0
  707. loopx/extensions/openviking_semantic_preference/provider.py +312 -0
  708. loopx/extensions/presentation.py +979 -0
  709. loopx/extensions/process_runtime.py +204 -0
  710. loopx/extensions/readiness.py +168 -0
  711. loopx/extensions/runtime.py +931 -0
  712. loopx/extensions/scaffold.py +335 -0
  713. loopx/feedback.py +581 -0
  714. loopx/file_lock.py +382 -0
  715. loopx/global_registry.py +842 -0
  716. loopx/global_risks.py +970 -0
  717. loopx/global_todos.py +568 -0
  718. loopx/handoff_budget.py +28 -0
  719. loopx/heartbeat_prequota.py +80 -0
  720. loopx/heartbeat_prompt.py +159 -0
  721. loopx/help_surface.py +516 -0
  722. loopx/history.py +1507 -0
  723. loopx/host_loop_activation.py +1311 -0
  724. loopx/host_mode_planner.py +991 -0
  725. loopx/install_contract.py +1 -0
  726. loopx/interface_budget.py +196 -0
  727. loopx/long_task_cadence.py +208 -0
  728. loopx/materials.py +185 -0
  729. loopx/ml_experiment.py +3 -0
  730. loopx/onboarding.py +214 -0
  731. loopx/opencode2_goal_mode/README.md +81 -0
  732. loopx/opencode2_goal_mode/__init__.py +9 -0
  733. loopx/opencode2_goal_mode/opencode2-goal-worker.mjs +1018 -0
  734. loopx/opencode_goal_mode/README.md +99 -0
  735. loopx/opencode_goal_mode/__init__.py +13 -0
  736. loopx/opencode_goal_mode/goal-bridge-runtime.mjs +858 -0
  737. loopx/opencode_goal_mode/loopx-goal.js +8 -0
  738. loopx/operator_gate.py +420 -0
  739. loopx/orchestration.py +127 -0
  740. loopx/paths.py +59 -0
  741. loopx/pi_goal_mode/README.md +67 -0
  742. loopx/pi_goal_mode/__init__.py +13 -0
  743. loopx/pi_goal_mode/loopx-goal.ts +254 -0
  744. loopx/pi_goal_mode/pi-goal-loop-runtime.mjs +574 -0
  745. loopx/pr_review.py +1206 -0
  746. loopx/presentation/__init__.py +1 -0
  747. loopx/presentation/explore_views.py +1334 -0
  748. loopx/presentation/markdown.py +61 -0
  749. loopx/presentation/projection_source_reconcile.py +140 -0
  750. loopx/presentation/public_safety.py +42 -0
  751. loopx/presentation/renderers/__init__.py +17 -0
  752. loopx/presentation/renderers/goal_channel_html.py +269 -0
  753. loopx/presentation/renderers/periodic_report_html.py +786 -0
  754. loopx/presentation/renderers/periodic_report_markdown.py +184 -0
  755. loopx/presentation/renderers/quota_event_markdown.py +116 -0
  756. loopx/presentation/renderers/quota_markdown.py +1112 -0
  757. loopx/presentation/renderers/status_markdown.py +1570 -0
  758. loopx/presentation/renderers/trajectory_hygiene_markdown.py +39 -0
  759. loopx/presentation/renderers/turn_envelope_markdown.py +33 -0
  760. loopx/presentation/sinks/__init__.py +5 -0
  761. loopx/presentation/sinks/openviking_periodic_report.py +7 -0
  762. loopx/presentation/static_site.py +691 -0
  763. loopx/presets.py +369 -0
  764. loopx/project_alias.py +217 -0
  765. loopx/project_map.py +589 -0
  766. loopx/project_prompt.py +1153 -0
  767. loopx/project_skill_cli.py +125 -0
  768. loopx/project_skill_delivery.py +470 -0
  769. loopx/project_uninstall.py +462 -0
  770. loopx/promotion_gate.py +197 -0
  771. loopx/quota.py +1197 -0
  772. loopx/ready_score.py +413 -0
  773. loopx/registry.py +621 -0
  774. loopx/registry_writability.py +64 -0
  775. loopx/release_candidate.py +148 -0
  776. loopx/release_manifest.py +316 -0
  777. loopx/repository_identity.py +100 -0
  778. loopx/review_packet.py +1024 -0
  779. loopx/rollout_event_log.py +505 -0
  780. loopx/runtime.py +112 -0
  781. loopx/self_update.py +750 -0
  782. loopx/session_runtime.py +418 -0
  783. loopx/skill_install_readback.py +500 -0
  784. loopx/slash_command_install.py +1393 -0
  785. loopx/slash_commands.py +264 -0
  786. loopx/state_backup.py +573 -0
  787. loopx/state_migration.py +350 -0
  788. loopx/state_projection.py +809 -0
  789. loopx/state_refresh.py +1416 -0
  790. loopx/status.py +1383 -0
  791. loopx/status_server.py +935 -0
  792. loopx/summary_all.py +725 -0
  793. loopx/terminal_bench_agent.py +2056 -0
  794. loopx/thread_agent_binding.py +408 -0
  795. loopx/todo_followups.py +168 -0
  796. loopx/todo_suggestion_prompt.py +204 -0
  797. loopx/todos.py +2229 -0
  798. loopx/turn_identity.py +17 -0
  799. loopx/upgrade.py +1083 -0
  800. loopx/visible_governance.py +667 -0
  801. loopx/visible_multi_agent_launcher.py +1253 -0
  802. loopx/visible_multi_agent_tmux.py +429 -0
  803. loopx/worker_bridge.py +1574 -0
  804. loopx-0.4.8.dist-info/METADATA +708 -0
  805. loopx-0.4.8.dist-info/RECORD +811 -0
  806. loopx-0.4.8.dist-info/WHEEL +5 -0
  807. loopx-0.4.8.dist-info/entry_points.txt +5 -0
  808. loopx-0.4.8.dist-info/licenses/LICENSE +202 -0
  809. loopx-0.4.8.dist-info/licenses/LICENSE-MIT +21 -0
  810. loopx-0.4.8.dist-info/licenses/NOTICE +6 -0
  811. loopx-0.4.8.dist-info/top_level.txt +1 -0
loopx/benchmark.py ADDED
@@ -0,0 +1,2875 @@
1
+ from __future__ import annotations
2
+
3
+ import importlib.util
4
+ import json
5
+ import os
6
+ import re
7
+ import shlex
8
+ import shutil
9
+ import subprocess
10
+ import sys
11
+ import tempfile
12
+ import time
13
+ from datetime import datetime, timezone
14
+ from pathlib import Path
15
+ from typing import Any, Iterable
16
+
17
+ from .worker_bridge import (
18
+ ACTIVE_USER_INTERVENTION_CHANNEL_CONTRACT_VERSION,
19
+ ACTIVE_USER_INTERVENTION_CHANNEL_SURFACE,
20
+ ACTIVE_USER_INTERVENTION_OBSERVATION_VERSION,
21
+ WORKER_BRIDGE_BENCHMARK_RUN_FORBIDDEN_PUBLIC_FIELDS,
22
+ WORKER_BRIDGE_BENCHMARK_RUN_REQUIRED_FIXED_FIELDS,
23
+ WORKER_BRIDGE_BENCHMARK_RUN_REQUIRED_TOP_LEVEL_FIELDS,
24
+ WORKER_BRIDGE_BENCHMARK_RUN_WRITEBACK_CONTRACT_VERSION,
25
+ WORKER_BRIDGE_SURFACE,
26
+ build_active_user_codex_simulator_contract,
27
+ build_active_user_intervention,
28
+ build_worker_bridge_install_contract,
29
+ )
30
+ from .benchmark_case_state import (
31
+ BENCHMARK_CASE_ACTIVE_STATE_PROOF_FIELDS,
32
+ BENCHMARK_CASE_ACTIVE_STATE_SCHEMA_VERSION,
33
+ benchmark_case_active_state_init_contract,
34
+ benchmark_case_active_state_path,
35
+ benchmark_case_goal_id,
36
+ )
37
+ from .benchmark_core import (
38
+ BENCHMARK_LIFECYCLE_STATE_SCHEMA_VERSION,
39
+ build_benchmark_candidate_source_boundary,
40
+ classify_benchmark_artifact_path,
41
+ classify_benchmark_candidate_source_path,
42
+ canonical_lifecycle,
43
+ filter_public_benchmark_artifact_paths,
44
+ )
45
+ from .benchmark_core.io import (
46
+ load_json_object as _load_json_object,
47
+ load_jsonl_objects as _load_jsonl_objects,
48
+ optional_float as _optional_float,
49
+ optional_positive_int as _optional_positive_int,
50
+ )
51
+ from .benchmark_adapters.agentissue import (
52
+ AGENTISSUE_BENCHMARK_ID,
53
+ AGENTISSUE_CODEX_CLI_RUNNER_EXECUTION_GATE_SCHEMA_VERSION,
54
+ AGENTISSUE_CODEX_CLI_RUNNER_FIRST_RUN_HANDOFF_SCHEMA_VERSION,
55
+ AGENTISSUE_CODEX_CLI_RUNNER_PRIVATE_SCRIPT_SCHEMA_VERSION,
56
+ AGENTISSUE_CODEX_CLI_RUNNER_REAL_RESULT_SCHEMA_VERSION,
57
+ AGENTISSUE_CODEX_CLI_RUNNER_RUN_GATE_SCHEMA_VERSION,
58
+ AGENTISSUE_CODEX_CLI_RUNNER_SYNTHETIC_STAGING_SCHEMA_VERSION,
59
+ AGENTISSUE_CODEX_CLI_RUNNER_TARGET_HANDOFF_SCHEMA_VERSION,
60
+ AGENTISSUE_CODEX_CLI_RUNNER_WORKFLOW_CHECK_SCHEMA_VERSION,
61
+ AGENTISSUE_CODEX_CLI_RUNNER_WRAPPER_SCHEMA_VERSION,
62
+ AGENTISSUE_DEFAULT_TAG,
63
+ build_agentissue_codex_cli_runner_wrapper,
64
+ materialize_agentissue_codex_cli_runner_execution_gate,
65
+ materialize_agentissue_codex_cli_runner_first_run_handoff,
66
+ materialize_agentissue_codex_cli_runner_private_script,
67
+ materialize_agentissue_codex_cli_runner_real_result,
68
+ materialize_agentissue_codex_cli_runner_run_gate,
69
+ materialize_agentissue_codex_cli_runner_synthetic_staging,
70
+ materialize_agentissue_codex_cli_runner_target_handoff,
71
+ materialize_agentissue_codex_cli_runner_workflow_check,
72
+ )
73
+ from .benchmark_adapters.skillsbench import (
74
+ BENCHMARK_MODEL_CONTROL_SCHEMA_VERSION,
75
+ CODEX_ACP_SET_MODEL_UNSUPPORTED_LABEL,
76
+ SKILLSBENCH_DEFAULT_DATASET,
77
+ SKILLSBENCH_DEFAULT_MODEL,
78
+ SKILLSBENCH_DEFAULT_ROUTE,
79
+ SKILLSBENCH_DEFAULT_TASK,
80
+ SKILLSBENCH_LOCAL_DRIVER_A2A_CONTRACT_SCHEMA_VERSION,
81
+ SKILLSBENCH_LOCAL_DRIVER_A2A_PAIR_ROUTES,
82
+ SKILLSBENCH_APP_SERVER_GOAL_WORKER_CONTRACT_SCHEMA_VERSION,
83
+ SKILLSBENCH_WORKER_HANDSHAKE_PREFLIGHT_SCHEMA_VERSION,
84
+ SKILLSBENCH_PRODUCT_MODE_CASE_GOAL_ID,
85
+ SKILLSBENCH_PRODUCT_MODE_CASE_STATE_PATH,
86
+ SKILLSBENCH_ROUTES,
87
+ build_skillsbench_benchmark_run,
88
+ build_skillsbench_app_server_goal_worker_contract,
89
+ build_skillsbench_benchflow_result_benchmark_run,
90
+ build_skillsbench_local_driver_a2a_contract,
91
+ build_skillsbench_run_permission_policy,
92
+ build_skillsbench_worker_handshake_preflight,
93
+ skillsbench_recommended_action,
94
+ skillsbench_job_name,
95
+ skillsbench_route_contract,
96
+ skillsbench_runner_error_attribution,
97
+ skillsbench_runner_error_fingerprint,
98
+ )
99
+ from .benchmark_adapters.terminal_bench import (
100
+ TERMINAL_BENCH_WORKER_BRIDGE_ACTIVE_USER_MOUNT_TARGET,
101
+ TERMINAL_BENCH_WORKER_BRIDGE_ACTIVE_USER_FEED_JSONL,
102
+ TERMINAL_BENCH_WORKER_BRIDGE_ACTIVE_USER_OBSERVATION_JSON,
103
+ TERMINAL_BENCH_WORKER_BRIDGE_BENCHMARK_RUN_JSON,
104
+ TERMINAL_BENCH_WORKER_BRIDGE_COUNTER_TRACE_JSON,
105
+ TERMINAL_BENCH_WORKER_BRIDGE_ACTIVE_USER_HOST_DIR_PLACEHOLDER,
106
+ TERMINAL_BENCH_WORKER_BRIDGE_PROJECT_ROOT_PLACEHOLDER,
107
+ TERMINAL_BENCH_WORKER_BRIDGE_RUNTIME_ROOT_PLACEHOLDER,
108
+ TERMINAL_BENCH_MODES,
109
+ TERMINAL_BENCH_DEFAULT_DATASET,
110
+ TERMINAL_BENCH_DEFAULT_TASK,
111
+ TERMINAL_BENCH_DEFAULT_MODEL,
112
+ TERMINAL_BENCH_CASE_GOAL_ID,
113
+ TERMINAL_BENCH_CASE_STATE_PATH,
114
+ TERMINAL_BENCH_HARBOR_REF,
115
+ TERMINAL_BENCH_PREFLIGHT_MODE,
116
+ TERMINAL_BENCH_CODEX_LOOPX_PREFLIGHT_MODE,
117
+ TERMINAL_BENCH_ACTIVE_USER_ASSISTED_TREATMENT_PREFLIGHT_MODE,
118
+ TERMINAL_BENCH_ACTIVE_USER_ASSISTED_TREATMENT_PREFLIGHT_SCHEMA,
119
+ TERMINAL_BENCH_ACTIVE_USER_ASSISTED_OBSERVATION_FIXTURE_MODE,
120
+ TERMINAL_BENCH_ACTIVE_USER_ASSISTED_OBSERVATION_FIXTURE_SCHEMA,
121
+ TERMINAL_BENCH_ACTIVE_USER_SIMULATOR_INJECTION_CHANNEL_SCHEMA,
122
+ TERMINAL_BENCH_ACTIVE_USER_PRIVATE_LAUNCHER_PLAN_SCHEMA,
123
+ TERMINAL_BENCH_TASK_MATERIAL_READINESS_SCHEMA,
124
+ TERMINAL_BENCH_POST_LAUNCH_MATERIALIZATION_SCHEMA,
125
+ TERMINAL_BENCH_COMPACT_FAILURE_MARKER_SCHEMA,
126
+ TERMINAL_BENCH_RESULT_FINALIZATION_GATE_SCHEMA,
127
+ TERMINAL_BENCH_RUN_LEDGER_CLOSEOUT_SCHEMA,
128
+ TERMINAL_BENCH_ENVIRONMENT_SETUP_READINESS_SCHEMA,
129
+ TERMINAL_BENCH_ENVIRONMENT_SETUP_PROBE_GATE_SCHEMA,
130
+ TERMINAL_BENCH_ENVIRONMENT_SETUP_PROBE_LAUNCH_SCHEMA,
131
+ TERMINAL_BENCH_CASE_RUN_LAUNCH_SCHEMA,
132
+ TERMINAL_BENCH_LAUNCH_MATERIALIZATION_OBSERVATION_SCHEMA,
133
+ TERMINAL_BENCH_AGENT_SETUP_READINESS_SCHEMA,
134
+ TERMINAL_BENCH_WORKER_SETUP_DIAGNOSTIC_SCHEMA,
135
+ TERMINAL_BENCH_SETUP_TIMEOUT_REPAIR_PROFILE_SCHEMA,
136
+ TERMINAL_BENCH_CODEX_INSTALL_STRATEGY_RUNTIME_INSTALL_IF_MISSING,
137
+ TERMINAL_BENCH_CODEX_INSTALL_STRATEGY_REQUIRE_EXISTING,
138
+ TERMINAL_BENCH_CODEX_INSTALL_STRATEGIES,
139
+ TERMINAL_BENCH_CODEX_RUNTIME_INSTALL_ALLOW_ENVIRONMENT_HOSTS,
140
+ TERMINAL_BENCH_WORKER_CODEX_MATERIALIZATION_STRATEGY_WORKER_PATH,
141
+ TERMINAL_BENCH_WORKER_CODEX_MATERIALIZATION_STRATEGY_RUNTIME_EXTENDED,
142
+ TERMINAL_BENCH_WORKER_CODEX_MATERIALIZATION_STRATEGIES,
143
+ TERMINAL_BENCH_SETUP_TIMEOUT_REPAIR_AGENT_TIMEOUT_MULTIPLIER,
144
+ TERMINAL_BENCH_SETUP_TIMEOUT_REPAIR_AGENT_SETUP_TIMEOUT_MULTIPLIER,
145
+ TERMINAL_BENCH_SETUP_TIMEOUT_REPAIR_CODEX_PREFLIGHT_TIMEOUT_SEC,
146
+ TERMINAL_BENCH_WORKER_SETUP_DIAGNOSTIC_FILE,
147
+ TERMINAL_BENCH_DETACHED_PROCESS_STATES,
148
+ TERMINAL_BENCH_ACTIVE_JOB_STALE_SECONDS,
149
+ TERMINAL_BENCH_ACTIVE_USER_SIMULATOR_SETTING,
150
+ TERMINAL_BENCH_ACTIVE_USER_SIMULATOR_INJECTION_FIRST_BLOCKER,
151
+ TERMINAL_BENCH_ACTIVE_USER_REAL_WORKER_OBSERVATION_FIRST_BLOCKER,
152
+ TERMINAL_BENCH_ACTIVE_USER_OBSERVATION_FIXTURE_FIRST_BLOCKER,
153
+ TERMINAL_BENCH_HARDENED_CODEX_BASELINE_PREFLIGHT_MODE,
154
+ TERMINAL_BENCH_HARDENED_CODEX_BASELINE_MODE,
155
+ TERMINAL_BENCH_CODEX_GOAL_MODE_BASELINE_MODE,
156
+ TERMINAL_BENCH_HARDENED_CODEX_LEGACY_CALIBRATION_MODE,
157
+ TERMINAL_BENCH_HARDENED_CODEX_BASELINE_MODES,
158
+ TERMINAL_BENCH_HARDENED_CODEX_BASELINE_SURFACE,
159
+ TERMINAL_BENCH_CODEX_GOAL_MODE_BASELINE_SURFACE,
160
+ TERMINAL_BENCH_HARDENED_CODEX_CALIBRATION_MODE,
161
+ TERMINAL_BENCH_HARDENED_CODEX_CALIBRATION_SURFACE,
162
+ TERMINAL_BENCH_MANAGED_AGENT_IMPORT_PATH,
163
+ TERMINAL_BENCH_MANAGED_POLICY_VERSION,
164
+ TERMINAL_BENCH_MANAGED_BEHAVIOR_SPEC_ID,
165
+ TERMINAL_BENCH_MANAGED_CODEX_LOOPX_KWARGS,
166
+ TERMINAL_BENCH_LOOPX_ACCESS_PACKET_VERSION,
167
+ TERMINAL_BENCH_LOOPX_ACCESS_PACKET_MODE_FULL,
168
+ TERMINAL_BENCH_LOOPX_ACCESS_PACKET_MODE_COMPACT,
169
+ TERMINAL_BENCH_LOOPX_ACCESS_PACKET_MODE_NONE,
170
+ TERMINAL_BENCH_LOOPX_ACCESS_PACKET_MODES,
171
+ TERMINAL_BENCH_LOOPX_INTERACTION_COUNTERS_VERSION,
172
+ TERMINAL_BENCH_OVERHEAD_ATTRIBUTION_COUNTERS_VERSION,
173
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_CONTRACT_VERSION,
174
+ TERMINAL_BENCH_LOOPX_ACCESS_PACKET_COMMANDS,
175
+ TERMINAL_BENCH_LOOPX_ACTIVE_USER_OBSERVE_COMMAND,
176
+ TERMINAL_BENCH_LOOPX_COUNTER_TRACE_COMMANDS,
177
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_CALL_POLICY_VERSION,
178
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_CALL_POLICY_MODE,
179
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_DEFAULT_REQUIRED_CALLS,
180
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_OPTIONAL_CONTEXT_CALLS,
181
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_REQUIRED_CALL_MINIMUM,
182
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_PLACEHOLDER_POLICY_VERSION,
183
+ TERMINAL_BENCH_LOOPX_INTERFACE_SURFACE,
184
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_AVAILABLE,
185
+ TERMINAL_BENCH_LOOPX_CLI_BRIDGE_SURFACE,
186
+ TERMINAL_BENCH_CODEX_WORKER_CLI_BRIDGE_SURFACE,
187
+ TERMINAL_BENCH_CODEX_AUTH_SURFACE_NAMES,
188
+ TERMINAL_BENCH_BOOL_AGENT_ENV_NAMES,
189
+ TERMINAL_BENCH_BOOL_AGENT_ENV_VALUES,
190
+ TERMINAL_BENCH_REDACTED_ENV_VALUE_MARKERS,
191
+ TERMINAL_BENCH_EXTRA_PROBE_PATHS,
192
+ TERMINAL_BENCH_COUNTER_TRACE_FILE,
193
+ TERMINAL_BENCH_WORKER_BENCHMARK_RUN_FILE,
194
+ TERMINAL_BENCH_DEFAULT_AGENT_TIMEOUT_SECONDS,
195
+ TERMINAL_BENCH_TRUE_LONG_TASK_BAR_SECONDS,
196
+ TERMINAL_BENCH_PREFERRED_HOURS_SCALE_BAR_SECONDS,
197
+ TERMINAL_BENCH_OFFICIAL_TIMEOUT_MULTIPLIER,
198
+ TERMINAL_BENCH_PRIVATE_EXTENDED_AGENT_TIMEOUT_MULTIPLIER,
199
+ TERMINAL_BENCH_PRIVATE_EXTENDED_AGENT_SETUP_TIMEOUT_MULTIPLIER,
200
+ TERMINAL_BENCH_EPISODE_POLICY_VERSION,
201
+ TERMINAL_BENCH_EPISODE_POLICY_MODE,
202
+ TERMINAL_BENCH_DEFAULT_EPISODE_CHECKPOINT_INTERVAL_SECONDS,
203
+ TERMINAL_BENCH_TIMEOUT_MULTIPLIER_KEYS,
204
+ TERMINAL_BENCH_VERIFIER_FAILURE_LOG_FILES,
205
+ TERMINAL_BENCH_VERIFIER_FAILURE_GLOB_PATTERNS,
206
+ TERMINAL_BENCH_CODEX_RUNTIME_GOAL_TOOL_NAMES,
207
+ TERMINAL_BENCH_WORKER_CASE_SUCCESS_VALIDATION_SCOPES,
208
+ TERMINAL_BENCH_WORKER_CONNECTIVITY_VALIDATION_SCOPES,
209
+ TERMINAL_BENCH_NON_BLOCKING_WORKER_SETUP_LABELS,
210
+ _compact_exception_kind,
211
+ _terminal_bench_agent_failure_attribution_labels,
212
+ agent_kwargs_from_invocation,
213
+ _compact_truthy_flag,
214
+ _terminal_bench_lock_first_agent_kwargs,
215
+ _terminal_bench_lock_worker_materialization_probe_only,
216
+ _compact_positive_int,
217
+ _benchmark_lifecycle_ready_preflight,
218
+ _benchmark_run_environment_setup_failure_context,
219
+ _terminal_bench_harbor_run_help_capability,
220
+ _terminal_bench_environment_setup_probe_command_template,
221
+ build_terminal_bench_environment_setup_probe_gate,
222
+ launch_terminal_bench_environment_setup_probe,
223
+ launch_terminal_bench_worker_materialization_probe,
224
+ _detached_process_state_from_pid_file,
225
+ _process_state_from_poll,
226
+ wait_for_terminal_bench_launch_materialization,
227
+ observe_terminal_bench_post_materialization_closeout,
228
+ build_terminal_bench_harbor_resume_command,
229
+ _terminal_bench_resume_recommended,
230
+ _terminal_bench_active_job_resume_contract,
231
+ resume_terminal_bench_materialized_job,
232
+ summarize_terminal_bench_prelaunch_job_root_guard,
233
+ launch_terminal_bench_case_run,
234
+ poll_terminal_bench_worker_materialization_probe,
235
+ build_terminal_bench_result_finalization_gate,
236
+ build_terminal_bench_active_user_injection_channel_probe,
237
+ build_terminal_bench_active_user_observation_fixture,
238
+ _empty_codex_runtime_goal_tool_calls,
239
+ _merge_numeric_counts,
240
+ _compact_trace_event_text,
241
+ _trajectory_codex_runtime_goal_tool_calls,
242
+ _terminal_bench_verifier_failure_attribution,
243
+ _terminal_bench_score_failure_attribution,
244
+ _terminal_bench_worker_validation_claim_kind,
245
+ _is_pre_worker_agent_setup_failure,
246
+ _is_environment_setup_failure_before_worker,
247
+ _terminal_bench_duration_tier,
248
+ _terminal_bench_environment_setup_failure_context,
249
+ _compactable_benchmark_run_v0_payload,
250
+ _terminal_bench_non_blocking_setup_label,
251
+ _terminal_bench_worker_materialization_probe_contract,
252
+ _terminal_bench_worker_startup_blocker,
253
+ _invocation_arg_value,
254
+ _redacted_agent_kwargs,
255
+ _numeric_metric_totals,
256
+ _reward_from_trial_result,
257
+ _first_numeric_reward,
258
+ _terminal_bench_finished_phase,
259
+ _terminal_bench_official_zero_observation,
260
+ _official_score_from_harbor_stats,
261
+ _numeric_reward_value,
262
+ _iso_duration_seconds,
263
+ _first_timeout_multiplier,
264
+ _is_default_timeout_multiplier,
265
+ _format_harbor_multiplier,
266
+ _terminal_bench_dataset_args,
267
+ _public_safe_benchmark_label,
268
+ build_terminal_bench_single_agent_episode_policy,
269
+ _terminal_bench_timeout_policy,
270
+ _counter_trace_interaction_counters,
271
+ _total_from_counter_map,
272
+ _terminal_bench_overhead_attribution_counters,
273
+ build_terminal_bench_harbor_result_benchmark_run,
274
+ _probe_path,
275
+ _probe_env,
276
+ _looks_like_redacted_env_value,
277
+ _split_env_assignment,
278
+ sanitize_terminal_bench_private_runner_env,
279
+ _prepend_env_path_entry,
280
+ build_terminal_bench_private_runner_env,
281
+ _apply_terminal_bench_private_default_timeout_policy,
282
+ _private_runner_loopx_project_root,
283
+ _private_runner_loopx_runtime_root,
284
+ _private_runner_active_user_host_dir,
285
+ _private_runner_absolute_jobs_dir,
286
+ _private_runner_command_kwargs,
287
+ build_terminal_bench_task_material_readiness,
288
+ _terminal_bench_setup_timeout_repair_profile,
289
+ build_terminal_bench_private_runner_launch,
290
+ _terminal_bench_run_ledger_closeout_templates,
291
+ _terminal_bench_compact_failure_marker,
292
+ summarize_terminal_bench_post_launch_materialization,
293
+ _terminal_bench_launch_timeout_multiplier_policy,
294
+ _terminal_bench_agent_setup_readiness,
295
+ summarize_terminal_bench_private_runner_launch,
296
+ normalize_terminal_bench_private_runner_invocation,
297
+ _command_present,
298
+ resolve_terminal_bench_runner_binary,
299
+ _probe_command,
300
+ collect_terminal_bench_managed_preflight_surface,
301
+ _managed_preflight_first_blocker,
302
+ build_terminal_bench_loopx_interaction_counters,
303
+ build_terminal_bench_loopx_cli_bridge_contract,
304
+ build_terminal_bench_case_state_init_contract,
305
+ collect_terminal_bench_loopx_cli_bridge_trace,
306
+ build_terminal_bench_active_user_private_launcher_plan,
307
+ build_terminal_bench_loopx_access_packet,
308
+ build_terminal_bench_loopx_access_packet_fixture,
309
+ _mode_contract,
310
+ build_terminal_bench_managed_harbor_command,
311
+ build_terminal_bench_benchmark_run,
312
+ terminal_bench_recommended_action,
313
+
314
+ )
315
+ from .benchmark_adapters.agents_last_exam import (
316
+ AGENTS_LAST_EXAM_BENCHMARK_ID,
317
+ AGENTS_LAST_EXAM_RESULT_INGEST_POLICY_VERSION,
318
+ AGENTS_LAST_EXAM_LOCAL_PREFLIGHT_SCHEMA_VERSION,
319
+ AGENTS_LAST_EXAM_LOCAL_DRY_RUN_PLAN_SCHEMA_VERSION,
320
+ AGENTS_LAST_EXAM_LOCAL_RUNNER_READINESS_SCHEMA_VERSION,
321
+ AGENTS_LAST_EXAM_LOCAL_SOURCE_READINESS_SCHEMA_VERSION,
322
+ AGENTS_LAST_EXAM_TASK_MATERIAL_READINESS_SCHEMA_VERSION,
323
+ AGENTS_LAST_EXAM_BAKED_TASK_INPUT_READINESS_SCHEMA_VERSION,
324
+ AGENTS_LAST_EXAM_BAKED_TASK_INPUT_SCAN_SCHEMA_VERSION,
325
+ AGENTS_LAST_EXAM_CANDIDATE_TASK_DATA_SCAN_SCHEMA_VERSION,
326
+ AGENTS_LAST_EXAM_LOCAL_LAUNCH_PACKET_SCHEMA_VERSION,
327
+ AGENTS_LAST_EXAM_LOCAL_EXACT_DRY_RUN_RESULT_SCHEMA_VERSION,
328
+ AGENTS_LAST_EXAM_HOST_CODEX_CLI_ROUTE_SCHEMA_VERSION,
329
+ AGENTS_LAST_EXAM_HOST_CODEX_CUA_NO_TASK_SMOKE_SCHEMA_VERSION,
330
+ AGENTS_LAST_EXAM_VALIDATION_RUN_GATE_SCHEMA_VERSION,
331
+ AGENTS_LAST_EXAM_TRACE_PUBLICNESS,
332
+ AGENTS_LAST_EXAM_CASE_GOAL_ID,
333
+ AGENTS_LAST_EXAM_CASE_STATE_PATH,
334
+ AGENTS_LAST_EXAM_DEFAULT_DOCKER_IMAGE,
335
+ AGENTS_LAST_EXAM_DEFAULT_ALT_DOCKER_IMAGE,
336
+ AGENTS_LAST_EXAM_DEFAULT_SNAPSHOT,
337
+ AGENTS_LAST_EXAM_DEFAULT_REPO_URL,
338
+ AGENTS_LAST_EXAM_RAW_SURFACES_EXCLUDED,
339
+ _AGENTS_LAST_EXAM_REQUIRES_TASK_DATA_RE,
340
+ _agents_last_exam_public_id,
341
+ _agents_last_exam_first_public_id,
342
+ _agents_last_exam_parse_int,
343
+ build_agents_last_exam_local_exact_dry_run_result,
344
+ _agents_last_exam_event_type_counts,
345
+ _agents_last_exam_nested,
346
+ _agents_last_exam_docker_image_metadata,
347
+ _agents_last_exam_public_image_metadata,
348
+ _agents_last_exam_disk_headroom,
349
+ build_agents_last_exam_local_preflight,
350
+ build_agents_last_exam_local_dry_run_plan,
351
+ _agents_last_exam_runner_binary_probe,
352
+ _agents_last_exam_python_module_probe,
353
+ _agents_last_exam_runner_binary_requires_python_module,
354
+ _agents_last_exam_codex_cli_probe,
355
+ _agents_last_exam_cua_mcp_assets_probe,
356
+ build_agents_last_exam_host_codex_cli_route,
357
+ _agents_last_exam_codex_exec_surface_probe,
358
+ _agents_last_exam_codex_mcp_config_probe,
359
+ _agents_last_exam_fake_cua_server,
360
+ _agents_last_exam_cua_mcp_test_probe,
361
+ build_agents_last_exam_host_codex_cua_no_task_smoke,
362
+ build_agents_last_exam_host_codex_cua_no_task_smoke_from_environment,
363
+ _agents_last_exam_boundary_flag,
364
+ _agents_last_exam_ready_input,
365
+ _agents_last_exam_source_freshness_input,
366
+ _agents_last_exam_case_state_init_contract_input,
367
+ build_agents_last_exam_validation_run_gate,
368
+ _agents_last_exam_normalized_repo_label,
369
+ _agents_last_exam_source_git_metadata,
370
+ build_agents_last_exam_local_source_readiness,
371
+ _agents_last_exam_public_task_parts,
372
+ _agents_last_exam_public_task_list_membership,
373
+ _agents_last_exam_bool_requirement,
374
+ build_agents_last_exam_baked_task_input_readiness,
375
+ build_agents_last_exam_baked_task_input_scan,
376
+ _agents_last_exam_task_data_source_readiness,
377
+ build_agents_last_exam_task_material_readiness,
378
+ _agents_last_exam_public_selected_task_scan,
379
+ _agents_last_exam_requires_task_data_line_scan,
380
+ build_agents_last_exam_candidate_task_data_scan,
381
+ _agents_last_exam_relative_file_probe,
382
+ build_agents_last_exam_local_launch_packet,
383
+ build_agents_last_exam_local_runner_readiness,
384
+ build_agents_last_exam_result_benchmark_report,
385
+ )
386
+
387
+
388
+ BENCHMARK_CLAIM_REVIEW_SCHEMA_VERSION = "benchmark_claim_review_v0"
389
+ BENCHMARK_LEARNING_LEDGER_SCHEMA_VERSION = "benchmark_learning_ledger_v0"
390
+ BENCHMARK_ATTEMPT_LEARNING_GATE_SCHEMA_VERSION = (
391
+ "benchmark_attempt_learning_gate_v0"
392
+ )
393
+ BENCHMARK_ADAPTER_KWARG_ABSORPTION_REVIEW_SCHEMA_VERSION = (
394
+ "benchmark_adapter_kwarg_absorption_review_v0"
395
+ )
396
+ BENCHMARK_VERIFIER_ATTRIBUTION_REVIEW_SCHEMA_VERSION = (
397
+ "benchmark_verifier_attribution_review_v0"
398
+ )
399
+ BENCHMARK_RUNNER_INVARIANT_REVIEW_SCHEMA_VERSION = (
400
+ "benchmark_runner_invariant_review_v0"
401
+ )
402
+ def _claim_review_numeric(value: Any) -> float | None:
403
+ if value is None or isinstance(value, bool):
404
+ return None
405
+ if isinstance(value, (int, float)):
406
+ return float(value)
407
+ if isinstance(value, str):
408
+ try:
409
+ return float(value)
410
+ except ValueError:
411
+ return None
412
+ return None
413
+
414
+
415
+ def _claim_review_run_mode(run: dict[str, Any]) -> str:
416
+ return str(run.get("mode") or "").strip().lower().replace("_", "-")
417
+
418
+
419
+ def _claim_review_run_score(run: dict[str, Any]) -> float | None:
420
+ official = run.get("official_task_score") if isinstance(run.get("official_task_score"), dict) else {}
421
+ return _claim_review_numeric(official.get("value"))
422
+
423
+
424
+ def _claim_review_worker_evidence(run: dict[str, Any]) -> dict[str, Any]:
425
+ interaction = run.get("interaction_counters") if isinstance(run.get("interaction_counters"), dict) else {}
426
+ calls = interaction.get("loopx_cli_calls") if isinstance(interaction.get("loopx_cli_calls"), dict) else {}
427
+ worker_cli_total = run.get("worker_loopx_cli_call_total")
428
+ if not isinstance(worker_cli_total, int) or isinstance(worker_cli_total, bool):
429
+ worker_cli_total = calls.get("total", 0)
430
+ if not isinstance(worker_cli_total, int) or isinstance(worker_cli_total, bool):
431
+ worker_cli_total = 0
432
+ controller_action_decisions = interaction.get("controller_action_decisions")
433
+ if not isinstance(controller_action_decisions, int) or isinstance(
434
+ controller_action_decisions, bool
435
+ ):
436
+ controller_action_decisions = 0
437
+ heartbeat_count = interaction.get("heartbeat_count")
438
+ if not isinstance(heartbeat_count, int) or isinstance(heartbeat_count, bool):
439
+ heartbeat_count = 0
440
+ state_reads = interaction.get("loopx_state_reads")
441
+ if not isinstance(state_reads, int) or isinstance(state_reads, bool):
442
+ state_reads = 0
443
+ state_writes = interaction.get("loopx_state_writes")
444
+ if not isinstance(state_writes, int) or isinstance(state_writes, bool):
445
+ state_writes = 0
446
+ outer_controller_present = bool(
447
+ interaction.get("loopx_automation_loop") is True
448
+ and (
449
+ interaction.get("controller_trace_present") is True
450
+ or controller_action_decisions > 0
451
+ or heartbeat_count > 0
452
+ or state_reads > 0
453
+ or state_writes > 0
454
+ )
455
+ )
456
+ observation = run.get("active_user_observation") if isinstance(run.get("active_user_observation"), dict) else {}
457
+ worker_file_count = run.get("worker_benchmark_run_schema_ok_count")
458
+ if not isinstance(worker_file_count, int) or isinstance(worker_file_count, bool):
459
+ worker_file_count = 0
460
+ present = bool(
461
+ worker_cli_total > 0
462
+ or worker_file_count > 0
463
+ or outer_controller_present
464
+ or observation.get("observed_after_worker_start")
465
+ or observation.get("worker_observation_proof")
466
+ )
467
+ return {
468
+ "worker_loopx_cli_call_total": worker_cli_total,
469
+ "worker_benchmark_run_schema_ok_count": worker_file_count,
470
+ "outer_loopx_controller_present": outer_controller_present,
471
+ "outer_loopx_controller_action_decisions": controller_action_decisions,
472
+ "outer_loopx_heartbeat_count": heartbeat_count,
473
+ "loopx_state_reads": state_reads,
474
+ "loopx_state_writes": state_writes,
475
+ "active_user_observed_after_worker_start": bool(
476
+ observation.get("observed_after_worker_start")
477
+ or observation.get("worker_observation_proof")
478
+ ),
479
+ "present": present,
480
+ }
481
+
482
+
483
+ def _compact_worker_start_status_kind(worker_start_status: Any) -> str:
484
+ """Classify compact worker-start state emitted by runner reducers."""
485
+
486
+ if not isinstance(worker_start_status, str) or not worker_start_status.strip():
487
+ return ""
488
+ status = worker_start_status.strip()
489
+ if status == "pre_worker_agent_setup_failed":
490
+ return "agent_setup_failure"
491
+ if status == "environment_setup_failed_before_worker":
492
+ return "environment_setup_failure"
493
+ return ""
494
+
495
+
496
+ def _claim_review_exception_kind_count(run: dict[str, Any], kind: str) -> int:
497
+ trials = run.get("trials")
498
+ if not isinstance(trials, list):
499
+ return 0
500
+ return sum(
501
+ 1
502
+ for trial in trials
503
+ if isinstance(trial, dict)
504
+ and _compact_exception_kind(trial.get("exception_type")) == kind
505
+ )
506
+
507
+
508
+ def _claim_review_worker_start_status_kind_count(
509
+ run: dict[str, Any],
510
+ kind: str,
511
+ ) -> int:
512
+ trials = run.get("trials")
513
+ count = 0
514
+ if isinstance(run.get("worker_start_status"), str):
515
+ count += int(_compact_worker_start_status_kind(run.get("worker_start_status")) == kind)
516
+ if not isinstance(trials, list):
517
+ return count
518
+ return count + sum(
519
+ 1
520
+ for trial in trials
521
+ if isinstance(trial, dict)
522
+ and _compact_worker_start_status_kind(trial.get("worker_start_status")) == kind
523
+ )
524
+
525
+
526
+ def _claim_review_worker_startup_blocker_observed(run: dict[str, Any]) -> bool:
527
+ if _compact_positive_int(run.get("worker_startup_blocker_count")):
528
+ return True
529
+ for field in (
530
+ "worker_bridge_materialization_status",
531
+ "worker_bridge_materialization_blocker",
532
+ "pre_worker_startup_blocker",
533
+ "first_blocker",
534
+ "repeat_blocked_by",
535
+ ):
536
+ value = run.get(field)
537
+ if isinstance(value, str) and value.strip():
538
+ text = value.strip()
539
+ if text == "pre_worker_startup_blocker_recorded":
540
+ return True
541
+ if field == "pre_worker_startup_blocker" and text != "none":
542
+ return True
543
+ outcome = run.get("worker_bridge_outcome")
544
+ if isinstance(outcome, dict):
545
+ return _claim_review_worker_startup_blocker_observed(outcome)
546
+ return False
547
+
548
+
549
+ def _claim_review_failure_labels(run: dict[str, Any]) -> list[str]:
550
+ labels = run.get("failure_attribution_labels")
551
+ compact_labels = [
552
+ str(label)
553
+ for label in labels or []
554
+ if isinstance(label, (str, int, float)) and not isinstance(label, bool)
555
+ ] if isinstance(labels, list) else []
556
+ if _claim_review_exception_kind_count(run, "agent_setup_timeout"):
557
+ compact_labels.append("agent_setup_timeout_before_worker_start")
558
+ if _claim_review_exception_kind_count(run, "agent_setup_failure"):
559
+ compact_labels.append("agent_setup_failed_before_worker_start")
560
+ if _claim_review_agent_timeout_count(run):
561
+ compact_labels.append("agent_timeout_before_solution_completion")
562
+ if _claim_review_worker_start_status_kind_count(run, "agent_setup_failure"):
563
+ compact_labels.append("agent_setup_failed_before_worker_start")
564
+ if _claim_review_worker_start_status_kind_count(run, "environment_setup_failure"):
565
+ compact_labels.append("environment_setup_failed_before_worker")
566
+ if _claim_review_worker_startup_blocker_observed(run):
567
+ compact_labels.append("pre_worker_startup_blocker_recorded")
568
+ return list(dict.fromkeys(compact_labels))[:8]
569
+
570
+
571
+ def _claim_review_agent_timeout_count(run: dict[str, Any]) -> int:
572
+ return _claim_review_exception_kind_count(run, "agent_timeout")
573
+
574
+
575
+ def _claim_review_score_failure_attribution(run: dict[str, Any]) -> str:
576
+ value = run.get("score_failure_attribution")
577
+ text = str(value).strip() if isinstance(value, str) and value.strip() else "none"
578
+ if text == "none" and _claim_review_exception_kind_count(run, "agent_setup_timeout"):
579
+ return "agent_setup_timeout_score_failure"
580
+ if text == "none" and _claim_review_exception_kind_count(run, "agent_setup_failure"):
581
+ return "agent_setup_score_failure"
582
+ if text == "none" and (
583
+ _claim_review_worker_start_status_kind_count(run, "agent_setup_failure")
584
+ or _claim_review_worker_start_status_kind_count(
585
+ run,
586
+ "environment_setup_failure",
587
+ )
588
+ or _claim_review_worker_startup_blocker_observed(run)
589
+ ):
590
+ return "agent_setup_score_failure"
591
+ if text == "none" and _claim_review_agent_timeout_count(run):
592
+ return "agent_timeout_score_failure"
593
+ return text
594
+
595
+
596
+ def _claim_review_pick_runs(
597
+ runs: list[dict[str, Any]],
598
+ ) -> tuple[dict[str, Any] | None, dict[str, Any] | None]:
599
+ baseline: dict[str, Any] | None = None
600
+ treatment: dict[str, Any] | None = None
601
+ for run in runs:
602
+ mode = _claim_review_run_mode(run)
603
+ job_name = str(run.get("job_name") or "").lower().replace("_", "-")
604
+ if baseline is None and (
605
+ "hardened-codex" in mode
606
+ or "bare-codex" in mode
607
+ or run.get("hardened_install_baseline") is True
608
+ ):
609
+ baseline = run
610
+ if treatment is None and (
611
+ "codex-loopx" in mode
612
+ or "codex-loopx" in job_name
613
+ or _claim_review_worker_evidence(run)["present"]
614
+ ):
615
+ treatment = run
616
+ if baseline is None and runs:
617
+ baseline = runs[0]
618
+ if treatment is None and len(runs) > 1:
619
+ treatment = runs[1]
620
+ return baseline, treatment
621
+
622
+
623
+ def build_benchmark_claim_review(
624
+ benchmark_comparison: dict[str, Any],
625
+ *,
626
+ benchmark_runs: Iterable[dict[str, Any]] = (),
627
+ ) -> dict[str, Any]:
628
+ """Review compact benchmark evidence without reading raw artifacts."""
629
+
630
+ runs = [run for run in benchmark_runs if isinstance(run, dict)]
631
+ baseline, treatment = _claim_review_pick_runs(runs)
632
+ official_delta = _claim_review_numeric(
633
+ benchmark_comparison.get("official_task_score_delta")
634
+ )
635
+ if official_delta is None and baseline and treatment:
636
+ baseline_score = _claim_review_run_score(baseline)
637
+ treatment_score = _claim_review_run_score(treatment)
638
+ if baseline_score is not None and treatment_score is not None:
639
+ official_delta = treatment_score - baseline_score
640
+
641
+ treatment_evidence = _claim_review_worker_evidence(treatment) if treatment else {"present": False}
642
+ baseline_labels = _claim_review_failure_labels(baseline or {})
643
+ baseline_attribution = _claim_review_score_failure_attribution(baseline or {})
644
+ attribution_caveat = baseline_attribution in {
645
+ "verifier_platform_probe_failure",
646
+ "verifier_infrastructure_failure",
647
+ "verifier_dependency_install_failure",
648
+ } or any(label.startswith("verifier_") for label in baseline_labels)
649
+ boundary_mismatch_count = sum(
650
+ int(run.get("worker_submit_eligible_mismatch_count") or 0)
651
+ for run in runs
652
+ if isinstance(run.get("worker_submit_eligible_mismatch_count"), int)
653
+ and not isinstance(run.get("worker_submit_eligible_mismatch_count"), bool)
654
+ )
655
+
656
+ blockers: list[str] = []
657
+ if official_delta is None:
658
+ blockers.append("missing_official_task_score_delta")
659
+ elif official_delta <= 0:
660
+ blockers.append("no_positive_official_task_score_delta")
661
+ if official_delta is not None and official_delta > 0 and not treatment_evidence.get("present"):
662
+ blockers.append("missing_treatment_worker_loopx_evidence")
663
+ if official_delta is not None and official_delta > 0 and attribution_caveat:
664
+ blockers.append("baseline_failure_attribution_caveat")
665
+ if boundary_mismatch_count:
666
+ blockers.append("worker_submit_eligible_boundary_mismatch")
667
+
668
+ positive_delta = official_delta is not None and official_delta > 0
669
+ assisted_evidence = bool(treatment_evidence.get("present"))
670
+ clean_validation = positive_delta and assisted_evidence and not blockers
671
+ candidate_validation = positive_delta and assisted_evidence
672
+ if clean_validation:
673
+ claim_strength = "strong_loopx_assisted_score_recovery"
674
+ elif candidate_validation:
675
+ claim_strength = "candidate_score_recovery_needs_attribution_review"
676
+ elif positive_delta:
677
+ claim_strength = "score_delta_without_assisted_worker_evidence"
678
+ elif assisted_evidence:
679
+ claim_strength = "loop_validation_no_score_uplift"
680
+ else:
681
+ claim_strength = "no_validation_enhancement"
682
+
683
+ if "baseline_failure_attribution_caveat" in blockers:
684
+ next_action = (
685
+ "run a same-protocol reliability repeat or add finer compact "
686
+ "verifier-side attribution before making a clean score-recovery claim"
687
+ )
688
+ elif "missing_treatment_worker_loopx_evidence" in blockers:
689
+ next_action = "collect compact worker-visible LoopX evidence before claiming assisted recovery"
690
+ elif "worker_submit_eligible_boundary_mismatch" in blockers:
691
+ next_action = "normalize the compact worker submit boundary before public claim review"
692
+ elif clean_validation:
693
+ next_action = "record as clean compact score-recovery evidence while preserving no-leaderboard claim boundary"
694
+ else:
695
+ next_action = "treat as loop/attribution evidence and seek a stronger paired sample"
696
+
697
+ claim_boundary = benchmark_comparison.get("claim_boundary") if isinstance(benchmark_comparison.get("claim_boundary"), dict) else {}
698
+ return {
699
+ "schema_version": BENCHMARK_CLAIM_REVIEW_SCHEMA_VERSION,
700
+ "input_schema_versions": {
701
+ "benchmark_comparison": benchmark_comparison.get("schema_version"),
702
+ "benchmark_runs": [
703
+ run.get("schema_version") for run in runs if run.get("schema_version")
704
+ ],
705
+ },
706
+ "task_id": benchmark_comparison.get("task_id"),
707
+ "comparison_id": benchmark_comparison.get("comparison_id"),
708
+ "official_task_score_delta": official_delta,
709
+ "control_plane_score_delta": benchmark_comparison.get("control_plane_score_delta"),
710
+ "treatment_worker_evidence": treatment_evidence,
711
+ "baseline_score_failure_attribution": baseline_attribution,
712
+ "baseline_failure_attribution_labels": baseline_labels,
713
+ "boundary_mismatch_count": boundary_mismatch_count,
714
+ "claim_boundary": {
715
+ "leaderboard_claim_allowed": bool(claim_boundary.get("leaderboard_claim_allowed")),
716
+ "official_score_uplift_claim_allowed": bool(claim_boundary.get("official_score_uplift_claim_allowed")),
717
+ "assisted_collaboration_claim_allowed": bool(claim_boundary.get("assisted_collaboration_claim_allowed")),
718
+ "raw_trace_excluded": claim_boundary.get("raw_trace_excluded") is not False,
719
+ },
720
+ "decision": {
721
+ "claim_strength": claim_strength,
722
+ "validation_enhancement_candidate": candidate_validation,
723
+ "clean_validation_enhancement": clean_validation,
724
+ "blockers": blockers,
725
+ "next_action": next_action,
726
+ },
727
+ "read_boundary": {
728
+ "compact_only": True,
729
+ "raw_artifacts_read": False,
730
+ "task_text_read": False,
731
+ "local_paths_recorded": False,
732
+ },
733
+ }
734
+
735
+
736
+ def _learning_ledger_failure_labels(
737
+ benchmark_comparison: dict[str, Any],
738
+ runs: Iterable[dict[str, Any]],
739
+ ) -> set[str]:
740
+ labels = set(
741
+ item
742
+ for item in benchmark_comparison.get("failure_attribution_labels") or []
743
+ if isinstance(item, str)
744
+ )
745
+ for run in runs:
746
+ labels.update(_claim_review_failure_labels(run))
747
+ first_blocker = run.get("first_blocker")
748
+ if isinstance(first_blocker, str) and first_blocker:
749
+ labels.add(first_blocker)
750
+ worker_start_status = run.get("worker_start_status")
751
+ if isinstance(worker_start_status, str) and worker_start_status:
752
+ labels.add(worker_start_status)
753
+ return labels
754
+
755
+
756
+ def _learning_ledger_repair_candidates(
757
+ claim_review: dict[str, Any],
758
+ benchmark_comparison: dict[str, Any],
759
+ runs: Iterable[dict[str, Any]],
760
+ ) -> list[str]:
761
+ labels = _learning_ledger_failure_labels(benchmark_comparison, runs)
762
+ blockers = set(
763
+ item
764
+ for item in (
765
+ (claim_review.get("decision") or {}).get("blockers")
766
+ if isinstance(claim_review.get("decision"), dict)
767
+ else []
768
+ )
769
+ if isinstance(item, str)
770
+ )
771
+ candidates: list[str] = []
772
+
773
+ environment_setup_failed = "environment_setup_failed_before_worker" in labels
774
+ if environment_setup_failed:
775
+ candidates.append("benchmark_environment_setup_contract")
776
+ if not environment_setup_failed and any(
777
+ label in labels
778
+ for label in (
779
+ "pre_worker_agent_setup_failed",
780
+ "treatment_pre_worker_agent_setup_failed",
781
+ "agent_setup_timeout_before_worker_start",
782
+ "agent_setup_failed_before_worker_start",
783
+ "pre_worker_startup_blocker_recorded",
784
+ "agent_setup_timeout_score_failure",
785
+ "agent_setup_score_failure",
786
+ )
787
+ ):
788
+ candidates.append("adapter_startup_argument_contract")
789
+ if any(
790
+ label in labels
791
+ for label in (
792
+ "runner_compact_result_missing",
793
+ "harbor_job_root_missing",
794
+ "post_launch_job_dir_materialization_missing",
795
+ "reducer_validation_failed",
796
+ )
797
+ ):
798
+ candidates.append("benchmark_lifecycle_materialization_gate")
799
+ if "worker_submit_eligible_boundary_mismatch" in blockers:
800
+ candidates.append("runner_owned_submit_boundary_invariant")
801
+ if "missing_treatment_worker_loopx_evidence" in blockers:
802
+ candidates.append("worker_visible_loopx_evidence_gate")
803
+ if "baseline_failure_attribution_caveat" in blockers:
804
+ candidates.append("compact_verifier_attribution_review")
805
+ if not candidates and bool(
806
+ (claim_review.get("treatment_worker_evidence") or {}).get("present")
807
+ if isinstance(claim_review.get("treatment_worker_evidence"), dict)
808
+ else False
809
+ ):
810
+ candidates.append("claim_cost_overhead_guard")
811
+ return candidates
812
+
813
+
814
+ def _learning_ledger_overhead_label(
815
+ official_delta: float | None,
816
+ cost_delta: float | None,
817
+ wall_time_delta: float | None,
818
+ ) -> str:
819
+ extra_cost = cost_delta is not None and cost_delta > 0
820
+ extra_time = wall_time_delta is not None and wall_time_delta > 0
821
+ positive_delta = official_delta is not None and official_delta > 0
822
+ if extra_cost and not positive_delta:
823
+ return "extra_cost_without_official_gain"
824
+ if extra_time and not positive_delta:
825
+ return "extra_wall_time_without_official_gain"
826
+ if (extra_cost or extra_time) and positive_delta:
827
+ return "positive_delta_with_overhead"
828
+ if cost_delta is not None and cost_delta < 0:
829
+ return "treatment_cheaper"
830
+ return "overhead_not_material_or_unknown"
831
+
832
+
833
+ def _learning_ledger_only_claim_cost_overhead_guard(
834
+ repair_candidates: list[str],
835
+ ) -> bool:
836
+ return repair_candidates == ["claim_cost_overhead_guard"]
837
+
838
+
839
+ def _learning_ledger_lifecycle_gate(
840
+ benchmark_comparison: dict[str, Any],
841
+ ) -> dict[str, Any]:
842
+ official_delta = benchmark_comparison.get("official_task_score_delta")
843
+ labels = benchmark_comparison.get("failure_attribution_labels")
844
+ compact_blocker = isinstance(labels, list) and bool(labels)
845
+ compact_score = _claim_review_numeric(official_delta) is not None
846
+ budget_count_allowed = compact_score or compact_blocker
847
+ return {
848
+ "schema_version": "benchmark_lifecycle_gate_v0",
849
+ "paired_comparison_present": True,
850
+ "compact_score_or_blocker_present": budget_count_allowed,
851
+ "budget_count_allowed": budget_count_allowed,
852
+ "blocked_reason": None
853
+ if budget_count_allowed
854
+ else "missing_compact_score_or_blocker_evidence",
855
+ }
856
+
857
+
858
+ def _learning_ledger_learning_quota_gate(
859
+ *,
860
+ lifecycle_gate: dict[str, Any],
861
+ repair_candidates: list[str],
862
+ clean_validation: bool,
863
+ validation_candidate: bool,
864
+ ) -> dict[str, Any]:
865
+ actionable_reasons: list[str] = []
866
+ if repair_candidates:
867
+ actionable_reasons.append("generic_repair_candidate")
868
+ if clean_validation:
869
+ actionable_reasons.append("clean_score_recovery_evidence")
870
+ elif validation_candidate:
871
+ actionable_reasons.append("candidate_score_recovery_needs_review")
872
+
873
+ lifecycle_ready = bool(lifecycle_gate.get("budget_count_allowed"))
874
+ actionable = bool(actionable_reasons)
875
+ if not lifecycle_ready:
876
+ blocked_reason = "missing_compact_score_or_blocker_evidence"
877
+ elif not actionable:
878
+ blocked_reason = "compact_result_has_no_loopx_learning_signal"
879
+ else:
880
+ blocked_reason = None
881
+
882
+ return {
883
+ "schema_version": "benchmark_learning_quota_gate_v0",
884
+ "actionable_learning_present": actionable,
885
+ "spend_allowed": lifecycle_ready and actionable,
886
+ "actionable_reasons": actionable_reasons,
887
+ "blocked_reason": blocked_reason,
888
+ }
889
+
890
+
891
+ def build_benchmark_learning_ledger(
892
+ benchmark_comparison: dict[str, Any],
893
+ *,
894
+ benchmark_runs: Iterable[dict[str, Any]] = (),
895
+ ) -> dict[str, Any]:
896
+ """Build a compact benchmark learning row from public-safe summaries."""
897
+
898
+ runs = [run for run in benchmark_runs if isinstance(run, dict)]
899
+ claim_review = build_benchmark_claim_review(
900
+ benchmark_comparison,
901
+ benchmark_runs=runs,
902
+ )
903
+ official_delta = claim_review.get("official_task_score_delta")
904
+ official_delta_num = (
905
+ official_delta if isinstance(official_delta, (int, float)) else None
906
+ )
907
+ cost_delta = _claim_review_numeric(benchmark_comparison.get("cost_delta_usd"))
908
+ wall_time_delta = _claim_review_numeric(
909
+ benchmark_comparison.get("wall_time_delta_seconds")
910
+ or benchmark_comparison.get("with_loopx_overhead_ms")
911
+ )
912
+ repair_candidates = _learning_ledger_repair_candidates(
913
+ claim_review,
914
+ benchmark_comparison,
915
+ runs,
916
+ )
917
+ lifecycle_gate = _learning_ledger_lifecycle_gate(benchmark_comparison)
918
+ decision = (
919
+ claim_review.get("decision")
920
+ if isinstance(claim_review.get("decision"), dict)
921
+ else {}
922
+ )
923
+ clean = bool(decision.get("clean_validation_enhancement"))
924
+ validation_candidate = bool(decision.get("validation_enhancement_candidate"))
925
+ overhead_guard_only = _learning_ledger_only_claim_cost_overhead_guard(
926
+ repair_candidates
927
+ )
928
+ if clean:
929
+ learning_status = "clean_score_recovery_evidence"
930
+ elif overhead_guard_only:
931
+ learning_status = "loop_validation_cost_overhead_guard"
932
+ elif repair_candidates:
933
+ learning_status = "generic_loopx_repair_or_attribution_required"
934
+ elif validation_candidate:
935
+ learning_status = "candidate_score_recovery_needs_review"
936
+ elif bool(
937
+ (claim_review.get("treatment_worker_evidence") or {}).get("present")
938
+ if isinstance(claim_review.get("treatment_worker_evidence"), dict)
939
+ else False
940
+ ):
941
+ learning_status = "loop_validation_or_overhead_evidence_only"
942
+ else:
943
+ learning_status = "no_loopx_validation_gain"
944
+ learning_quota_gate = _learning_ledger_learning_quota_gate(
945
+ lifecycle_gate=lifecycle_gate,
946
+ repair_candidates=repair_candidates,
947
+ clean_validation=clean,
948
+ validation_candidate=validation_candidate,
949
+ )
950
+
951
+ if overhead_guard_only:
952
+ next_allowed_action = (
953
+ "select_next_candidate_or_add_named_cost_control_hypothesis_before_repeat"
954
+ )
955
+ repeat_allowed = False
956
+ elif repair_candidates:
957
+ next_allowed_action = f"repair_or_validate_{repair_candidates[0]}"
958
+ repeat_allowed = False
959
+ elif not lifecycle_gate["budget_count_allowed"]:
960
+ next_allowed_action = "write_compact_blocker_before_repeat_or_new_candidate"
961
+ repeat_allowed = False
962
+ elif not learning_quota_gate["spend_allowed"]:
963
+ next_allowed_action = "stop_without_spend_and_record_no_learning_signal"
964
+ repeat_allowed = False
965
+ elif clean:
966
+ next_allowed_action = "record_clean_evidence_then_select_next_benchmark_lane"
967
+ repeat_allowed = True
968
+ else:
969
+ next_allowed_action = "only_repeat_with_named_attribution_or_stability_hypothesis"
970
+ repeat_allowed = True
971
+
972
+ return {
973
+ "schema_version": BENCHMARK_LEARNING_LEDGER_SCHEMA_VERSION,
974
+ "input_schema_versions": {
975
+ "benchmark_comparison": benchmark_comparison.get("schema_version"),
976
+ "benchmark_runs": [
977
+ run.get("schema_version") for run in runs if run.get("schema_version")
978
+ ],
979
+ "claim_review": claim_review.get("schema_version"),
980
+ },
981
+ "task_id": benchmark_comparison.get("task_id"),
982
+ "comparison_id": benchmark_comparison.get("comparison_id"),
983
+ "official_task_score_delta": official_delta,
984
+ "control_plane_score_delta": benchmark_comparison.get(
985
+ "control_plane_score_delta"
986
+ ),
987
+ "learning_status": learning_status,
988
+ "repair_candidates": repair_candidates,
989
+ "lifecycle_gate": lifecycle_gate,
990
+ "claim_strength": decision.get("claim_strength"),
991
+ "claim_blockers": decision.get("blockers") or [],
992
+ "learning_quota_gate": learning_quota_gate,
993
+ "overhead": {
994
+ "cost_delta_usd": cost_delta,
995
+ "wall_time_delta_seconds_or_ms": wall_time_delta,
996
+ "label": _learning_ledger_overhead_label(
997
+ official_delta_num,
998
+ cost_delta,
999
+ wall_time_delta,
1000
+ ),
1001
+ },
1002
+ "routing": {
1003
+ "repeat_allowed": repeat_allowed,
1004
+ "new_candidate_allowed": (
1005
+ not repair_candidates or overhead_guard_only
1006
+ )
1007
+ and bool(learning_quota_gate["spend_allowed"]),
1008
+ "next_allowed_action": next_allowed_action,
1009
+ },
1010
+ "read_boundary": {
1011
+ "compact_only": True,
1012
+ "raw_artifacts_read": False,
1013
+ "task_text_read": False,
1014
+ "local_paths_recorded": False,
1015
+ },
1016
+ }
1017
+
1018
+
1019
+ def _attempt_learning_task_ids(run: dict[str, Any]) -> list[str]:
1020
+ task_ids: list[str] = []
1021
+ trials = run.get("trials")
1022
+ if isinstance(trials, list):
1023
+ for trial in trials[:8]:
1024
+ if not isinstance(trial, dict):
1025
+ continue
1026
+ task_id = trial.get("task_id")
1027
+ if isinstance(task_id, str) and task_id and task_id not in task_ids:
1028
+ task_ids.append(task_id)
1029
+ return task_ids[:4]
1030
+
1031
+
1032
+ def _attempt_learning_repair_candidates(run: dict[str, Any]) -> list[str]:
1033
+ labels = set(_claim_review_failure_labels(run))
1034
+ first_blocker = run.get("first_blocker")
1035
+ if isinstance(first_blocker, str) and first_blocker:
1036
+ labels.add(first_blocker)
1037
+ candidates: list[str] = []
1038
+ if "environment_setup_failed_before_worker" in labels:
1039
+ candidates.append("benchmark_environment_setup_contract")
1040
+ elif any(
1041
+ label in labels
1042
+ for label in (
1043
+ "pre_worker_agent_setup_failed",
1044
+ "treatment_pre_worker_agent_setup_failed",
1045
+ )
1046
+ ):
1047
+ candidates.append("adapter_startup_argument_contract")
1048
+ if any(
1049
+ label in labels
1050
+ for label in (
1051
+ "runner_compact_result_missing",
1052
+ "harbor_job_root_missing",
1053
+ "post_launch_job_dir_materialization_missing",
1054
+ "reducer_validation_failed",
1055
+ )
1056
+ ):
1057
+ candidates.append("benchmark_lifecycle_materialization_gate")
1058
+ if _compact_positive_int(run.get("worker_submit_eligible_mismatch_count")):
1059
+ candidates.append("runner_owned_submit_boundary_invariant")
1060
+ if not candidates and labels:
1061
+ candidates.append("compact_failure_attribution_review")
1062
+ return candidates
1063
+
1064
+
1065
+ def _attempt_learning_run_countable(run: dict[str, Any]) -> bool:
1066
+ if not run:
1067
+ return False
1068
+ official = (
1069
+ run.get("official_task_score")
1070
+ if isinstance(run.get("official_task_score"), dict)
1071
+ else {}
1072
+ )
1073
+ compact_score = any(
1074
+ isinstance(official.get(field), (bool, int, float))
1075
+ for field in ("value", "passed")
1076
+ )
1077
+ compact_blocker = bool(run.get("first_blocker")) or bool(
1078
+ _claim_review_failure_labels(run)
1079
+ )
1080
+ return compact_score or compact_blocker
1081
+
1082
+
1083
+ def _attempt_learning_ledger_actionable(
1084
+ learning_ledger: dict[str, Any] | None,
1085
+ ) -> bool:
1086
+ if not isinstance(learning_ledger, dict):
1087
+ return False
1088
+ learning_gate = (
1089
+ learning_ledger.get("learning_quota_gate")
1090
+ if isinstance(learning_ledger.get("learning_quota_gate"), dict)
1091
+ else {}
1092
+ )
1093
+ routing = (
1094
+ learning_ledger.get("routing")
1095
+ if isinstance(learning_ledger.get("routing"), dict)
1096
+ else {}
1097
+ )
1098
+ return (
1099
+ learning_gate.get("spend_allowed") is True
1100
+ and isinstance(routing.get("next_allowed_action"), str)
1101
+ and bool(str(routing.get("next_allowed_action")).strip())
1102
+ )
1103
+
1104
+
1105
+ def build_benchmark_attempt_learning_gate(
1106
+ benchmark_run: dict[str, Any],
1107
+ *,
1108
+ benchmark_learning_ledger: dict[str, Any] | None = None,
1109
+ ) -> dict[str, Any]:
1110
+ """Gate benchmark budget counting on durable compact learning evidence."""
1111
+
1112
+ countable_attempt = _attempt_learning_run_countable(benchmark_run)
1113
+ repair_candidates = _attempt_learning_repair_candidates(benchmark_run)
1114
+ ledger_present = (
1115
+ isinstance(benchmark_learning_ledger, dict)
1116
+ and benchmark_learning_ledger.get("schema_version")
1117
+ == BENCHMARK_LEARNING_LEDGER_SCHEMA_VERSION
1118
+ )
1119
+ ledger_actionable = _attempt_learning_ledger_actionable(
1120
+ benchmark_learning_ledger
1121
+ )
1122
+
1123
+ if not countable_attempt:
1124
+ classification = "benchmark_attempt_not_countable"
1125
+ next_required_action = "record_compact_score_or_blocker_before_budget_count"
1126
+ elif not ledger_present:
1127
+ classification = "benchmark_attempt_learning_row_missing"
1128
+ next_required_action = "build_compact_benchmark_learning_ledger_before_repeat_or_new_candidate"
1129
+ elif not ledger_actionable:
1130
+ classification = "benchmark_attempt_learning_row_nonactionable"
1131
+ next_required_action = (
1132
+ "stop_without_spend_or_add_named_repair_caveat_before_repeat"
1133
+ )
1134
+ else:
1135
+ classification = "benchmark_attempt_learning_ready"
1136
+ routing = (
1137
+ benchmark_learning_ledger.get("routing")
1138
+ if isinstance(benchmark_learning_ledger, dict)
1139
+ and isinstance(benchmark_learning_ledger.get("routing"), dict)
1140
+ else {}
1141
+ )
1142
+ next_required_action = str(
1143
+ routing.get("next_allowed_action")
1144
+ or "record_learning_row_and_continue"
1145
+ )
1146
+
1147
+ return {
1148
+ "schema_version": BENCHMARK_ATTEMPT_LEARNING_GATE_SCHEMA_VERSION,
1149
+ "benchmark_id": benchmark_run.get("benchmark_id"),
1150
+ "mode": benchmark_run.get("mode"),
1151
+ "task_ids": _attempt_learning_task_ids(benchmark_run),
1152
+ "classification": classification,
1153
+ "countable_attempt": countable_attempt,
1154
+ "learning_row_present": ledger_present,
1155
+ "learning_row_actionable": ledger_actionable,
1156
+ "budget_count_allowed": countable_attempt and ledger_actionable,
1157
+ "repeat_allowed": bool(
1158
+ benchmark_learning_ledger
1159
+ and isinstance(benchmark_learning_ledger.get("routing"), dict)
1160
+ and benchmark_learning_ledger["routing"].get("repeat_allowed") is True
1161
+ and ledger_actionable
1162
+ ),
1163
+ "new_candidate_allowed": bool(
1164
+ benchmark_learning_ledger
1165
+ and isinstance(benchmark_learning_ledger.get("routing"), dict)
1166
+ and benchmark_learning_ledger["routing"].get("new_candidate_allowed")
1167
+ is True
1168
+ and ledger_actionable
1169
+ ),
1170
+ "repair_candidates": repair_candidates,
1171
+ "next_required_action": next_required_action,
1172
+ "claim_boundary": {
1173
+ "requires_learning_row_before_budget_count": True,
1174
+ "requires_learning_row_before_repeat_or_new_candidate": True,
1175
+ "raw_trace_excluded": True,
1176
+ "leaderboard_claim_allowed": False,
1177
+ },
1178
+ "read_boundary": {
1179
+ "compact_only": True,
1180
+ "raw_artifacts_read": False,
1181
+ "task_text_read": False,
1182
+ "local_paths_recorded": False,
1183
+ },
1184
+ }
1185
+
1186
+
1187
+ def _public_safe_kwarg_key_list(values: Iterable[Any]) -> list[str]:
1188
+ keys: list[str] = []
1189
+ for value in values:
1190
+ if not isinstance(value, (str, int, float)) or isinstance(value, bool):
1191
+ continue
1192
+ key = str(value).strip()
1193
+ if not key:
1194
+ continue
1195
+ if "=" in key:
1196
+ key = key.split("=", 1)[0].strip()
1197
+ if key.startswith("loopx_") and key not in keys:
1198
+ keys.append(key)
1199
+ return sorted(keys)[:80]
1200
+
1201
+
1202
+ def build_benchmark_adapter_kwarg_absorption_review(
1203
+ *,
1204
+ adapter_label: str,
1205
+ agent_kwargs: dict[str, Any],
1206
+ accepted_loopx_kwargs: Iterable[Any],
1207
+ allowed_base_passthrough: Iterable[Any] = (),
1208
+ ) -> dict[str, Any]:
1209
+ """Review whether generated loopx_* kwargs are adapter-absorbed."""
1210
+
1211
+ generated_keys = _public_safe_kwarg_key_list(agent_kwargs.keys())
1212
+ accepted_keys = set(_public_safe_kwarg_key_list(accepted_loopx_kwargs))
1213
+ passthrough_keys = set(_public_safe_kwarg_key_list(allowed_base_passthrough))
1214
+ absorbed_keys = sorted(
1215
+ key for key in generated_keys if key in accepted_keys or key in passthrough_keys
1216
+ )
1217
+ leaked_keys = sorted(
1218
+ key
1219
+ for key in generated_keys
1220
+ if key not in accepted_keys and key not in passthrough_keys
1221
+ )
1222
+
1223
+ if leaked_keys:
1224
+ classification = "adapter_kwarg_leak_risk"
1225
+ next_required_action = (
1226
+ "consume_or_reject_generated_loopx_kwargs_before_worker_start"
1227
+ )
1228
+ elif generated_keys:
1229
+ classification = "adapter_kwargs_absorbed"
1230
+ next_required_action = "adapter_kwarg_absorption_guard_passed"
1231
+ else:
1232
+ classification = "adapter_loopx_kwargs_missing"
1233
+ next_required_action = "record_generated_loopx_kwargs_before_run"
1234
+
1235
+ return {
1236
+ "schema_version": BENCHMARK_ADAPTER_KWARG_ABSORPTION_REVIEW_SCHEMA_VERSION,
1237
+ "adapter_label": adapter_label,
1238
+ "classification": classification,
1239
+ "clean": bool(generated_keys) and not leaked_keys,
1240
+ "generated_loopx_kwarg_count": len(generated_keys),
1241
+ "absorbed_loopx_kwarg_count": len(absorbed_keys),
1242
+ "leaked_loopx_kwarg_count": len(leaked_keys),
1243
+ "generated_loopx_kwarg_keys": generated_keys,
1244
+ "absorbed_loopx_kwarg_keys": absorbed_keys,
1245
+ "leaked_loopx_kwarg_keys": leaked_keys,
1246
+ "accepted_loopx_kwarg_keys": sorted(accepted_keys)[:80],
1247
+ "allowed_base_passthrough_keys": sorted(passthrough_keys)[:40],
1248
+ "next_required_action": next_required_action,
1249
+ "claim_boundary": {
1250
+ "kwarg_values_recorded": False,
1251
+ "local_paths_recorded": False,
1252
+ "adapter_absorption_required_before_worker_start": True,
1253
+ "base_constructor_may_receive_generated_loopx_kwargs": False,
1254
+ },
1255
+ "read_boundary": {
1256
+ "compact_only": True,
1257
+ "raw_artifacts_read": False,
1258
+ "task_text_read": False,
1259
+ "local_paths_recorded": False,
1260
+ "docker_invoked": False,
1261
+ "model_api_invoked": False,
1262
+ "upload_invoked": False,
1263
+ },
1264
+ }
1265
+
1266
+
1267
+ def _verifier_attribution_labels(run: dict[str, Any]) -> list[str]:
1268
+ labels = set(_claim_review_failure_labels(run))
1269
+ outcome = run.get("worker_bridge_outcome")
1270
+ if isinstance(outcome, dict):
1271
+ labels.update(_claim_review_failure_labels(outcome))
1272
+ trials = run.get("trials")
1273
+ if isinstance(trials, list):
1274
+ for trial in trials[:8]:
1275
+ if not isinstance(trial, dict):
1276
+ continue
1277
+ label_values = trial.get("verifier_failure_attribution_labels")
1278
+ if isinstance(label_values, list):
1279
+ labels.update(
1280
+ str(label)
1281
+ for label in label_values
1282
+ if isinstance(label, (str, int, float))
1283
+ and not isinstance(label, bool)
1284
+ )
1285
+ attribution = trial.get("verifier_failure_attribution")
1286
+ if isinstance(attribution, str) and attribution.strip():
1287
+ labels.add(attribution.strip())
1288
+ exception_kind = _compact_exception_kind(trial.get("exception_type"))
1289
+ if exception_kind == "agent_setup_timeout":
1290
+ labels.add("agent_setup_timeout_before_worker_start")
1291
+ elif exception_kind == "agent_setup_failure":
1292
+ labels.add("agent_setup_failed_before_worker_start")
1293
+ elif exception_kind == "agent_timeout":
1294
+ labels.add("agent_timeout_before_solution_completion")
1295
+ elif exception_kind == "agent_exception":
1296
+ labels.add("agent_exception_before_solution_completion")
1297
+ worker_start_kind = _compact_worker_start_status_kind(
1298
+ trial.get("worker_start_status")
1299
+ )
1300
+ if worker_start_kind == "agent_setup_failure":
1301
+ labels.add("agent_setup_failed_before_worker_start")
1302
+ elif worker_start_kind == "environment_setup_failure":
1303
+ labels.add("environment_setup_failed_before_worker")
1304
+ return sorted(labels)[:12]
1305
+
1306
+
1307
+ def _compact_trial_exception_summary(run: dict[str, Any]) -> dict[str, Any]:
1308
+ trials = run.get("trials")
1309
+ if not isinstance(trials, list):
1310
+ return {
1311
+ "schema_version": "compact_trial_exception_summary_v0",
1312
+ "trial_count": 0,
1313
+ "agent_timeout_count": 0,
1314
+ "agent_setup_timeout_count": 0,
1315
+ "agent_setup_failure_count": 0,
1316
+ "agent_exception_count": 0,
1317
+ "exception_types": [],
1318
+ }
1319
+ exception_types: list[str] = []
1320
+ agent_timeout_count = 0
1321
+ agent_setup_timeout_count = 0
1322
+ agent_setup_failure_count = 0
1323
+ agent_exception_count = 0
1324
+ for trial in trials[:8]:
1325
+ if not isinstance(trial, dict):
1326
+ continue
1327
+ exception_type = trial.get("exception_type")
1328
+ exception_kind = ""
1329
+ if isinstance(exception_type, str) and exception_type.strip():
1330
+ exception_type = exception_type.strip()
1331
+ if exception_type not in exception_types:
1332
+ exception_types.append(exception_type)
1333
+ exception_kind = _compact_exception_kind(exception_type)
1334
+ if exception_kind == "agent_timeout":
1335
+ agent_timeout_count += 1
1336
+ elif exception_kind == "agent_setup_timeout":
1337
+ agent_setup_timeout_count += 1
1338
+ elif exception_kind == "agent_setup_failure":
1339
+ agent_setup_failure_count += 1
1340
+ elif exception_kind == "agent_exception":
1341
+ agent_exception_count += 1
1342
+ worker_start_kind = _compact_worker_start_status_kind(
1343
+ trial.get("worker_start_status")
1344
+ )
1345
+ if worker_start_kind in {"agent_setup_failure", "environment_setup_failure"}:
1346
+ agent_setup_failure_count += 1
1347
+ return {
1348
+ "schema_version": "compact_trial_exception_summary_v0",
1349
+ "trial_count": len([trial for trial in trials if isinstance(trial, dict)]),
1350
+ "agent_timeout_count": agent_timeout_count,
1351
+ "agent_setup_timeout_count": agent_setup_timeout_count,
1352
+ "agent_setup_failure_count": agent_setup_failure_count,
1353
+ "agent_exception_count": agent_exception_count,
1354
+ "exception_types": exception_types[:8],
1355
+ }
1356
+
1357
+
1358
+ def _compact_runner_completed_score_zero_signal(
1359
+ *,
1360
+ run: dict[str, Any],
1361
+ score: float | None,
1362
+ labels: list[str],
1363
+ verifier_failure_count: int,
1364
+ verifier_dependency_failure_count: int,
1365
+ agent_timeout_count: int,
1366
+ agent_setup_timeout_count: int,
1367
+ agent_setup_failure_count: int,
1368
+ agent_exception_count: int,
1369
+ ) -> dict[str, Any]:
1370
+ """Detect clean runner completion with an official zero score and no compact cause."""
1371
+
1372
+ progress = run.get("progress")
1373
+ if not isinstance(progress, dict):
1374
+ progress = {}
1375
+ trials = run.get("trials")
1376
+ trial_dicts = [trial for trial in trials if isinstance(trial, dict)] if isinstance(trials, list) else []
1377
+ exception_types = [
1378
+ str(trial.get("exception_type")).strip()
1379
+ for trial in trial_dicts[:8]
1380
+ if isinstance(trial.get("exception_type"), str)
1381
+ and str(trial.get("exception_type")).strip()
1382
+ ]
1383
+ non_empty_exceptions = [
1384
+ exception_type
1385
+ for exception_type in exception_types
1386
+ if exception_type.lower() not in {"none", "null", "no_exception"}
1387
+ ]
1388
+ completed_trials = _compact_positive_int(progress.get("n_completed_trials"))
1389
+ errored_trials = _compact_positive_int(progress.get("n_errored_trials"))
1390
+ running_trials = _compact_positive_int(progress.get("n_running_trials"))
1391
+ pending_trials = _compact_positive_int(progress.get("n_pending_trials"))
1392
+ verifier_reward_present_count = sum(
1393
+ 1
1394
+ for trial in trial_dicts[:8]
1395
+ if trial.get("verifier_reward_present") is True
1396
+ or isinstance(trial.get("reward"), dict)
1397
+ )
1398
+ explicit_compact_cause_present = any(
1399
+ [
1400
+ labels,
1401
+ verifier_failure_count,
1402
+ verifier_dependency_failure_count,
1403
+ agent_timeout_count,
1404
+ agent_setup_timeout_count,
1405
+ agent_setup_failure_count,
1406
+ agent_exception_count,
1407
+ non_empty_exceptions,
1408
+ ]
1409
+ )
1410
+ runner_completed = str(run.get("runner_return_status") or "").strip() == "completed"
1411
+ official_score_completed = (
1412
+ str(run.get("official_score_status") or "").strip() == "completed"
1413
+ )
1414
+ completed_cleanly = (
1415
+ score == 0
1416
+ and runner_completed
1417
+ and official_score_completed
1418
+ and completed_trials > 0
1419
+ and errored_trials == 0
1420
+ and running_trials == 0
1421
+ and pending_trials == 0
1422
+ and verifier_reward_present_count > 0
1423
+ and not explicit_compact_cause_present
1424
+ )
1425
+ return {
1426
+ "schema_version": "runner_completed_score_zero_signal_v0",
1427
+ "detected": completed_cleanly,
1428
+ "runner_return_status": run.get("runner_return_status"),
1429
+ "official_score_status": run.get("official_score_status"),
1430
+ "completed_trials": completed_trials,
1431
+ "errored_trials": errored_trials,
1432
+ "running_trials": running_trials,
1433
+ "pending_trials": pending_trials,
1434
+ "verifier_reward_present_count": verifier_reward_present_count,
1435
+ "non_empty_exception_types": non_empty_exceptions[:8],
1436
+ }
1437
+
1438
+
1439
+ def _verifier_attribution_class(
1440
+ *,
1441
+ score: float | None,
1442
+ score_attribution: str,
1443
+ labels: list[str],
1444
+ verifier_failure_count: int,
1445
+ verifier_dependency_failure_count: int,
1446
+ agent_timeout_count: int,
1447
+ agent_setup_timeout_count: int,
1448
+ agent_setup_failure_count: int,
1449
+ agent_exception_count: int,
1450
+ ) -> str:
1451
+ if score is not None and score > 0:
1452
+ return "no_score_failure"
1453
+ if (
1454
+ score_attribution == "verifier_dependency_install_failure"
1455
+ or verifier_dependency_failure_count > 0
1456
+ or "verifier_dependency_install_failure" in labels
1457
+ ):
1458
+ return "verifier_dependency_install_failure"
1459
+ if score_attribution == "verifier_platform_probe_failure" or (
1460
+ "verifier_platform_probe_failure" in labels
1461
+ ):
1462
+ return "verifier_platform_probe_failure"
1463
+ if score_attribution in {"verifier_infrastructure_failure", "verifier_failure"}:
1464
+ return "verifier_infrastructure_failure"
1465
+ if any(label.startswith("verifier_") for label in labels) or (
1466
+ verifier_failure_count > 0
1467
+ ):
1468
+ return "verifier_infrastructure_failure"
1469
+ if (
1470
+ score_attribution == "worker_self_validation_official_score_mismatch"
1471
+ or "worker_self_validation_official_score_mismatch" in labels
1472
+ ):
1473
+ return "worker_self_validation_official_score_mismatch"
1474
+ if (
1475
+ score_attribution == "worker_validation_scope_ambiguous_official_score_failure"
1476
+ or "worker_validation_scope_ambiguous_official_score_failure" in labels
1477
+ ):
1478
+ return "worker_validation_scope_ambiguous_official_score_failure"
1479
+ if (
1480
+ score_attribution == "worker_bridge_connected_official_score_failure"
1481
+ or "worker_bridge_connected_official_score_failure" in labels
1482
+ ):
1483
+ return "model_or_solution_failure"
1484
+ if score_attribution in {
1485
+ "model_solution_failure",
1486
+ "agent_solution_failure",
1487
+ "agent_timeout_before_solution_completion",
1488
+ "task_solution_failure",
1489
+ "solution_incorrect",
1490
+ "official_verifier_solution_failure",
1491
+ }:
1492
+ return "model_or_solution_failure"
1493
+ if (
1494
+ score_attribution == "agent_setup_timeout_score_failure"
1495
+ or agent_setup_timeout_count > 0
1496
+ or "agent_setup_timeout_before_worker_start" in labels
1497
+ ):
1498
+ return "agent_setup_timeout_score_failure"
1499
+ if (
1500
+ score_attribution == "agent_setup_score_failure"
1501
+ or agent_setup_failure_count > 0
1502
+ or "agent_setup_failed_before_worker_start" in labels
1503
+ or "environment_setup_failed_before_worker" in labels
1504
+ or "pre_worker_startup_blocker_recorded" in labels
1505
+ ):
1506
+ return "agent_setup_score_failure"
1507
+ if agent_timeout_count > 0 or "agent_timeout_before_solution_completion" in labels:
1508
+ return "agent_timeout_score_failure"
1509
+ if (
1510
+ agent_exception_count > 0
1511
+ or "agent_exception_before_solution_completion" in labels
1512
+ ):
1513
+ return "agent_exception_score_failure"
1514
+ if score is not None and score == 0:
1515
+ return "unattributed_score_failure"
1516
+ return "missing_official_score"
1517
+
1518
+
1519
+ def _compact_validation_failed_checks(run: dict[str, Any]) -> list[str]:
1520
+ validation = run.get("validation")
1521
+ if not isinstance(validation, dict):
1522
+ return []
1523
+ failed = validation.get("failed_checks")
1524
+ if not isinstance(failed, list):
1525
+ return []
1526
+ return [
1527
+ str(item)
1528
+ for item in failed
1529
+ if isinstance(item, (str, int, float)) and not isinstance(item, bool)
1530
+ ][:12]
1531
+
1532
+
1533
+ def _verifier_attribution_run_review(run: dict[str, Any]) -> dict[str, Any]:
1534
+ score = _claim_review_run_score(run)
1535
+ score_attribution = _claim_review_score_failure_attribution(run)
1536
+ labels = _verifier_attribution_labels(run)
1537
+ verifier_failure_count = _compact_positive_int(
1538
+ run.get("verifier_failure_attribution_count")
1539
+ )
1540
+ verifier_dependency_failure_count = _compact_positive_int(
1541
+ run.get("verifier_dependency_failure_count")
1542
+ )
1543
+ exception_summary = _compact_trial_exception_summary(run)
1544
+ agent_timeout_count = _compact_positive_int(
1545
+ exception_summary.get("agent_timeout_count")
1546
+ )
1547
+ agent_setup_timeout_count = _compact_positive_int(
1548
+ exception_summary.get("agent_setup_timeout_count")
1549
+ )
1550
+ agent_setup_failure_count = _compact_positive_int(
1551
+ exception_summary.get("agent_setup_failure_count")
1552
+ )
1553
+ agent_exception_count = _compact_positive_int(
1554
+ exception_summary.get("agent_exception_count")
1555
+ )
1556
+ attribution_class = _verifier_attribution_class(
1557
+ score=score,
1558
+ score_attribution=score_attribution,
1559
+ labels=labels,
1560
+ verifier_failure_count=verifier_failure_count,
1561
+ verifier_dependency_failure_count=verifier_dependency_failure_count,
1562
+ agent_timeout_count=agent_timeout_count,
1563
+ agent_setup_timeout_count=agent_setup_timeout_count,
1564
+ agent_setup_failure_count=agent_setup_failure_count,
1565
+ agent_exception_count=agent_exception_count,
1566
+ )
1567
+ runner_completed_score_zero_signal = _compact_runner_completed_score_zero_signal(
1568
+ run=run,
1569
+ score=score,
1570
+ labels=labels,
1571
+ verifier_failure_count=verifier_failure_count,
1572
+ verifier_dependency_failure_count=verifier_dependency_failure_count,
1573
+ agent_timeout_count=agent_timeout_count,
1574
+ agent_setup_timeout_count=agent_setup_timeout_count,
1575
+ agent_setup_failure_count=agent_setup_failure_count,
1576
+ agent_exception_count=agent_exception_count,
1577
+ )
1578
+ if (
1579
+ attribution_class == "unattributed_score_failure"
1580
+ and runner_completed_score_zero_signal["detected"]
1581
+ ):
1582
+ attribution_class = "runner_completed_official_score_zero_unattributed"
1583
+ verifier_caveat = attribution_class in {
1584
+ "verifier_dependency_install_failure",
1585
+ "verifier_platform_probe_failure",
1586
+ "verifier_infrastructure_failure",
1587
+ "worker_self_validation_official_score_mismatch",
1588
+ "worker_validation_scope_ambiguous_official_score_failure",
1589
+ "runner_completed_official_score_zero_unattributed",
1590
+ "unattributed_score_failure",
1591
+ "missing_official_score",
1592
+ }
1593
+ caveat_resolved = attribution_class in {
1594
+ "model_or_solution_failure",
1595
+ "agent_setup_timeout_score_failure",
1596
+ "agent_setup_score_failure",
1597
+ "agent_timeout_score_failure",
1598
+ "agent_exception_score_failure",
1599
+ }
1600
+ if attribution_class.startswith("verifier_"):
1601
+ next_action = (
1602
+ "keep attribution caveat; require same-protocol repeat or finer "
1603
+ "compact verifier evidence"
1604
+ )
1605
+ elif attribution_class == "worker_self_validation_official_score_mismatch":
1606
+ next_action = (
1607
+ "keep attribution caveat; align worker self-validation with official "
1608
+ "verifier or collect finer compact verifier-facing evidence"
1609
+ )
1610
+ elif attribution_class == "worker_validation_scope_ambiguous_official_score_failure":
1611
+ next_action = (
1612
+ "keep attribution caveat; add explicit worker validation_scope and "
1613
+ "claim_boundary before same-task repeat"
1614
+ )
1615
+ elif attribution_class == "runner_completed_official_score_zero_unattributed":
1616
+ next_action = (
1617
+ "keep attribution caveat; runner and official verifier completed, "
1618
+ "but compact score-zero cause still needs finer attribution"
1619
+ )
1620
+ elif attribution_class == "unattributed_score_failure":
1621
+ next_action = (
1622
+ "keep attribution caveat; compact score failure is not yet attributed"
1623
+ )
1624
+ elif attribution_class == "missing_official_score":
1625
+ next_action = "wait for compact official score before attribution review"
1626
+ elif attribution_class == "agent_timeout_score_failure":
1627
+ next_action = (
1628
+ "claim caveat resolved by compact agent-timeout attribution; "
1629
+ "treat as non-verifier score failure"
1630
+ )
1631
+ elif attribution_class == "agent_exception_score_failure":
1632
+ next_action = (
1633
+ "claim caveat resolved by compact agent-exception attribution; "
1634
+ "inspect case-level exception context before same-task repeat"
1635
+ )
1636
+ elif attribution_class == "agent_setup_timeout_score_failure":
1637
+ next_action = (
1638
+ "claim caveat resolved by compact agent-setup-timeout attribution; "
1639
+ "repair startup/setup before same-task repeat"
1640
+ )
1641
+ elif attribution_class == "agent_setup_score_failure":
1642
+ next_action = (
1643
+ "claim caveat resolved by compact agent-setup attribution; repair "
1644
+ "startup/setup before same-task repeat"
1645
+ )
1646
+ elif caveat_resolved:
1647
+ next_action = "claim caveat resolved by compact non-verifier failure attribution"
1648
+ else:
1649
+ next_action = "no score-failure caveat for this run"
1650
+
1651
+ return {
1652
+ "mode": run.get("mode"),
1653
+ "job_name_present": bool(run.get("job_name")),
1654
+ "task_ids": [
1655
+ str(trial.get("task_id"))
1656
+ for trial in (
1657
+ run.get("trials") if isinstance(run.get("trials"), list) else []
1658
+ )
1659
+ if isinstance(trial, dict) and trial.get("task_id")
1660
+ ][:4],
1661
+ "official_score": score,
1662
+ "official_passed": bool(
1663
+ (run.get("official_task_score") or {}).get("passed")
1664
+ )
1665
+ if isinstance(run.get("official_task_score"), dict)
1666
+ else None,
1667
+ "score_failure_attribution": score_attribution,
1668
+ "failure_attribution_labels": labels,
1669
+ "compact_trial_exception_summary": exception_summary,
1670
+ "agent_timeout_count": agent_timeout_count,
1671
+ "agent_setup_timeout_count": agent_setup_timeout_count,
1672
+ "agent_setup_failure_count": agent_setup_failure_count,
1673
+ "agent_exception_count": agent_exception_count,
1674
+ "verifier_failure_attribution_count": verifier_failure_count,
1675
+ "verifier_dependency_failure_count": verifier_dependency_failure_count,
1676
+ "validation_failed_checks": _compact_validation_failed_checks(run),
1677
+ "runner_completed_score_zero_signal": runner_completed_score_zero_signal,
1678
+ "worker_submit_eligible_mismatch_count": _compact_positive_int(
1679
+ run.get("worker_submit_eligible_mismatch_count")
1680
+ ),
1681
+ "worker_self_validation_official_score_mismatch_count": _compact_positive_int(
1682
+ run.get("worker_self_validation_official_score_mismatch_count")
1683
+ ),
1684
+ "worker_validation_scope_ambiguous_official_score_failure_count": (
1685
+ _compact_positive_int(
1686
+ run.get(
1687
+ "worker_validation_scope_ambiguous_official_score_failure_count"
1688
+ )
1689
+ )
1690
+ ),
1691
+ "worker_bridge_connected_official_score_failure_count": _compact_positive_int(
1692
+ run.get("worker_bridge_connected_official_score_failure_count")
1693
+ ),
1694
+ "attribution_class": attribution_class,
1695
+ "verifier_caveat": verifier_caveat,
1696
+ "claim_caveat_resolved": caveat_resolved,
1697
+ "next_action": next_action,
1698
+ }
1699
+
1700
+
1701
+ def _verifier_attribution_review_routing(
1702
+ *,
1703
+ baseline_review: dict[str, Any] | None,
1704
+ blockers: list[str],
1705
+ baseline_caveat_resolved: bool,
1706
+ ) -> dict[str, Any]:
1707
+ """Project compact attribution into machine-readable routing decisions."""
1708
+
1709
+ attribution_class = (
1710
+ str(baseline_review.get("attribution_class") or "")
1711
+ if isinstance(baseline_review, dict)
1712
+ else ""
1713
+ )
1714
+ verifier_blocked = "baseline_verifier_attribution_caveat" in blockers
1715
+ worker_verifier_alignment_blocked = (
1716
+ "baseline_worker_verifier_alignment_caveat" in blockers
1717
+ )
1718
+ worker_validation_scope_blocked = (
1719
+ "baseline_worker_validation_scope_ambiguous_caveat" in blockers
1720
+ )
1721
+ missing_baseline = "missing_compact_baseline_run" in blockers
1722
+ missing_score = "baseline_official_score_missing" in blockers
1723
+ unattributed = "baseline_score_failure_unattributed" in blockers
1724
+ boundary_mismatch = "baseline_submit_boundary_mismatch" in blockers
1725
+ no_score_failure = attribution_class == "no_score_failure" and not blockers
1726
+ requires_preflight_repair = attribution_class in {
1727
+ "verifier_dependency_install_failure",
1728
+ "verifier_platform_probe_failure",
1729
+ "verifier_infrastructure_failure",
1730
+ }
1731
+ requires_agent_setup_repair = attribution_class in {
1732
+ "agent_setup_timeout_score_failure",
1733
+ "agent_setup_score_failure",
1734
+ }
1735
+ requires_case_exception_research = (
1736
+ attribution_class == "agent_exception_score_failure"
1737
+ )
1738
+
1739
+ treatment_eligible = (
1740
+ baseline_caveat_resolved
1741
+ and not requires_agent_setup_repair
1742
+ and not requires_case_exception_research
1743
+ )
1744
+ repeat_allowed = baseline_caveat_resolved
1745
+ new_candidate_allowed = (
1746
+ baseline_caveat_resolved
1747
+ or verifier_blocked
1748
+ or worker_verifier_alignment_blocked
1749
+ or worker_validation_scope_blocked
1750
+ )
1751
+
1752
+ if missing_baseline:
1753
+ next_allowed_action = "provide_compact_baseline_run"
1754
+ elif missing_score:
1755
+ next_allowed_action = "wait_for_compact_official_score"
1756
+ elif boundary_mismatch:
1757
+ next_allowed_action = "repair_submit_boundary_mismatch"
1758
+ elif requires_preflight_repair:
1759
+ next_allowed_action = (
1760
+ "repair_verifier_preflight_or_select_new_material_ready_case"
1761
+ )
1762
+ repeat_allowed = False
1763
+ elif attribution_class == "worker_self_validation_official_score_mismatch":
1764
+ next_allowed_action = "align_worker_self_validation_with_official_verifier"
1765
+ repeat_allowed = False
1766
+ new_candidate_allowed = False
1767
+ elif attribution_class == "worker_validation_scope_ambiguous_official_score_failure":
1768
+ next_allowed_action = "add_worker_validation_scope_and_claim_boundary"
1769
+ repeat_allowed = False
1770
+ new_candidate_allowed = False
1771
+ elif requires_agent_setup_repair:
1772
+ next_allowed_action = "repair_agent_setup_timeout_or_select_new_material_ready_case"
1773
+ repeat_allowed = False
1774
+ new_candidate_allowed = True
1775
+ elif requires_case_exception_research:
1776
+ next_allowed_action = "inspect_compact_agent_exception_before_same_task_repeat"
1777
+ repeat_allowed = False
1778
+ new_candidate_allowed = True
1779
+ elif unattributed:
1780
+ next_allowed_action = "collect_finer_compact_failure_attribution"
1781
+ repeat_allowed = False
1782
+ new_candidate_allowed = False
1783
+ elif no_score_failure:
1784
+ next_allowed_action = "select_new_material_ready_case_no_score_failure"
1785
+ treatment_eligible = False
1786
+ repeat_allowed = False
1787
+ new_candidate_allowed = True
1788
+ elif baseline_caveat_resolved:
1789
+ next_allowed_action = "baseline_failure_is_control_plane_addressable"
1790
+ else:
1791
+ next_allowed_action = "keep_treatment_blocked_until_attribution_resolves"
1792
+ repeat_allowed = False
1793
+ new_candidate_allowed = False
1794
+
1795
+ return {
1796
+ "treatment_eligible": treatment_eligible,
1797
+ "repeat_allowed": repeat_allowed,
1798
+ "new_candidate_allowed": new_candidate_allowed,
1799
+ "requires_verifier_preflight_repair": requires_preflight_repair,
1800
+ "requires_agent_setup_repair": requires_agent_setup_repair,
1801
+ "requires_case_exception_research": requires_case_exception_research,
1802
+ "requires_compact_official_score": missing_score,
1803
+ "requires_compact_baseline_run": missing_baseline,
1804
+ "requires_finer_compact_attribution": unattributed,
1805
+ "requires_worker_verifier_alignment": (
1806
+ attribution_class == "worker_self_validation_official_score_mismatch"
1807
+ ),
1808
+ "requires_worker_validation_scope": (
1809
+ attribution_class
1810
+ == "worker_validation_scope_ambiguous_official_score_failure"
1811
+ ),
1812
+ "next_allowed_action": next_allowed_action,
1813
+ "blocked_action_scope": (
1814
+ "treatment_and_same_task_repeat"
1815
+ if requires_preflight_repair
1816
+ else "same_task_repeat_until_worker_verifier_alignment"
1817
+ if attribution_class == "worker_self_validation_official_score_mismatch"
1818
+ else "same_task_repeat_until_worker_validation_scope"
1819
+ if attribution_class
1820
+ == "worker_validation_scope_ambiguous_official_score_failure"
1821
+ else "same_task_repeat_until_setup_repair"
1822
+ if requires_agent_setup_repair
1823
+ else "same_task_repeat_until_exception_hypothesis"
1824
+ if requires_case_exception_research
1825
+ else "same_task_claim"
1826
+ if no_score_failure
1827
+ else "treatment"
1828
+ if blockers and not baseline_caveat_resolved
1829
+ else ""
1830
+ ),
1831
+ }
1832
+
1833
+
1834
+ def _benchmark_lifecycle_schema(value: dict[str, Any] | None) -> str:
1835
+ if not isinstance(value, dict):
1836
+ return ""
1837
+ return str(value.get("schema_version") or "")
1838
+
1839
+
1840
+ def _benchmark_lifecycle_launched(value: dict[str, Any] | None) -> bool:
1841
+ if not isinstance(value, dict) or not value:
1842
+ return False
1843
+ for field in ("process_started", "launched", "started", "pid"):
1844
+ if value.get(field):
1845
+ return True
1846
+ return False
1847
+
1848
+
1849
+ def _benchmark_lifecycle_budget_count_allowed(
1850
+ learning_ledger: dict[str, Any] | None,
1851
+ ) -> bool:
1852
+ if not isinstance(learning_ledger, dict):
1853
+ return False
1854
+ lifecycle_gate = (
1855
+ learning_ledger.get("lifecycle_gate")
1856
+ if isinstance(learning_ledger.get("lifecycle_gate"), dict)
1857
+ else {}
1858
+ )
1859
+ return lifecycle_gate.get("budget_count_allowed") is True
1860
+
1861
+
1862
+ def _benchmark_lifecycle_environment_setup_readiness(
1863
+ *,
1864
+ benchmark_run: dict[str, Any] | None,
1865
+ preflight: dict[str, Any] | None,
1866
+ ) -> dict[str, Any]:
1867
+ context = _benchmark_run_environment_setup_failure_context(benchmark_run)
1868
+ if not context:
1869
+ return {}
1870
+
1871
+ preflight_ready = _benchmark_lifecycle_ready_preflight(preflight)
1872
+ task_id = "unknown_task"
1873
+ if isinstance(benchmark_run, dict):
1874
+ for trial in benchmark_run.get("trials") or []:
1875
+ if not isinstance(trial, dict):
1876
+ continue
1877
+ task_label = _public_safe_benchmark_label(trial.get("task_id"))
1878
+ if task_label:
1879
+ task_id = task_label
1880
+ break
1881
+ no_run_preflight_status = "ready" if preflight_ready else "not_ready_or_absent"
1882
+ first_blocker = "environment_setup_failed_before_worker"
1883
+ if not preflight_ready:
1884
+ next_allowed_action = "repair_no_run_preflight_before_environment_setup_probe"
1885
+ else:
1886
+ next_allowed_action = (
1887
+ "run_setup_only_environment_preflight_or_select_new_material_ready_case"
1888
+ )
1889
+
1890
+ return {
1891
+ "schema_version": TERMINAL_BENCH_ENVIRONMENT_SETUP_READINESS_SCHEMA,
1892
+ "benchmark_id": (
1893
+ _public_safe_benchmark_label(
1894
+ benchmark_run.get("benchmark_id") if isinstance(benchmark_run, dict) else None
1895
+ )
1896
+ or "benchmark"
1897
+ ),
1898
+ "task_id": task_id,
1899
+ "previous_failure_observed": True,
1900
+ "previous_failure_context": context,
1901
+ "no_run_preflight_ready": preflight_ready,
1902
+ "no_run_preflight_status": no_run_preflight_status,
1903
+ "same_task_repeat_allowed": False,
1904
+ "repeat_blocked_by": first_blocker,
1905
+ "first_blocker": first_blocker,
1906
+ "diagnostic_limit": "cannot_prove_reproducible_or_cleared_from_no_run_preflight",
1907
+ "next_allowed_action": next_allowed_action,
1908
+ "read_boundary": {
1909
+ "compact_only": True,
1910
+ "raw_artifacts_read": False,
1911
+ "raw_logs_read": False,
1912
+ "task_text_read": False,
1913
+ "trajectory_read": False,
1914
+ "docker_logs_read": False,
1915
+ "credential_values_recorded": False,
1916
+ "local_paths_recorded": False,
1917
+ "model_api_invoked": False,
1918
+ "upload_invoked": False,
1919
+ "submit_invoked": False,
1920
+ },
1921
+ }
1922
+
1923
+
1924
+ def _benchmark_lifecycle_environment_setup_probe_result(
1925
+ benchmark_run: dict[str, Any] | None,
1926
+ ) -> dict[str, Any]:
1927
+ """Return compact lifecycle facts for a no-upload environment setup probe."""
1928
+
1929
+ if not isinstance(benchmark_run, dict):
1930
+ return {}
1931
+ trials = [
1932
+ trial
1933
+ for trial in benchmark_run.get("trials") or []
1934
+ if isinstance(trial, dict)
1935
+ ]
1936
+ materialized_trials: list[dict[str, Any]] = []
1937
+ for trial in trials:
1938
+ if trial.get("worker_start_status") != "environment_setup_probe_materialized":
1939
+ continue
1940
+ materialized_trials.append(trial)
1941
+ if not materialized_trials:
1942
+ return {}
1943
+
1944
+ first_trial = materialized_trials[0]
1945
+ task_id = _public_safe_benchmark_label(first_trial.get("task_id")) or "unknown_task"
1946
+ exception_type = (
1947
+ _public_safe_benchmark_label(first_trial.get("exception_type"), limit=120)
1948
+ or "none"
1949
+ )
1950
+ exception_present = exception_type not in {"", "none", "not_applicable"}
1951
+ if exception_present:
1952
+ probe_outcome = "materialized_with_exception"
1953
+ repeat_blocked_by = "environment_setup_probe_exception_requires_interpretation"
1954
+ next_allowed_action = (
1955
+ "classify_environment_setup_probe_exception_before_same_task_repeat"
1956
+ )
1957
+ else:
1958
+ probe_outcome = "materialized_without_exception"
1959
+ repeat_blocked_by = "environment_setup_probe_result_requires_review"
1960
+ next_allowed_action = (
1961
+ "review_environment_setup_probe_result_before_same_task_repeat"
1962
+ )
1963
+ return {
1964
+ "schema_version": "terminal_bench_environment_setup_probe_result_v0",
1965
+ "benchmark_id": (
1966
+ _public_safe_benchmark_label(benchmark_run.get("benchmark_id"))
1967
+ or "benchmark"
1968
+ ),
1969
+ "task_id": task_id,
1970
+ "worker_mode": (
1971
+ _public_safe_benchmark_label(benchmark_run.get("worker_mode"))
1972
+ or "unknown"
1973
+ ),
1974
+ "probe_materialized": True,
1975
+ "materialized_trial_count": len(materialized_trials),
1976
+ "trial_result_present_count": sum(
1977
+ 1 for trial in trials if trial.get("trial_result_present") is True
1978
+ ),
1979
+ "artifact_manifest_present_count": sum(
1980
+ 1 for trial in trials if trial.get("artifact_manifest_present") is True
1981
+ ),
1982
+ "exception_type": exception_type,
1983
+ "exception_present": exception_present,
1984
+ "probe_outcome": probe_outcome,
1985
+ "repeat_blocked_by": repeat_blocked_by,
1986
+ "case_attempt_countable": False,
1987
+ "benchmark_budget_countable": False,
1988
+ "same_task_repeat_allowed": False,
1989
+ "next_allowed_action": next_allowed_action,
1990
+ "read_boundary": {
1991
+ "compact_only": True,
1992
+ "raw_artifacts_read": False,
1993
+ "raw_logs_read": False,
1994
+ "task_text_read": False,
1995
+ "trajectory_read": False,
1996
+ "docker_logs_read": False,
1997
+ "credential_values_recorded": False,
1998
+ "local_paths_recorded": False,
1999
+ "model_api_invoked": False,
2000
+ "upload_invoked": False,
2001
+ "submit_invoked": False,
2002
+ },
2003
+ }
2004
+
2005
+
2006
+ def build_benchmark_lifecycle_state(
2007
+ *,
2008
+ preflight: dict[str, Any] | None = None,
2009
+ launch: dict[str, Any] | None = None,
2010
+ post_launch_materialization: dict[str, Any] | None = None,
2011
+ benchmark_run: dict[str, Any] | None = None,
2012
+ benchmark_comparison: dict[str, Any] | None = None,
2013
+ claim_review: dict[str, Any] | None = None,
2014
+ learning_ledger: dict[str, Any] | None = None,
2015
+ ) -> dict[str, Any]:
2016
+ """Reduce compact benchmark evidence into an explicit lifecycle state."""
2017
+
2018
+ preflight_ready = _benchmark_lifecycle_ready_preflight(preflight)
2019
+ process_launched = _benchmark_lifecycle_launched(launch)
2020
+ materialized = (
2021
+ isinstance(post_launch_materialization, dict)
2022
+ and post_launch_materialization.get("ready_for_launch_state") is True
2023
+ )
2024
+ compact_ready = (
2025
+ isinstance(post_launch_materialization, dict)
2026
+ and post_launch_materialization.get("ready_for_compact_result_ingest") is True
2027
+ ) or _benchmark_lifecycle_schema(benchmark_run) == "benchmark_run_v0"
2028
+ compact_failure_marker_ready = (
2029
+ isinstance(post_launch_materialization, dict)
2030
+ and post_launch_materialization.get("ready_for_compact_failure_marker") is True
2031
+ )
2032
+ result_ingested = _benchmark_lifecycle_schema(benchmark_run) == "benchmark_run_v0"
2033
+ if result_ingested:
2034
+ process_launched = True
2035
+ materialized = True
2036
+ compact_ready = True
2037
+ verifier_scored = False
2038
+ if isinstance(benchmark_run, dict):
2039
+ verifier_scored = any(
2040
+ isinstance(benchmark_run.get(field), (int, float))
2041
+ and not isinstance(benchmark_run.get(field), bool)
2042
+ for field in (
2043
+ "official_score",
2044
+ "official_task_score",
2045
+ "score",
2046
+ )
2047
+ )
2048
+ if not verifier_scored:
2049
+ for trial in benchmark_run.get("trials") or []:
2050
+ if not isinstance(trial, dict):
2051
+ continue
2052
+ if any(
2053
+ isinstance(trial.get(field), (int, float))
2054
+ and not isinstance(trial.get(field), bool)
2055
+ for field in (
2056
+ "official_score",
2057
+ "official_task_score",
2058
+ "score",
2059
+ )
2060
+ ):
2061
+ verifier_scored = True
2062
+ break
2063
+ paired_compared = (
2064
+ _benchmark_lifecycle_schema(benchmark_comparison)
2065
+ == "benchmark_comparison_v0"
2066
+ )
2067
+ claim_reviewed = (
2068
+ _benchmark_lifecycle_schema(claim_review)
2069
+ == BENCHMARK_CLAIM_REVIEW_SCHEMA_VERSION
2070
+ )
2071
+ learning_ledgered = (
2072
+ _benchmark_lifecycle_schema(learning_ledger)
2073
+ == BENCHMARK_LEARNING_LEDGER_SCHEMA_VERSION
2074
+ )
2075
+ budget_count_allowed = _benchmark_lifecycle_budget_count_allowed(learning_ledger)
2076
+ environment_setup_readiness = _benchmark_lifecycle_environment_setup_readiness(
2077
+ benchmark_run=benchmark_run,
2078
+ preflight=preflight,
2079
+ )
2080
+ environment_setup_probe_result = (
2081
+ _benchmark_lifecycle_environment_setup_probe_result(benchmark_run)
2082
+ )
2083
+ environment_setup_repeat_cleared = (
2084
+ not environment_setup_readiness
2085
+ or environment_setup_readiness.get("same_task_repeat_allowed") is True
2086
+ )
2087
+ environment_setup_probe_completed = (
2088
+ environment_setup_probe_result.get("probe_materialized") is True
2089
+ )
2090
+
2091
+ transitions = [
2092
+ ("preflight_ready", preflight_ready),
2093
+ ("launched_process", process_launched),
2094
+ ("post_launch_materialized", materialized),
2095
+ ("compact_result_ready", compact_ready),
2096
+ ("result_ingested", result_ingested),
2097
+ ]
2098
+ if environment_setup_readiness:
2099
+ transitions.append(
2100
+ (
2101
+ "environment_setup_repeat_cleared",
2102
+ environment_setup_repeat_cleared,
2103
+ )
2104
+ )
2105
+ if environment_setup_probe_result:
2106
+ transitions.append(
2107
+ (
2108
+ "environment_setup_probe_completed",
2109
+ environment_setup_probe_completed,
2110
+ )
2111
+ )
2112
+ transitions.extend(
2113
+ [
2114
+ ("paired_compared", paired_compared),
2115
+ ("claim_reviewed", claim_reviewed),
2116
+ ("learning_ledgered", learning_ledgered),
2117
+ ("budget_counted", budget_count_allowed),
2118
+ ]
2119
+ )
2120
+ achieved = [name for name, ready in transitions if ready]
2121
+ current_phase = achieved[-1] if achieved else "not_started"
2122
+
2123
+ first_blocker = "ready_for_budget_count" if budget_count_allowed else ""
2124
+ if not preflight_ready:
2125
+ first_blocker = "preflight_not_ready"
2126
+ elif process_launched and not materialized:
2127
+ first_blocker = "post_launch_materialization_missing"
2128
+ elif materialized and not compact_ready:
2129
+ first_blocker = "compact_result_not_ready"
2130
+ elif compact_ready and not result_ingested:
2131
+ first_blocker = "compact_result_not_ingested"
2132
+ elif result_ingested and not environment_setup_repeat_cleared:
2133
+ first_blocker = "environment_setup_readiness_preflight_required"
2134
+ elif result_ingested and environment_setup_probe_completed:
2135
+ first_blocker = str(
2136
+ environment_setup_probe_result.get("repeat_blocked_by")
2137
+ or "inspect_environment_setup_probe_result_before_same_task_repeat"
2138
+ )
2139
+ elif result_ingested and not paired_compared:
2140
+ first_blocker = "paired_comparison_missing"
2141
+ elif paired_compared and not claim_reviewed:
2142
+ first_blocker = "claim_review_missing"
2143
+ elif claim_reviewed and not learning_ledgered:
2144
+ first_blocker = "benchmark_learning_ledger_missing"
2145
+ elif learning_ledgered and not budget_count_allowed:
2146
+ first_blocker = "budget_count_blocked_by_learning_ledger"
2147
+
2148
+ next_required_transition = ""
2149
+ for name, ready in transitions:
2150
+ if not ready:
2151
+ next_required_transition = name
2152
+ break
2153
+ if (
2154
+ materialized
2155
+ and compact_failure_marker_ready
2156
+ and not result_ingested
2157
+ ):
2158
+ if "compact_failure_marker_ready" not in achieved:
2159
+ achieved.append("compact_failure_marker_ready")
2160
+ current_phase = "compact_failure_marker_ready"
2161
+ first_blocker = "compact_failure_marker_ledger_ingest_required"
2162
+ next_required_transition = "compact_failure_marker_ledger_ingest"
2163
+ if result_ingested and environment_setup_probe_completed:
2164
+ current_phase = "environment_setup_probe_completed"
2165
+ next_required_transition = "case_repeat_decision"
2166
+ canonical = canonical_lifecycle(
2167
+ process_started=process_launched,
2168
+ runner_accepted_args=process_launched,
2169
+ job_root_materialized=materialized,
2170
+ trial_started=compact_ready or result_ingested,
2171
+ worker_started=result_ingested,
2172
+ result_written=result_ingested,
2173
+ verifier_scored=verifier_scored,
2174
+ )
2175
+
2176
+ routing = (
2177
+ learning_ledger.get("routing")
2178
+ if isinstance(learning_ledger, dict)
2179
+ and isinstance(learning_ledger.get("routing"), dict)
2180
+ else {}
2181
+ )
2182
+ learning_gate = (
2183
+ learning_ledger.get("learning_quota_gate")
2184
+ if isinstance(learning_ledger, dict)
2185
+ and isinstance(learning_ledger.get("learning_quota_gate"), dict)
2186
+ else {}
2187
+ )
2188
+ ledger_repeat_allowed = (
2189
+ routing.get("repeat_allowed")
2190
+ if isinstance(routing.get("repeat_allowed"), bool)
2191
+ else False
2192
+ )
2193
+ post_launch_blocker = (
2194
+ str(post_launch_materialization.get("first_blocker") or "")
2195
+ if isinstance(post_launch_materialization, dict)
2196
+ else ""
2197
+ )
2198
+ compact_failure_marker = (
2199
+ post_launch_materialization.get("compact_failure_marker")
2200
+ if isinstance(post_launch_materialization, dict)
2201
+ and isinstance(post_launch_materialization.get("compact_failure_marker"), dict)
2202
+ else {}
2203
+ )
2204
+ case_attempt_countable = compact_failure_marker.get("case_attempt_countable") is True
2205
+ benchmark_budget_countable = (
2206
+ compact_failure_marker.get("benchmark_budget_countable") is True
2207
+ )
2208
+ terminal_closeout = compact_failure_marker.get("terminal_closeout") is True
2209
+ return {
2210
+ "schema_version": BENCHMARK_LIFECYCLE_STATE_SCHEMA_VERSION,
2211
+ "current_phase": current_phase,
2212
+ "canonical_lifecycle": canonical,
2213
+ "achieved_transitions": achieved,
2214
+ "next_required_transition": next_required_transition,
2215
+ "first_blocker": first_blocker,
2216
+ "transition_ready": {name: ready for name, ready in transitions},
2217
+ "gates": {
2218
+ "launch_state_countable": materialized,
2219
+ "compact_result_ingest_allowed": compact_ready,
2220
+ "compact_failure_marker_ready": compact_failure_marker_ready,
2221
+ "terminal_closeout": terminal_closeout,
2222
+ "case_attempt_countable": case_attempt_countable,
2223
+ "benchmark_budget_countable": bool(
2224
+ benchmark_budget_countable or budget_count_allowed
2225
+ ),
2226
+ "budget_count_allowed": budget_count_allowed,
2227
+ "new_candidate_allowed": routing.get("new_candidate_allowed")
2228
+ if isinstance(routing.get("new_candidate_allowed"), bool)
2229
+ else False,
2230
+ "repeat_allowed": bool(
2231
+ ledger_repeat_allowed and environment_setup_repeat_cleared
2232
+ ),
2233
+ "environment_setup_repeat_allowed": (
2234
+ environment_setup_readiness.get("same_task_repeat_allowed")
2235
+ if environment_setup_readiness
2236
+ else None
2237
+ ),
2238
+ "environment_setup_probe_completed": environment_setup_probe_completed,
2239
+ "environment_setup_probe_case_attempt_countable": (
2240
+ environment_setup_probe_result.get("case_attempt_countable")
2241
+ if environment_setup_probe_result
2242
+ else None
2243
+ ),
2244
+ "learning_spend_allowed": learning_gate.get("spend_allowed")
2245
+ if isinstance(learning_gate.get("spend_allowed"), bool)
2246
+ else False,
2247
+ },
2248
+ "environment_setup_readiness_preflight": environment_setup_readiness,
2249
+ "environment_setup_probe_result": environment_setup_probe_result,
2250
+ "inputs": {
2251
+ "preflight_schema": _benchmark_lifecycle_schema(preflight),
2252
+ "launch_present": isinstance(launch, dict) and bool(launch),
2253
+ "post_launch_schema": _benchmark_lifecycle_schema(
2254
+ post_launch_materialization
2255
+ ),
2256
+ "post_launch_first_blocker": post_launch_blocker,
2257
+ "benchmark_run_schema": _benchmark_lifecycle_schema(benchmark_run),
2258
+ "benchmark_comparison_schema": _benchmark_lifecycle_schema(
2259
+ benchmark_comparison
2260
+ ),
2261
+ "claim_review_schema": _benchmark_lifecycle_schema(claim_review),
2262
+ "learning_ledger_schema": _benchmark_lifecycle_schema(learning_ledger),
2263
+ },
2264
+ "read_boundary": {
2265
+ "compact_only": True,
2266
+ "raw_artifacts_read": False,
2267
+ "task_text_read": False,
2268
+ "trajectory_read": False,
2269
+ "local_paths_recorded": False,
2270
+ "docker_invoked": False,
2271
+ "model_api_invoked": False,
2272
+ "upload_invoked": False,
2273
+ },
2274
+ }
2275
+
2276
+
2277
+ def build_benchmark_verifier_attribution_review(
2278
+ *,
2279
+ benchmark_runs: Iterable[dict[str, Any]],
2280
+ ) -> dict[str, Any]:
2281
+ """Classify compact verifier attribution without opening raw verifier logs."""
2282
+
2283
+ runs = [run for run in benchmark_runs if isinstance(run, dict)]
2284
+ baseline, _treatment = _claim_review_pick_runs(runs)
2285
+ run_reviews = [_verifier_attribution_run_review(run) for run in runs]
2286
+ baseline_index = 0
2287
+ if baseline is not None:
2288
+ for index, run in enumerate(runs):
2289
+ if run is baseline:
2290
+ baseline_index = index
2291
+ break
2292
+ baseline_review = run_reviews[baseline_index] if run_reviews else None
2293
+
2294
+ blockers: list[str] = []
2295
+ if baseline_review is None:
2296
+ blockers.append("missing_compact_baseline_run")
2297
+ elif baseline_review["attribution_class"].startswith("verifier_"):
2298
+ blockers.append("baseline_verifier_attribution_caveat")
2299
+ elif (
2300
+ baseline_review["attribution_class"]
2301
+ == "worker_self_validation_official_score_mismatch"
2302
+ ):
2303
+ blockers.append("baseline_worker_verifier_alignment_caveat")
2304
+ elif (
2305
+ baseline_review["attribution_class"]
2306
+ == "worker_validation_scope_ambiguous_official_score_failure"
2307
+ ):
2308
+ blockers.append("baseline_worker_validation_scope_ambiguous_caveat")
2309
+ elif baseline_review["attribution_class"] in {
2310
+ "runner_completed_official_score_zero_unattributed",
2311
+ "unattributed_score_failure",
2312
+ }:
2313
+ blockers.append("baseline_score_failure_unattributed")
2314
+ elif baseline_review["attribution_class"] == "missing_official_score":
2315
+ blockers.append("baseline_official_score_missing")
2316
+ elif _compact_positive_int(
2317
+ baseline_review.get("worker_submit_eligible_mismatch_count")
2318
+ ):
2319
+ blockers.append("baseline_submit_boundary_mismatch")
2320
+
2321
+ baseline_caveat_resolved = bool(
2322
+ baseline_review
2323
+ and baseline_review.get("claim_caveat_resolved")
2324
+ and not blockers
2325
+ )
2326
+ if (
2327
+ baseline_caveat_resolved
2328
+ and baseline_review
2329
+ and baseline_review.get("attribution_class") == "agent_exception_score_failure"
2330
+ ):
2331
+ next_action = (
2332
+ "baseline compact verifier caveat resolved as agent exception; "
2333
+ "inspect case-level exception hypothesis before same-task repeat"
2334
+ )
2335
+ elif baseline_caveat_resolved:
2336
+ next_action = (
2337
+ "baseline compact verifier caveat resolved; rerun claim review "
2338
+ "before upgrading proof strength"
2339
+ )
2340
+ elif "baseline_verifier_attribution_caveat" in blockers:
2341
+ next_action = (
2342
+ "do not upgrade claim; run same-protocol repeat or collect finer "
2343
+ "compact verifier-side attribution"
2344
+ )
2345
+ elif "baseline_worker_verifier_alignment_caveat" in blockers:
2346
+ next_action = (
2347
+ "do not upgrade claim; align worker self-validation with official "
2348
+ "verifier evidence before same-task repeat"
2349
+ )
2350
+ elif "baseline_worker_validation_scope_ambiguous_caveat" in blockers:
2351
+ next_action = (
2352
+ "do not repeat same task; add explicit worker validation_scope and "
2353
+ "claim_boundary so bridge connectivity cannot be confused with case success"
2354
+ )
2355
+ elif "baseline_score_failure_unattributed" in blockers:
2356
+ next_action = (
2357
+ "do not upgrade claim; compact baseline score failure is unattributed"
2358
+ )
2359
+ elif "missing_compact_baseline_run" in blockers:
2360
+ next_action = "provide a compact benchmark_run_v0 for the baseline arm"
2361
+ elif (
2362
+ baseline_review
2363
+ and baseline_review.get("attribution_class") == "no_score_failure"
2364
+ and not blockers
2365
+ ):
2366
+ next_action = (
2367
+ "no baseline score-failure caveat; do not claim same-task uplift, "
2368
+ "select a new material-ready case"
2369
+ )
2370
+ else:
2371
+ next_action = "keep claim blocked until compact attribution blockers are resolved"
2372
+ routing = _verifier_attribution_review_routing(
2373
+ baseline_review=baseline_review,
2374
+ blockers=blockers,
2375
+ baseline_caveat_resolved=baseline_caveat_resolved,
2376
+ )
2377
+
2378
+ return {
2379
+ "schema_version": BENCHMARK_VERIFIER_ATTRIBUTION_REVIEW_SCHEMA_VERSION,
2380
+ "input_schema_versions": {
2381
+ "benchmark_runs": [
2382
+ run.get("schema_version") for run in runs if run.get("schema_version")
2383
+ ],
2384
+ },
2385
+ "reviewed_run_count": len(run_reviews),
2386
+ "baseline_run_index": baseline_index if run_reviews else None,
2387
+ "run_reviews": run_reviews,
2388
+ "decision": {
2389
+ "baseline_claim_caveat_resolved": baseline_caveat_resolved,
2390
+ "clean_model_failure_attribution": baseline_caveat_resolved,
2391
+ "blockers": blockers,
2392
+ "next_action": next_action,
2393
+ },
2394
+ "routing": routing,
2395
+ "read_boundary": {
2396
+ "compact_only": True,
2397
+ "raw_artifacts_read": False,
2398
+ "task_text_read": False,
2399
+ "local_paths_recorded": False,
2400
+ },
2401
+ }
2402
+
2403
+
2404
+ DEFAULT_BENCHMARK_RUNNER_OWNED_FLAG_INVARIANTS = {
2405
+ "submit_eligible": WORKER_BRIDGE_BENCHMARK_RUN_REQUIRED_FIXED_FIELDS[
2406
+ "submit_eligible"
2407
+ ],
2408
+ "leaderboard_evidence": WORKER_BRIDGE_BENCHMARK_RUN_REQUIRED_FIXED_FIELDS[
2409
+ "leaderboard_evidence"
2410
+ ],
2411
+ }
2412
+ DEFAULT_BENCHMARK_RUNNER_OWNED_READ_BOUNDARY_INVARIANTS = {
2413
+ "compact_only": True,
2414
+ "raw_artifacts_read": False,
2415
+ "task_text_read": False,
2416
+ "local_paths_recorded": False,
2417
+ }
2418
+
2419
+
2420
+ def _runner_invariant_compare_bool(
2421
+ *,
2422
+ source: dict[str, Any],
2423
+ field: str,
2424
+ expected: bool,
2425
+ namespace: str,
2426
+ observed: dict[str, bool],
2427
+ mismatches: list[dict[str, Any]],
2428
+ missing_fields: list[str],
2429
+ ) -> None:
2430
+ actual = source.get(field)
2431
+ qualified_field = f"{namespace}.{field}" if namespace else field
2432
+ if isinstance(actual, bool):
2433
+ observed[qualified_field] = actual
2434
+ if actual != expected:
2435
+ mismatches.append(
2436
+ {
2437
+ "field": qualified_field,
2438
+ "expected": expected,
2439
+ "actual": actual,
2440
+ "owner": "runner",
2441
+ "reason": "worker_writeback_conflicts_with_runner_owned_boundary",
2442
+ }
2443
+ )
2444
+ return
2445
+ missing_fields.append(qualified_field)
2446
+
2447
+
2448
+ def build_benchmark_runner_invariant_review(
2449
+ benchmark_run: dict[str, Any],
2450
+ *,
2451
+ expected_flags: dict[str, bool] | None = None,
2452
+ expected_read_boundary: dict[str, bool] | None = None,
2453
+ runner_label: str | None = None,
2454
+ ) -> dict[str, Any]:
2455
+ """Compare compact worker writeback against runner-owned boundary facts."""
2456
+
2457
+ flags = expected_flags or DEFAULT_BENCHMARK_RUNNER_OWNED_FLAG_INVARIANTS
2458
+ read_boundary_expectations = (
2459
+ expected_read_boundary
2460
+ or DEFAULT_BENCHMARK_RUNNER_OWNED_READ_BOUNDARY_INVARIANTS
2461
+ )
2462
+ read_boundary = (
2463
+ benchmark_run.get("read_boundary")
2464
+ if isinstance(benchmark_run.get("read_boundary"), dict)
2465
+ else {}
2466
+ )
2467
+ observed: dict[str, bool] = {}
2468
+ mismatches: list[dict[str, Any]] = []
2469
+ missing_fields: list[str] = []
2470
+
2471
+ for field, expected in flags.items():
2472
+ _runner_invariant_compare_bool(
2473
+ source=benchmark_run,
2474
+ field=field,
2475
+ expected=bool(expected),
2476
+ namespace="",
2477
+ observed=observed,
2478
+ mismatches=mismatches,
2479
+ missing_fields=missing_fields,
2480
+ )
2481
+ for field, expected in read_boundary_expectations.items():
2482
+ _runner_invariant_compare_bool(
2483
+ source=read_boundary,
2484
+ field=field,
2485
+ expected=bool(expected),
2486
+ namespace="read_boundary",
2487
+ observed=observed,
2488
+ mismatches=mismatches,
2489
+ missing_fields=missing_fields,
2490
+ )
2491
+
2492
+ if mismatches:
2493
+ classification = "runner_owned_boundary_mismatch"
2494
+ repair_recommendation = (
2495
+ "treat worker writeback as boundary-mismatch evidence; preserve "
2496
+ "runner-owned launch/preflight facts and do not widen no-upload, "
2497
+ "no-submit, leaderboard, or raw-read claims"
2498
+ )
2499
+ elif missing_fields:
2500
+ classification = "runner_owned_boundary_incomplete"
2501
+ repair_recommendation = (
2502
+ "require compact runner-owned boundary fields before trusting the "
2503
+ "worker writeback for public claim review"
2504
+ )
2505
+ else:
2506
+ classification = "runner_owned_boundary_ok"
2507
+ repair_recommendation = (
2508
+ "accept compact boundary echo for review while keeping runner-owned "
2509
+ "fields authoritative"
2510
+ )
2511
+
2512
+ return {
2513
+ "schema_version": BENCHMARK_RUNNER_INVARIANT_REVIEW_SCHEMA_VERSION,
2514
+ "benchmark_id": benchmark_run.get("benchmark_id"),
2515
+ "job_name_present": bool(benchmark_run.get("job_name")),
2516
+ "mode": benchmark_run.get("mode"),
2517
+ "runner_label": runner_label or benchmark_run.get("source_runner"),
2518
+ "classification": classification,
2519
+ "clean": not mismatches and not missing_fields,
2520
+ "mismatch_count": len(mismatches),
2521
+ "missing_field_count": len(missing_fields),
2522
+ "mismatches": mismatches,
2523
+ "missing_fields": missing_fields[:12],
2524
+ "observed_runner_owned_fields": observed,
2525
+ "expected_runner_owned_fields": {
2526
+ **{field: bool(value) for field, value in flags.items()},
2527
+ **{
2528
+ f"read_boundary.{field}": bool(value)
2529
+ for field, value in read_boundary_expectations.items()
2530
+ },
2531
+ },
2532
+ "claim_boundary": {
2533
+ "runner_owned_fields_authoritative": True,
2534
+ "worker_may_override_runner_owned_fields": False,
2535
+ "submit_eligible": flags.get("submit_eligible") is True,
2536
+ "leaderboard_evidence": flags.get("leaderboard_evidence") is True,
2537
+ "raw_trace_excluded": True,
2538
+ },
2539
+ "repair_recommendation": repair_recommendation,
2540
+ "read_boundary": {
2541
+ "compact_only": True,
2542
+ "raw_artifacts_read": False,
2543
+ "task_text_read": False,
2544
+ "local_paths_recorded": False,
2545
+ },
2546
+ }
2547
+
2548
+
2549
+
2550
+ def _is_compactable_benchmark_run_v0(payload: dict[str, Any]) -> bool:
2551
+ """Return true for payload shapes accepted by history append-benchmark-run."""
2552
+
2553
+ if payload.get("schema_version") == "benchmark_run_v0":
2554
+ return True
2555
+ nested = payload.get("benchmark_run")
2556
+ return (
2557
+ isinstance(nested, dict)
2558
+ and nested.get("schema_version") == "benchmark_run_v0"
2559
+ )
2560
+
2561
+
2562
+ def _benchmark_result_failed(result: dict[str, Any]) -> bool:
2563
+ official = (
2564
+ result.get("official_task_score")
2565
+ if isinstance(result.get("official_task_score"), dict)
2566
+ else {}
2567
+ )
2568
+ if isinstance(official.get("passed"), bool):
2569
+ return official.get("passed") is False
2570
+ terminal_state = str(result.get("terminal_state") or "").strip().lower()
2571
+ if terminal_state in {"success", "succeeded", "passed", "resolved"}:
2572
+ return False
2573
+ return bool(terminal_state)
2574
+
2575
+
2576
+ def benchmark_result_from_benchmark_run_for_baseline_gate(
2577
+ benchmark_run: dict[str, Any],
2578
+ ) -> dict[str, Any]:
2579
+ """Project a compact benchmark_run_v0 into baseline-gate result shape.
2580
+
2581
+ Current benchmark runners increasingly write run-level compact artifacts
2582
+ because they need to preserve protocol, timing, bridge, and ledger context.
2583
+ The baseline-failure gate only needs a result-level public-safe slice:
2584
+ task id, scenario id, terminal state, score, and compact attribution labels.
2585
+ """
2586
+
2587
+ if benchmark_run.get("schema_version") != "benchmark_run_v0":
2588
+ raise ValueError("benchmark_run must be compact benchmark_run_v0")
2589
+
2590
+ safe_mode = _public_safe_benchmark_label(benchmark_run.get("mode")) or "baseline"
2591
+ trials = benchmark_run.get("trials") if isinstance(benchmark_run.get("trials"), list) else []
2592
+ first_trial = trials[0] if trials and isinstance(trials[0], dict) else {}
2593
+ case_ids = benchmark_run.get("case_ids") if isinstance(benchmark_run.get("case_ids"), list) else []
2594
+ task_id = (
2595
+ _public_safe_benchmark_label(first_trial.get("task_id"))
2596
+ or _public_safe_benchmark_label(benchmark_run.get("task_id"))
2597
+ or (_public_safe_benchmark_label(case_ids[0]) if case_ids else None)
2598
+ or _public_safe_benchmark_label(benchmark_run.get("job_name"))
2599
+ or "unknown_task"
2600
+ )
2601
+
2602
+ official = (
2603
+ benchmark_run.get("official_task_score")
2604
+ if isinstance(benchmark_run.get("official_task_score"), dict)
2605
+ else {}
2606
+ )
2607
+ score_value = official.get("value")
2608
+ if not isinstance(score_value, (int, float)) or isinstance(score_value, bool):
2609
+ score_value = benchmark_run.get("official_score")
2610
+ passed = official.get("passed")
2611
+ if not isinstance(passed, bool):
2612
+ passed = None
2613
+ if passed is None and isinstance(score_value, (int, float)) and not isinstance(score_value, bool):
2614
+ passed = score_value > 0
2615
+
2616
+ runner_status = _public_safe_benchmark_label(
2617
+ benchmark_run.get("runner_return_status")
2618
+ or benchmark_run.get("official_score_status")
2619
+ or benchmark_run.get("status")
2620
+ )
2621
+ if passed is True:
2622
+ terminal_state = "passed"
2623
+ elif passed is False:
2624
+ terminal_state = "failed"
2625
+ else:
2626
+ terminal_state = runner_status or "unknown"
2627
+
2628
+ labels: list[str] = []
2629
+ for item in (
2630
+ benchmark_run.get("score_failure_attribution"),
2631
+ benchmark_run.get("failure_class"),
2632
+ ):
2633
+ label = _public_safe_benchmark_label(item)
2634
+ if label and label not in {"none", "unknown", "missing"} and label not in labels:
2635
+ labels.append(label)
2636
+ result_labels = benchmark_run.get("failure_attribution_labels")
2637
+ if isinstance(result_labels, list):
2638
+ for item in result_labels:
2639
+ label = _public_safe_benchmark_label(item)
2640
+ if label and label not in {"none", "unknown", "missing"} and label not in labels:
2641
+ labels.append(label)
2642
+ worker_bridge_outcome = (
2643
+ benchmark_run.get("worker_bridge_outcome")
2644
+ if isinstance(benchmark_run.get("worker_bridge_outcome"), dict)
2645
+ else {}
2646
+ )
2647
+ for item in (
2648
+ worker_bridge_outcome.get("score_failure_attribution"),
2649
+ worker_bridge_outcome.get("worker_bridge_failure_attribution"),
2650
+ worker_bridge_outcome.get("worker_bridge_materialization_blocker"),
2651
+ worker_bridge_outcome.get("pre_worker_startup_blocker"),
2652
+ ):
2653
+ label = _public_safe_benchmark_label(item)
2654
+ if label and label not in {"none", "unknown", "missing"} and label not in labels:
2655
+ labels.append(label)
2656
+
2657
+ official_score: dict[str, Any] = {
2658
+ "kind": (
2659
+ _public_safe_benchmark_label(official.get("kind"))
2660
+ or _public_safe_benchmark_label(benchmark_run.get("official_score_source"))
2661
+ or "benchmark_run_official_score"
2662
+ ),
2663
+ }
2664
+ if isinstance(score_value, (int, float)) and not isinstance(score_value, bool):
2665
+ official_score["value"] = score_value
2666
+ if isinstance(passed, bool):
2667
+ official_score["passed"] = passed
2668
+
2669
+ projected: dict[str, Any] = {
2670
+ "schema_version": "benchmark_result_v0",
2671
+ "task_id": task_id,
2672
+ "scenario_id": safe_mode,
2673
+ "worker_mode": (
2674
+ _public_safe_benchmark_label(benchmark_run.get("worker_mode"))
2675
+ or "benchmark_run_worker"
2676
+ ),
2677
+ "terminal_state": terminal_state,
2678
+ "official_task_score": official_score,
2679
+ "trace_publicness": (
2680
+ _public_safe_benchmark_label(benchmark_run.get("trace_publicness"))
2681
+ or _public_safe_benchmark_label(worker_bridge_outcome.get("trace_publicness"))
2682
+ or "compact_counts_only_no_raw_trace"
2683
+ ),
2684
+ "source_schema_version": "benchmark_run_v0",
2685
+ }
2686
+ if labels:
2687
+ projected["failure_attribution_labels"] = labels[:8]
2688
+ return projected
2689
+
2690
+
2691
+ def build_benchmark_baseline_failure_gate_comparison(
2692
+ *,
2693
+ baseline_result: dict[str, Any],
2694
+ benchmark_id: str,
2695
+ baseline_mode: str = "codex_cli_goal_mode",
2696
+ treatment_scenario_id: str = "codex_loopx",
2697
+ comparison_id: str | None = None,
2698
+ failure_phase: str | None = None,
2699
+ failure_class: str | None = None,
2700
+ failure_attribution_labels: Iterable[str] | None = None,
2701
+ control_plane_addressable: bool = False,
2702
+ same_task_semantics: bool = False,
2703
+ same_runner_protocol: bool = False,
2704
+ trace_publicness_verified: bool = False,
2705
+ baseline_attempt_count: int = 1,
2706
+ minimum_next_evidence: str | None = None,
2707
+ negative_selection_reason: str | None = None,
2708
+ next_action: str | None = None,
2709
+ evidence_refs: Iterable[str] | None = None,
2710
+ ) -> dict[str, Any]:
2711
+ """Build a public-safe baseline-failure gate comparison from compact result.
2712
+
2713
+ The reducer is benchmark-generic: callers must explicitly mark whether the
2714
+ observed baseline failure is control-plane-addressable. Without that signal
2715
+ the comparison is a negative-selection gate and must not route to treatment.
2716
+ """
2717
+
2718
+ if baseline_result.get("schema_version") != "benchmark_result_v0":
2719
+ raise ValueError("baseline_result must be compact benchmark_result_v0")
2720
+
2721
+ task_id = _public_safe_benchmark_label(baseline_result.get("task_id")) or "unknown_task"
2722
+ baseline_scenario_id = (
2723
+ _public_safe_benchmark_label(baseline_result.get("scenario_id"))
2724
+ or _public_safe_benchmark_label(baseline_mode)
2725
+ or "baseline"
2726
+ )
2727
+ safe_benchmark_id = _public_safe_benchmark_label(benchmark_id) or "benchmark"
2728
+ safe_treatment_id = (
2729
+ _public_safe_benchmark_label(treatment_scenario_id)
2730
+ or "treatment"
2731
+ )
2732
+ safe_baseline_mode = (
2733
+ _public_safe_benchmark_label(baseline_mode)
2734
+ or "codex_cli_goal_mode"
2735
+ )
2736
+ terminal_state = (
2737
+ _public_safe_benchmark_label(baseline_result.get("terminal_state"))
2738
+ or "unknown"
2739
+ )
2740
+ baseline_failed = _benchmark_result_failed(baseline_result)
2741
+ labels = [
2742
+ label
2743
+ for label in (
2744
+ _public_safe_benchmark_label(item)
2745
+ for item in (failure_attribution_labels or [])
2746
+ )
2747
+ if label
2748
+ ]
2749
+ result_labels = baseline_result.get("failure_attribution_labels")
2750
+ if isinstance(result_labels, list):
2751
+ for item in result_labels:
2752
+ label = _public_safe_benchmark_label(item)
2753
+ if label and label not in labels:
2754
+ labels.append(label)
2755
+ safe_failure_phase = (
2756
+ _public_safe_benchmark_label(failure_phase)
2757
+ or ("unknown_failure_phase" if baseline_failed else "not_failed")
2758
+ )
2759
+ safe_failure_class = (
2760
+ _public_safe_benchmark_label(failure_class)
2761
+ or (labels[0] if labels else None)
2762
+ or ("unclassified_baseline_failure" if baseline_failed else "baseline_not_failed")
2763
+ )
2764
+ same_task = bool(same_task_semantics)
2765
+ same_runner = bool(same_runner_protocol)
2766
+ trace_public = bool(trace_publicness_verified)
2767
+ addressable = bool(control_plane_addressable)
2768
+ treatment_eligible = (
2769
+ baseline_failed
2770
+ and addressable
2771
+ and same_task
2772
+ and same_runner
2773
+ and trace_public
2774
+ )
2775
+
2776
+ if treatment_eligible:
2777
+ default_minimum_next = (
2778
+ "run the LoopX treatment arm on the same compactly verified task"
2779
+ )
2780
+ default_negative_reason = ""
2781
+ elif not baseline_failed:
2782
+ default_minimum_next = "select a failed goal-mode baseline before treatment"
2783
+ default_negative_reason = "baseline did not fail"
2784
+ elif not addressable:
2785
+ default_minimum_next = (
2786
+ "attribute a control-plane-addressable goal-mode baseline failure"
2787
+ )
2788
+ default_negative_reason = "baseline failure is not marked control-plane-addressable"
2789
+ elif not same_task:
2790
+ default_minimum_next = "verify same task semantics before treatment"
2791
+ default_negative_reason = "same task semantics not verified"
2792
+ elif not same_runner:
2793
+ default_minimum_next = "verify same runner protocol before treatment"
2794
+ default_negative_reason = "same runner protocol not verified"
2795
+ else:
2796
+ default_minimum_next = "verify trace publicness before treatment"
2797
+ default_negative_reason = "trace publicness not verified"
2798
+
2799
+ gate: dict[str, Any] = {
2800
+ "schema_version": "benchmark_baseline_failure_gate_v0",
2801
+ "baseline_mode": safe_baseline_mode,
2802
+ "baseline_scenario_id": baseline_scenario_id,
2803
+ "baseline_terminal_state": terminal_state,
2804
+ "baseline_failed": baseline_failed,
2805
+ "failure_phase": safe_failure_phase,
2806
+ "failure_class": safe_failure_class,
2807
+ "control_plane_addressable": addressable,
2808
+ "treatment_eligible": treatment_eligible,
2809
+ "same_task_semantics": same_task,
2810
+ "same_runner_protocol": same_runner,
2811
+ "trace_publicness_verified": trace_public,
2812
+ "baseline_attempt_count": max(1, int(baseline_attempt_count)),
2813
+ "minimum_next_evidence": (
2814
+ _public_safe_benchmark_label(minimum_next_evidence, limit=180)
2815
+ or default_minimum_next
2816
+ ),
2817
+ }
2818
+ safe_negative_reason = _public_safe_benchmark_label(
2819
+ negative_selection_reason or default_negative_reason,
2820
+ limit=180,
2821
+ )
2822
+ if safe_negative_reason:
2823
+ gate["negative_selection_reason"] = safe_negative_reason
2824
+ if labels:
2825
+ gate["failure_attribution_labels"] = labels[:8]
2826
+ safe_evidence_refs = [
2827
+ ref
2828
+ for ref in (
2829
+ _public_safe_benchmark_label(item, limit=180)
2830
+ for item in (evidence_refs or [])
2831
+ )
2832
+ if ref
2833
+ ]
2834
+ if not safe_evidence_refs:
2835
+ safe_evidence_refs = [f"benchmark_result_v0:{baseline_scenario_id}"]
2836
+ gate["evidence_refs"] = safe_evidence_refs[:8]
2837
+ safe_next_action = _public_safe_benchmark_label(next_action, limit=180)
2838
+ if safe_next_action:
2839
+ gate["next_action"] = safe_next_action
2840
+
2841
+ safe_comparison_id = (
2842
+ _public_safe_benchmark_label(comparison_id)
2843
+ or f"{task_id}_{baseline_scenario_id}_baseline_failure_gate"
2844
+ )[:180]
2845
+ comparison: dict[str, Any] = {
2846
+ "schema_version": "benchmark_comparison_v0",
2847
+ "task_id": task_id,
2848
+ "comparison_id": safe_comparison_id,
2849
+ "benchmark_id": safe_benchmark_id,
2850
+ "mode_pair": [baseline_scenario_id, safe_treatment_id],
2851
+ "baseline_scenario_id": baseline_scenario_id,
2852
+ "treatment_scenario_id": safe_treatment_id,
2853
+ "baseline_failure_gate": gate,
2854
+ "claim_boundary": {
2855
+ "leaderboard_claim_allowed": False,
2856
+ "official_score_uplift_claim_allowed": False,
2857
+ "assisted_collaboration_claim_allowed": False,
2858
+ "raw_trace_excluded": True,
2859
+ "credential_values_recorded": False,
2860
+ },
2861
+ "decision": {
2862
+ "score_uplift": False,
2863
+ "validation_enhancement_point": treatment_eligible,
2864
+ "why": (
2865
+ "Baseline failure is gate-eligible for treatment"
2866
+ if treatment_eligible
2867
+ else "Baseline is negative-selected before treatment"
2868
+ ),
2869
+ },
2870
+ }
2871
+ if safe_next_action:
2872
+ comparison["next_action"] = safe_next_action
2873
+ if labels:
2874
+ comparison["failure_attribution_labels"] = labels[:8]
2875
+ return comparison