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.
- loopx/__init__.py +5 -0
- loopx/agent_onboarding.py +654 -0
- loopx/agent_registry.py +112 -0
- loopx/ark_managed_agent_host.py +59 -0
- loopx/authority.py +805 -0
- loopx/benchmark.py +2875 -0
- loopx/benchmark_adapters/__init__.py +1 -0
- loopx/benchmark_adapters/agentissue.py +2644 -0
- loopx/benchmark_adapters/agents_last_exam.py +3998 -0
- loopx/benchmark_adapters/edgebench.py +322 -0
- loopx/benchmark_adapters/skillsbench.py +5978 -0
- loopx/benchmark_adapters/skillsbench_acp_failure_policy.py +143 -0
- loopx/benchmark_adapters/skillsbench_acp_process.py +31 -0
- loopx/benchmark_adapters/skillsbench_acp_relay.py +4832 -0
- loopx/benchmark_adapters/skillsbench_batch.py +124 -0
- loopx/benchmark_adapters/skillsbench_bridge_guard.py +209 -0
- loopx/benchmark_adapters/skillsbench_bridge_summary.py +203 -0
- loopx/benchmark_adapters/skillsbench_codex_goal_recovery.py +271 -0
- loopx/benchmark_adapters/skillsbench_codex_goal_trace.py +81 -0
- loopx/benchmark_adapters/skillsbench_codex_runtime.py +339 -0
- loopx/benchmark_adapters/skillsbench_dockerfile_runtime.py +467 -0
- loopx/benchmark_adapters/skillsbench_failure_signals.py +652 -0
- loopx/benchmark_adapters/skillsbench_proxy_runtime.py +327 -0
- loopx/benchmark_adapters/skillsbench_remote_bridge.py +402 -0
- loopx/benchmark_adapters/skillsbench_result_discovery.py +143 -0
- loopx/benchmark_adapters/skillsbench_runner_profile.py +436 -0
- loopx/benchmark_adapters/skillsbench_runner_source.py +99 -0
- loopx/benchmark_adapters/skillsbench_setup_preflight.py +771 -0
- loopx/benchmark_adapters/skillsbench_signals.py +15 -0
- loopx/benchmark_adapters/skillsbench_task_source.py +141 -0
- loopx/benchmark_adapters/skillsbench_turn_route.py +723 -0
- loopx/benchmark_adapters/skillsbench_turn_runtime.py +1069 -0
- loopx/benchmark_adapters/skillsbench_typed_repair.py +689 -0
- loopx/benchmark_adapters/skillsbench_uv_cache.py +111 -0
- loopx/benchmark_adapters/skillsbench_verifier_bootstrap.py +227 -0
- loopx/benchmark_adapters/skillsbench_verifier_cache.py +138 -0
- loopx/benchmark_adapters/terminal_bench.py +10078 -0
- loopx/benchmark_case_analysis.py +1276 -0
- loopx/benchmark_case_state.py +1079 -0
- loopx/benchmark_core/__init__.py +239 -0
- loopx/benchmark_core/adapter.py +84 -0
- loopx/benchmark_core/artifacts.py +517 -0
- loopx/benchmark_core/attempts.py +199 -0
- loopx/benchmark_core/container_exec.py +216 -0
- loopx/benchmark_core/io.py +68 -0
- loopx/benchmark_core/lifecycle.py +211 -0
- loopx/benchmark_core/loop_protocol.py +689 -0
- loopx/benchmark_core/observable_handles.py +348 -0
- loopx/benchmark_core/parity.py +256 -0
- loopx/benchmark_core/remote_closeout.py +482 -0
- loopx/benchmark_core/rounds.py +215 -0
- loopx/benchmark_core/route_profile.py +509 -0
- loopx/benchmark_core/run_permissions.py +206 -0
- loopx/benchmark_core/split_control.py +925 -0
- loopx/benchmark_core/turn_fidelity.py +326 -0
- loopx/benchmark_ledger.py +3793 -0
- loopx/benchmark_ledger_countability.py +372 -0
- loopx/benchmark_ledger_current.py +724 -0
- loopx/benchmark_trajectory.py +405 -0
- loopx/benchmarks/__init__.py +1 -0
- loopx/benchmarks/qualification/__init__.py +1 -0
- loopx/benchmarks/qualification/release_outcome_baseline.py +360 -0
- loopx/benchmarks/read_models/__init__.py +1 -0
- loopx/benchmarks/read_models/benchmark_attempt_accounting.py +53 -0
- loopx/benchmarks/read_models/benchmark_comparison.py +414 -0
- loopx/benchmarks/read_models/benchmark_event_timeline.py +113 -0
- loopx/benchmarks/read_models/benchmark_experiment_report.py +475 -0
- loopx/benchmarks/read_models/benchmark_learning_ledger.py +137 -0
- loopx/benchmarks/read_models/benchmark_lifecycle_contracts.py +228 -0
- loopx/benchmarks/read_models/benchmark_projection.py +723 -0
- loopx/benchmarks/read_models/benchmark_result.py +146 -0
- loopx/benchmarks/read_models/benchmark_run_execution_contract.py +116 -0
- loopx/benchmarks/read_models/benchmark_run_failure.py +157 -0
- loopx/benchmarks/read_models/benchmark_run_metrics.py +213 -0
- loopx/benchmarks/read_models/benchmark_run_post_execution.py +635 -0
- loopx/benchmarks/read_models/benchmark_run_pre_execution.py +541 -0
- loopx/benchmarks/read_models/benchmark_status_compaction.py +1255 -0
- loopx/benchmarks/read_models/benchmark_status_runner.py +780 -0
- loopx/benchmarks/read_models/goal_start_control_score.py +857 -0
- loopx/benchmarks/read_models/skillsbench_post_run_debug.py +746 -0
- loopx/benchmarks/read_models/skillsbench_verifier_attribution.py +269 -0
- loopx/bootstrap.py +1116 -0
- loopx/bootstrap_command_pack.py +2167 -0
- loopx/boundary_authority.py +199 -0
- loopx/canary/__init__.py +1 -0
- loopx/canary/maintainability_ratchet.py +800 -0
- loopx/canary/planner.py +1984 -0
- loopx/canary/premerge.py +1130 -0
- loopx/canary/qualification_profiles.py +309 -0
- loopx/canary/quality_surface_catalog.py +838 -0
- loopx/canary/release_profiles.py +51 -0
- loopx/canary/runner.py +1107 -0
- loopx/canary/smoke_health.py +581 -0
- loopx/canary/smoke_profiles.py +212 -0
- loopx/capabilities/__init__.py +0 -0
- loopx/capabilities/agent_turn_recall/__init__.py +17 -0
- loopx/capabilities/agent_turn_recall/cli.py +369 -0
- loopx/capabilities/agent_turn_recall/core.py +296 -0
- loopx/capabilities/auto_research/__init__.py +16 -0
- loopx/capabilities/auto_research/bootstrap_contract.py +157 -0
- loopx/capabilities/auto_research/cli.py +1468 -0
- loopx/capabilities/auto_research/core.py +11 -0
- loopx/capabilities/auto_research/defaults.py +79 -0
- loopx/capabilities/auto_research/demo_e2e.py +1848 -0
- loopx/capabilities/auto_research/demo_supervisor.py +186 -0
- loopx/capabilities/auto_research/evidence_packet.py +767 -0
- loopx/capabilities/auto_research/human_view.py +794 -0
- loopx/capabilities/auto_research/kernel.py +191 -0
- loopx/capabilities/auto_research/knn_demo_workspace.py +322 -0
- loopx/capabilities/auto_research/live_evidence.py +248 -0
- loopx/capabilities/auto_research/preset.py +176 -0
- loopx/capabilities/auto_research/research_state.py +1085 -0
- loopx/capabilities/auto_research/role_profiles.py +394 -0
- loopx/capabilities/auto_research/rollout_append.py +97 -0
- loopx/capabilities/auto_research/terminal_result_contract.py +422 -0
- loopx/capabilities/auto_research/terminal_result_projection.py +171 -0
- loopx/capabilities/auto_research/terminal_result_query.py +233 -0
- loopx/capabilities/auto_research/terminal_results.py +349 -0
- loopx/capabilities/auto_research/user_contract.py +190 -0
- loopx/capabilities/auto_research/worker_loop.py +163 -0
- loopx/capabilities/auto_research/worker_runtime.py +777 -0
- loopx/capabilities/auto_research/worker_skill/SKILL.md +343 -0
- loopx/capabilities/benchmark_toolkit/__init__.py +19 -0
- loopx/capabilities/benchmark_toolkit/integrity.py +387 -0
- loopx/capabilities/catalog.py +1875 -0
- loopx/capabilities/change_quality/__init__.py +19 -0
- loopx/capabilities/change_quality/cli.py +171 -0
- loopx/capabilities/change_quality/context.py +156 -0
- loopx/capabilities/change_quality/oracles.py +269 -0
- loopx/capabilities/change_quality/policy.py +34 -0
- loopx/capabilities/change_quality/receipt.py +482 -0
- loopx/capabilities/change_quality/result.py +493 -0
- loopx/capabilities/change_quality/scope.py +171 -0
- loopx/capabilities/change_quality/shadow.py +680 -0
- loopx/capabilities/content_ops/__init__.py +0 -0
- loopx/capabilities/content_ops/cli.py +649 -0
- loopx/capabilities/content_ops/connector_packets.py +164 -0
- loopx/capabilities/content_ops/item_lifecycle.py +1000 -0
- loopx/capabilities/content_ops/layout.py +451 -0
- loopx/capabilities/content_ops/markdown.py +456 -0
- loopx/capabilities/content_ops/schemas.py +51 -0
- loopx/capabilities/content_ops/social_browser_x.py +107 -0
- loopx/capabilities/content_ops/surface.py +1956 -0
- loopx/capabilities/content_ops/templates/layout-catalog-v0.json +72 -0
- loopx/capabilities/context_providers/__init__.py +36 -0
- loopx/capabilities/context_providers/base.py +189 -0
- loopx/capabilities/context_providers/factory.py +32 -0
- loopx/capabilities/context_providers/openviking.py +702 -0
- loopx/capabilities/context_providers/service_ownership.py +185 -0
- loopx/capabilities/decision_context/__init__.py +129 -0
- loopx/capabilities/decision_context/architecture.py +83 -0
- loopx/capabilities/decision_context/assembler.py +849 -0
- loopx/capabilities/decision_context/catalog_entry.py +195 -0
- loopx/capabilities/decision_context/cli.py +310 -0
- loopx/capabilities/decision_context/cursor_commit.py +535 -0
- loopx/capabilities/decision_context/outcome_feedback.py +352 -0
- loopx/capabilities/decision_context/packets.py +654 -0
- loopx/capabilities/decision_context/private_state.py +189 -0
- loopx/capabilities/decision_context/profile.py +453 -0
- loopx/capabilities/decision_context/providers.py +228 -0
- loopx/capabilities/decision_context/review_settlement.py +136 -0
- loopx/capabilities/decision_context/runtime.py +273 -0
- loopx/capabilities/decision_context/sources.py +415 -0
- loopx/capabilities/explore/__init__.py +1 -0
- loopx/capabilities/explore/activation.py +198 -0
- loopx/capabilities/explore/adaptive_replay_planner.py +221 -0
- loopx/capabilities/explore/child_replay_runtime.py +463 -0
- loopx/capabilities/explore/composition_frontier.py +291 -0
- loopx/capabilities/explore/counterfactual_runtime.py +578 -0
- loopx/capabilities/explore/episode_runtime.py +647 -0
- loopx/capabilities/explore/harness_checkpoint.py +171 -0
- loopx/capabilities/explore/harness_gate.py +115 -0
- loopx/capabilities/explore/harness_runtime.py +1124 -0
- loopx/capabilities/explore/replay_metrics.py +206 -0
- loopx/capabilities/explore/replay_runtime.py +1271 -0
- loopx/capabilities/explore/resource_portfolio.py +173 -0
- loopx/capabilities/explore/result_log.py +974 -0
- loopx/capabilities/explore/router_state.py +432 -0
- loopx/capabilities/explore/source_history_reconcile.py +255 -0
- loopx/capabilities/explore/speculative_scheduler.py +498 -0
- loopx/capabilities/explore/todo_branch_plan.py +650 -0
- loopx/capabilities/explore/todo_evidence.py +141 -0
- loopx/capabilities/explore/trace_runtime.py +284 -0
- loopx/capabilities/explore/worker_branch_plan.py +1257 -0
- loopx/capabilities/integration_branch/__init__.py +13 -0
- loopx/capabilities/integration_branch/cli.py +148 -0
- loopx/capabilities/integration_branch/core.py +916 -0
- loopx/capabilities/issue_fix/__init__.py +19 -0
- loopx/capabilities/issue_fix/acceptance_loop.py +1050 -0
- loopx/capabilities/issue_fix/candidate_evidence.py +503 -0
- loopx/capabilities/issue_fix/candidate_preflight.py +676 -0
- loopx/capabilities/issue_fix/cli.py +1822 -0
- loopx/capabilities/issue_fix/cli_input.py +87 -0
- loopx/capabilities/issue_fix/content_ops_cli.py +148 -0
- loopx/capabilities/issue_fix/discovered_issue_promotion.py +947 -0
- loopx/capabilities/issue_fix/explore_projection.py +710 -0
- loopx/capabilities/issue_fix/feasibility.py +542 -0
- loopx/capabilities/issue_fix/github_public.py +661 -0
- loopx/capabilities/issue_fix/intake_surface.py +832 -0
- loopx/capabilities/issue_fix/metadata_preview.py +218 -0
- loopx/capabilities/issue_fix/metrics_projection.py +1340 -0
- loopx/capabilities/issue_fix/metrics_supplement.py +634 -0
- loopx/capabilities/issue_fix/metrics_supplement_cli.py +127 -0
- loopx/capabilities/issue_fix/outcome_projection.py +1235 -0
- loopx/capabilities/issue_fix/periodic_report.py +189 -0
- loopx/capabilities/issue_fix/pr_description.py +418 -0
- loopx/capabilities/issue_fix/pr_gate_reconcile.py +496 -0
- loopx/capabilities/issue_fix/pr_gate_reconcile_cli.py +464 -0
- loopx/capabilities/issue_fix/pr_lifecycle.py +1327 -0
- loopx/capabilities/issue_fix/pr_lifecycle_rollout.py +85 -0
- loopx/capabilities/issue_fix/pr_monitor_materialization.py +257 -0
- loopx/capabilities/issue_fix/pr_review_ack.py +439 -0
- loopx/capabilities/issue_fix/provider_hooks.py +24 -0
- loopx/capabilities/issue_fix/repository_commit_evidence.py +186 -0
- loopx/capabilities/issue_fix/repository_context.py +457 -0
- loopx/capabilities/issue_fix/repository_memory.py +459 -0
- loopx/capabilities/issue_fix/repository_memory_provider.py +1454 -0
- loopx/capabilities/issue_fix/repository_snapshot.py +454 -0
- loopx/capabilities/issue_fix/reviewer_cli.py +917 -0
- loopx/capabilities/issue_fix/reviewer_notification.py +882 -0
- loopx/capabilities/issue_fix/reviewer_notification_drain.py +942 -0
- loopx/capabilities/issue_fix/reviewer_recommendation.py +1057 -0
- loopx/capabilities/issue_fix/reviewer_request.py +1282 -0
- loopx/capabilities/issue_fix/reward_memory.py +879 -0
- loopx/capabilities/issue_fix/workflow_plan.py +1286 -0
- loopx/capabilities/material_lifecycle/__init__.py +161 -0
- loopx/capabilities/material_lifecycle/_validation.py +183 -0
- loopx/capabilities/material_lifecycle/apply.py +672 -0
- loopx/capabilities/material_lifecycle/architecture.py +122 -0
- loopx/capabilities/material_lifecycle/cli.py +161 -0
- loopx/capabilities/material_lifecycle/decision_planning.py +470 -0
- loopx/capabilities/material_lifecycle/explore_execution.py +306 -0
- loopx/capabilities/material_lifecycle/intake.py +869 -0
- loopx/capabilities/material_lifecycle/inventory.py +147 -0
- loopx/capabilities/material_lifecycle/lifecycle.py +98 -0
- loopx/capabilities/material_lifecycle/preparation.py +147 -0
- loopx/capabilities/material_lifecycle/project_skill.py +83 -0
- loopx/capabilities/material_lifecycle/ranking.py +267 -0
- loopx/capabilities/material_lifecycle/readable_projection.py +500 -0
- loopx/capabilities/material_lifecycle/rebuild.py +480 -0
- loopx/capabilities/material_lifecycle/settlement.py +238 -0
- loopx/capabilities/periodic_report/__init__.py +71 -0
- loopx/capabilities/periodic_report/adapters.py +939 -0
- loopx/capabilities/periodic_report/archive.py +422 -0
- loopx/capabilities/periodic_report/bindings.py +705 -0
- loopx/capabilities/periodic_report/cli.py +277 -0
- loopx/capabilities/periodic_report/core.py +691 -0
- loopx/capabilities/periodic_report/extension_envelope.py +66 -0
- loopx/capabilities/periodic_report/presets.py +103 -0
- loopx/capabilities/periodic_report/profile.py +235 -0
- loopx/capabilities/periodic_report/project_progress.py +179 -0
- loopx/capabilities/periodic_report/triggers.py +452 -0
- loopx/capabilities/pr_review_queue/__init__.py +17 -0
- loopx/capabilities/pr_review_queue/core.py +506 -0
- loopx/capabilities/pr_review_queue/review_contract.py +506 -0
- loopx/capabilities/registry.py +192 -0
- loopx/capabilities/reward_memory/__init__.py +75 -0
- loopx/capabilities/reward_memory/application.py +819 -0
- loopx/capabilities/reward_memory/architecture.py +572 -0
- loopx/capabilities/reward_memory/candidate_review.py +511 -0
- loopx/capabilities/reward_memory/cli.py +469 -0
- loopx/capabilities/reward_memory/dogfood.py +574 -0
- loopx/capabilities/reward_memory/evaluation.py +296 -0
- loopx/capabilities/reward_memory/evaluation_fixtures.py +362 -0
- loopx/capabilities/reward_memory/experiment.py +567 -0
- loopx/capabilities/reward_memory/health.py +222 -0
- loopx/capabilities/reward_memory/ingestion.py +519 -0
- loopx/capabilities/reward_memory/registry.py +600 -0
- loopx/capabilities/reward_memory/runtime_hooks.py +312 -0
- loopx/capabilities/reward_memory/scoped_feedback.py +173 -0
- loopx/capabilities/semantic_preference/__init__.py +12 -0
- loopx/capabilities/semantic_preference/cli.py +189 -0
- loopx/capabilities/semantic_preference/contract.py +592 -0
- loopx/capabilities/semantic_preference/reward_memory.py +62 -0
- loopx/capabilities/value_connectors/__init__.py +1 -0
- loopx/capabilities/value_connectors/cli.py +401 -0
- loopx/capabilities/value_connectors/finance_extension_migration.py +108 -0
- loopx/capabilities/value_connectors/install_check.py +147 -0
- loopx/capabilities/value_connectors/planner.py +733 -0
- loopx/capabilities/value_connectors/source_map.py +446 -0
- loopx/claude_goal_baseline.py +138 -0
- loopx/claude_goal_mode/__init__.py +23 -0
- loopx/claude_goal_mode/hooks/goal_policy.py +212 -0
- loopx/claude_goal_mode/hooks/goal_state.py +139 -0
- loopx/claude_goal_mode/mcp/loopx_mcp.py +167 -0
- loopx/claude_goal_mode/scripts/connect.py +103 -0
- loopx/claude_goal_mode/scripts/goalmode_cmd.py +241 -0
- loopx/claude_goal_mode/scripts/install.py +328 -0
- loopx/claude_goal_mode/statusline/goal_status.py +97 -0
- loopx/cli.py +836 -0
- loopx/cli_commands/__init__.py +334 -0
- loopx/cli_commands/_host_thread.py +13 -0
- loopx/cli_commands/agentissue_runner_flow.py +447 -0
- loopx/cli_commands/agents_last_exam.py +160 -0
- loopx/cli_commands/agents_last_exam_baked_input.py +302 -0
- loopx/cli_commands/agents_last_exam_host_codex.py +374 -0
- loopx/cli_commands/agents_last_exam_launch_dry_run.py +372 -0
- loopx/cli_commands/agents_last_exam_local_plan.py +322 -0
- loopx/cli_commands/agents_last_exam_runner_source.py +352 -0
- loopx/cli_commands/agents_last_exam_task_material.py +335 -0
- loopx/cli_commands/agents_last_exam_validation_gate.py +236 -0
- loopx/cli_commands/benchmark_boundary.py +499 -0
- loopx/cli_commands/benchmark_dispatch.py +161 -0
- loopx/cli_commands/benchmark_release_outcome.py +123 -0
- loopx/cli_commands/benchmark_review_lifecycle.py +1275 -0
- loopx/cli_commands/benchmark_run_ledger.py +763 -0
- loopx/cli_commands/benchmark_run_ledger_case_analysis.py +249 -0
- loopx/cli_commands/benchmark_run_ledger_classification.py +45 -0
- loopx/cli_commands/benchmark_run_ledger_maintenance.py +486 -0
- loopx/cli_commands/benchmark_run_ledger_maintenance_registration.py +342 -0
- loopx/cli_commands/benchmark_run_ledger_maintenance_rendering.py +233 -0
- loopx/cli_commands/benchmark_run_ledger_parity.py +92 -0
- loopx/cli_commands/bootstrap_connect.py +238 -0
- loopx/cli_commands/canary.py +707 -0
- loopx/cli_commands/canary_release_qualification.py +79 -0
- loopx/cli_commands/capability.py +96 -0
- loopx/cli_commands/doctor.py +43 -0
- loopx/cli_commands/dreaming.py +143 -0
- loopx/cli_commands/edgebench.py +205 -0
- loopx/cli_commands/evidence_log.py +275 -0
- loopx/cli_commands/explore.py +989 -0
- loopx/cli_commands/explore_planning_commands.py +157 -0
- loopx/cli_commands/extension.py +271 -0
- loopx/cli_commands/first_run_report.py +73 -0
- loopx/cli_commands/goal_channel.py +656 -0
- loopx/cli_commands/handoff_mode.py +158 -0
- loopx/cli_commands/history.py +622 -0
- loopx/cli_commands/host_mode_plan.py +113 -0
- loopx/cli_commands/lark_inbox.py +431 -0
- loopx/cli_commands/lark_kanban.py +629 -0
- loopx/cli_commands/ml_experiment.py +321 -0
- loopx/cli_commands/multi_agent.py +211 -0
- loopx/cli_commands/opencode2_goal_worker.py +217 -0
- loopx/cli_commands/pr_review.py +167 -0
- loopx/cli_commands/presentation.py +218 -0
- loopx/cli_commands/preset.py +96 -0
- loopx/cli_commands/project.py +150 -0
- loopx/cli_commands/project_lifecycle.py +915 -0
- loopx/cli_commands/quota.py +859 -0
- loopx/cli_commands/quota_registration.py +241 -0
- loopx/cli_commands/quota_request.py +113 -0
- loopx/cli_commands/ready_score.py +110 -0
- loopx/cli_commands/registry_admin.py +975 -0
- loopx/cli_commands/registry_admin_configure.py +344 -0
- loopx/cli_commands/registry_admin_peer.py +84 -0
- loopx/cli_commands/registry_authority.py +218 -0
- loopx/cli_commands/review_batch.py +146 -0
- loopx/cli_commands/slash_commands.py +145 -0
- loopx/cli_commands/start_goal.py +251 -0
- loopx/cli_commands/starter.py +175 -0
- loopx/cli_commands/starter_bootstrap.py +179 -0
- loopx/cli_commands/starter_bootstrap_registration.py +198 -0
- loopx/cli_commands/starter_runtime_idle.py +107 -0
- loopx/cli_commands/starter_scheduler.py +207 -0
- loopx/cli_commands/starter_session_runtime.py +152 -0
- loopx/cli_commands/starter_visible_common.py +54 -0
- loopx/cli_commands/starter_visible_driver.py +161 -0
- loopx/cli_commands/starter_visible_pilot.py +278 -0
- loopx/cli_commands/status.py +867 -0
- loopx/cli_commands/status_registration.py +239 -0
- loopx/cli_commands/summary_all.py +222 -0
- loopx/cli_commands/support_control.py +809 -0
- loopx/cli_commands/support_control_registry.py +68 -0
- loopx/cli_commands/support_control_supervisor.py +289 -0
- loopx/cli_commands/task_lease.py +306 -0
- loopx/cli_commands/terminal_bench_adapter.py +717 -0
- loopx/cli_commands/terminal_bench_environment_result.py +1246 -0
- loopx/cli_commands/todo.py +940 -0
- loopx/cli_commands/todo_argument_validation.py +572 -0
- loopx/cli_commands/todo_event.py +114 -0
- loopx/cli_commands/turn.py +804 -0
- loopx/cli_commands/version.py +46 -0
- loopx/cli_commands/worker_bridge.py +659 -0
- loopx/cli_rollout.py +314 -0
- loopx/codex_cli_goal_tui.py +672 -0
- loopx/codex_cli_probe.py +1530 -0
- loopx/codex_cli_probe_markdown.py +935 -0
- loopx/codex_cli_runtime_probe.py +733 -0
- loopx/codex_cli_scheduler.py +564 -0
- loopx/codex_goal_baseline.py +620 -0
- loopx/configuration_catalog.py +617 -0
- loopx/configure_goal.py +1375 -0
- loopx/contract.py +996 -0
- loopx/control_plane/__init__.py +71 -0
- loopx/control_plane/agents/__init__.py +1 -0
- loopx/control_plane/agents/agent_lane_recommendation.py +516 -0
- loopx/control_plane/agents/agent_scope.py +1578 -0
- loopx/control_plane/agents/agent_scope_frontier.py +60 -0
- loopx/control_plane/agents/capability_gate.py +531 -0
- loopx/control_plane/agents/identity.py +140 -0
- loopx/control_plane/agents/legacy_migration.py +169 -0
- loopx/control_plane/agents/management_projection.py +658 -0
- loopx/control_plane/agents/material_frontier.py +608 -0
- loopx/control_plane/agents/material_handoff.py +156 -0
- loopx/control_plane/agents/multi_agent/__init__.py +1 -0
- loopx/control_plane/agents/multi_agent/codex_executable.py +207 -0
- loopx/control_plane/agents/multi_agent/collective_round_ledger.py +387 -0
- loopx/control_plane/agents/multi_agent/contract.py +474 -0
- loopx/control_plane/agents/multi_agent/recipe.py +110 -0
- loopx/control_plane/agents/multi_agent/role_successor.py +297 -0
- loopx/control_plane/agents/multi_agent/runtime_scripts.py +426 -0
- loopx/control_plane/agents/multi_agent/visible_launch_policy.py +149 -0
- loopx/control_plane/agents/multi_agent/visible_wake_scheduler.py +392 -0
- loopx/control_plane/agents/profile.py +216 -0
- loopx/control_plane/agents/runtime_model.py +73 -0
- loopx/control_plane/agents/subagent_activity.py +164 -0
- loopx/control_plane/agents/supervisor.py +544 -0
- loopx/control_plane/agents/supervisor_events.py +462 -0
- loopx/control_plane/agents/supervisor_inject.py +204 -0
- loopx/control_plane/agents/work_mode.py +56 -0
- loopx/control_plane/agents/workspace_guard.py +364 -0
- loopx/control_plane/effect_program.py +644 -0
- loopx/control_plane/goals/__init__.py +1 -0
- loopx/control_plane/goals/active_state_event_projection.py +103 -0
- loopx/control_plane/goals/active_state_metadata.py +47 -0
- loopx/control_plane/goals/active_state_sections.py +58 -0
- loopx/control_plane/goals/configure_goal_service.py +354 -0
- loopx/control_plane/goals/contract_health.py +132 -0
- loopx/control_plane/goals/dreaming.py +152 -0
- loopx/control_plane/goals/global_registry_health.py +199 -0
- loopx/control_plane/goals/global_registry_shadow.py +33 -0
- loopx/control_plane/goals/goal_channel.py +34 -0
- loopx/control_plane/goals/goal_channel_projection.py +560 -0
- loopx/control_plane/goals/goal_frontier/__init__.py +1917 -0
- loopx/control_plane/goals/goal_frontier/ack_policy.py +149 -0
- loopx/control_plane/goals/goal_frontier/outcome_continuity.py +437 -0
- loopx/control_plane/goals/goal_frontier/replan_rules.py +210 -0
- loopx/control_plane/goals/goal_frontier/semantic_history.py +314 -0
- loopx/control_plane/goals/goal_frontier/terminal.py +180 -0
- loopx/control_plane/goals/goal_vision.py +443 -0
- loopx/control_plane/goals/goal_vision_policy.py +36 -0
- loopx/control_plane/goals/goal_vision_state.py +62 -0
- loopx/control_plane/goals/goal_vision_wait.py +290 -0
- loopx/control_plane/goals/path_resolution.py +20 -0
- loopx/control_plane/goals/start_contract.py +206 -0
- loopx/control_plane/goals/vision_checkpoint.py +92 -0
- loopx/control_plane/handoff/__init__.py +1 -0
- loopx/control_plane/handoff/cross_runtime_impl_review.py +311 -0
- loopx/control_plane/handoff/delivery_contract.py +161 -0
- loopx/control_plane/handoff/handoff_runs.py +71 -0
- loopx/control_plane/handoff/project_handoff.py +155 -0
- loopx/control_plane/handoff/review_batch.py +463 -0
- loopx/control_plane/handoff/review_packet_context.py +216 -0
- loopx/control_plane/heartbeat/agent.py +173 -0
- loopx/control_plane/heartbeat/budget.py +66 -0
- loopx/control_plane/heartbeat/builder.py +501 -0
- loopx/control_plane/heartbeat/host.py +64 -0
- loopx/control_plane/heartbeat/rules.py +68 -0
- loopx/control_plane/heartbeat/task_body.py +759 -0
- loopx/control_plane/heartbeat/visible_goal.py +86 -0
- loopx/control_plane/projects/__init__.py +1 -0
- loopx/control_plane/projects/contract.py +25 -0
- loopx/control_plane/projects/registry.py +663 -0
- loopx/control_plane/quota/__init__.py +1 -0
- loopx/control_plane/quota/cli_projection.py +704 -0
- loopx/control_plane/quota/decision_summary.py +431 -0
- loopx/control_plane/quota/effect_program.py +152 -0
- loopx/control_plane/quota/error_codes.py +19 -0
- loopx/control_plane/quota/goal_boundary.py +464 -0
- loopx/control_plane/quota/heartbeat_receipt.py +277 -0
- loopx/control_plane/quota/heartbeat_recommendation.py +718 -0
- loopx/control_plane/quota/host_poll_receipts.py +162 -0
- loopx/control_plane/quota/live_decision.py +142 -0
- loopx/control_plane/quota/monitor_poll.py +786 -0
- loopx/control_plane/quota/policy_constants.py +40 -0
- loopx/control_plane/quota/projection_repair.py +262 -0
- loopx/control_plane/quota/recent_runs.py +210 -0
- loopx/control_plane/quota/scheduler_ack.py +490 -0
- loopx/control_plane/quota/selected_todo_projection.py +139 -0
- loopx/control_plane/quota/settlement.py +437 -0
- loopx/control_plane/quota/settlement_cli.py +246 -0
- loopx/control_plane/quota/settlement_validation.py +64 -0
- loopx/control_plane/quota/settlement_workspace_causality.py +180 -0
- loopx/control_plane/quota/should_run.py +249 -0
- loopx/control_plane/quota/should_run_packet.py +1165 -0
- loopx/control_plane/quota/should_run_prepare.py +675 -0
- loopx/control_plane/quota/slot_accounting.py +1123 -0
- loopx/control_plane/quota/spend_sources.py +11 -0
- loopx/control_plane/quota/stall_repair.py +397 -0
- loopx/control_plane/quota/states.py +29 -0
- loopx/control_plane/quota/task_orchestration.py +448 -0
- loopx/control_plane/quota/task_orchestration_admission.py +497 -0
- loopx/control_plane/quota/turn_envelope.py +889 -0
- loopx/control_plane/quota/usage_summary.py +140 -0
- loopx/control_plane/reward_memory.py +43 -0
- loopx/control_plane/runtime/__init__.py +2 -0
- loopx/control_plane/runtime/active_user_assisted_pilot.py +275 -0
- loopx/control_plane/runtime/agent_scoped_evidence_log.py +435 -0
- loopx/control_plane/runtime/decision_freshness.py +203 -0
- loopx/control_plane/runtime/event_ledger.py +197 -0
- loopx/control_plane/runtime/event_store_migration_bridge.py +196 -0
- loopx/control_plane/runtime/goal_project_route.py +70 -0
- loopx/control_plane/runtime/local_state_write_correctness.py +242 -0
- loopx/control_plane/runtime/promotion_readiness.py +152 -0
- loopx/control_plane/runtime/public_safety.py +120 -0
- loopx/control_plane/runtime/run_artifacts.py +78 -0
- loopx/control_plane/runtime/run_compaction.py +397 -0
- loopx/control_plane/runtime/run_context_retention.py +241 -0
- loopx/control_plane/runtime/run_history.py +132 -0
- loopx/control_plane/runtime/run_index_duplicates.py +205 -0
- loopx/control_plane/runtime/run_index_rebuild.py +263 -0
- loopx/control_plane/runtime/run_ingest_health.py +336 -0
- loopx/control_plane/runtime/runtime_projection_route.py +624 -0
- loopx/control_plane/runtime/runtime_projection_writer.py +98 -0
- loopx/control_plane/runtime/session_runtime.py +339 -0
- loopx/control_plane/runtime/shared_runtime_material_projection.py +332 -0
- loopx/control_plane/runtime/shared_runtime_refresh_projection.py +183 -0
- loopx/control_plane/runtime/stale_latest_run.py +90 -0
- loopx/control_plane/runtime/status_classifications.py +49 -0
- loopx/control_plane/runtime/status_projection_cache.py +235 -0
- loopx/control_plane/runtime/stride_observation.py +144 -0
- loopx/control_plane/runtime/time.py +39 -0
- loopx/control_plane/runtime/trajectory_hygiene.py +149 -0
- loopx/control_plane/runtime/validation_command.py +69 -0
- loopx/control_plane/scheduler/__init__.py +1 -0
- loopx/control_plane/scheduler/ack.py +329 -0
- loopx/control_plane/scheduler/arbitration.py +188 -0
- loopx/control_plane/scheduler/automation_liveness.py +183 -0
- loopx/control_plane/scheduler/execution_context.py +555 -0
- loopx/control_plane/scheduler/external_evidence_observation.py +428 -0
- loopx/control_plane/scheduler/monitor_display.py +143 -0
- loopx/control_plane/scheduler/monitor_poll_policy.py +161 -0
- loopx/control_plane/scheduler/monitor_poll_writeback.py +351 -0
- loopx/control_plane/scheduler/monitor_target.py +64 -0
- loopx/control_plane/scheduler/monitor_todo.py +146 -0
- loopx/control_plane/scheduler/monitor_wait.py +237 -0
- loopx/control_plane/scheduler/scheduler_hint.py +1284 -0
- loopx/control_plane/scheduler/state.py +354 -0
- loopx/control_plane/scheduler/state_transition_rules.py +179 -0
- loopx/control_plane/scheduler/time.py +10 -0
- loopx/control_plane/settlement_driver.py +293 -0
- loopx/control_plane/status/__init__.py +6 -0
- loopx/control_plane/status/active_state_projection.py +105 -0
- loopx/control_plane/status/agent_lane_projection.py +375 -0
- loopx/control_plane/status/attention_projection.py +74 -0
- loopx/control_plane/status/autonomous_replan_projection.py +103 -0
- loopx/control_plane/status/collection.py +140 -0
- loopx/control_plane/status/contract_projection.py +31 -0
- loopx/control_plane/status/dreaming_projection.py +52 -0
- loopx/control_plane/status/goal_attention_projection.py +157 -0
- loopx/control_plane/status/lifecycle_projection.py +110 -0
- loopx/control_plane/status/monitor_display_projection.py +69 -0
- loopx/control_plane/status/registry_health_projection.py +75 -0
- loopx/control_plane/status/run_projection.py +70 -0
- loopx/control_plane/status/runtime_summaries.py +161 -0
- loopx/control_plane/testing/__init__.py +1 -0
- loopx/control_plane/testing/actual_default_model_behavior_portfolio.py +1371 -0
- loopx/control_plane/testing/canary_harness.py +182 -0
- loopx/control_plane/testing/capability_monitor_repair_tool_behavior.py +674 -0
- loopx/control_plane/testing/cli_output_budget.py +807 -0
- loopx/control_plane/testing/cli_output_differential.py +250 -0
- loopx/control_plane/testing/cli_output_semantics.py +87 -0
- loopx/control_plane/testing/control_plane_composition_scenarios.py +225 -0
- loopx/control_plane/testing/decision_replay.py +268 -0
- loopx/control_plane/testing/doubao_model_behavior_actor.py +559 -0
- loopx/control_plane/testing/model_behavior_corpus.py +344 -0
- loopx/control_plane/testing/model_behavior_qualification.py +769 -0
- loopx/control_plane/testing/model_behavior_retained_cases.py +235 -0
- loopx/control_plane/testing/model_tool_behavior.py +536 -0
- loopx/control_plane/testing/onboarding_model_behavior_qualification.py +642 -0
- loopx/control_plane/testing/quota_fixtures.py +208 -0
- loopx/control_plane/testing/quota_should_run_parity.py +57 -0
- loopx/control_plane/testing/release_commit_qualification.py +671 -0
- loopx/control_plane/testing/replan_semantic_action_behavior.py +1302 -0
- loopx/control_plane/testing/scoped_gate_successor_tool_behavior.py +527 -0
- loopx/control_plane/testing/selected_todo_tool_behavior.py +1002 -0
- loopx/control_plane/testing/terminal_settlement_tool_behavior.py +656 -0
- loopx/control_plane/todos/__init__.py +1 -0
- loopx/control_plane/todos/active_state_editing.py +296 -0
- loopx/control_plane/todos/active_state_todo_parser.py +138 -0
- loopx/control_plane/todos/active_state_todos.py +175 -0
- loopx/control_plane/todos/addition.py +103 -0
- loopx/control_plane/todos/claim_visibility.py +253 -0
- loopx/control_plane/todos/completed_archive.py +139 -0
- loopx/control_plane/todos/completion_fence.py +49 -0
- loopx/control_plane/todos/completion_policy.py +153 -0
- loopx/control_plane/todos/completion_validation.py +248 -0
- loopx/control_plane/todos/completion_validation_accountability.py +27 -0
- loopx/control_plane/todos/completion_validation_projection.py +57 -0
- loopx/control_plane/todos/contract.py +1476 -0
- loopx/control_plane/todos/decision_scope.py +554 -0
- loopx/control_plane/todos/deferred_resume.py +546 -0
- loopx/control_plane/todos/durable_completion.py +201 -0
- loopx/control_plane/todos/event_writeback.py +484 -0
- loopx/control_plane/todos/frontier_deadline.py +132 -0
- loopx/control_plane/todos/handoff_gate.py +283 -0
- loopx/control_plane/todos/handoff_mode.py +444 -0
- loopx/control_plane/todos/handoff_note.py +202 -0
- loopx/control_plane/todos/line_update.py +361 -0
- loopx/control_plane/todos/list_projection.py +205 -0
- loopx/control_plane/todos/markdown.py +199 -0
- loopx/control_plane/todos/monitor_metadata.py +88 -0
- loopx/control_plane/todos/mutation_authority.py +299 -0
- loopx/control_plane/todos/projection.py +655 -0
- loopx/control_plane/todos/quota_summary.py +1138 -0
- loopx/control_plane/todos/route_continuation.py +267 -0
- loopx/control_plane/todos/succession_warning.py +174 -0
- loopx/control_plane/todos/summary_item.py +223 -0
- loopx/control_plane/todos/text.py +30 -0
- loopx/control_plane/todos/todo_index.py +226 -0
- loopx/control_plane/todos/todo_summary.py +1458 -0
- loopx/control_plane/todos/unblock_resume.py +326 -0
- loopx/control_plane/todos/user_gate.py +263 -0
- loopx/control_plane/todos/write_hint.py +63 -0
- loopx/control_plane/todos/write_policy.py +135 -0
- loopx/control_plane/turn_driver/__init__.py +85 -0
- loopx/control_plane/turn_driver/codex_cli.py +502 -0
- loopx/control_plane/turn_driver/driver.py +355 -0
- loopx/control_plane/turn_driver/executor.py +1468 -0
- loopx/control_plane/turn_driver/loop_controller.py +669 -0
- loopx/control_plane/turn_driver/settlement.py +318 -0
- loopx/control_plane/turn_driver/transaction.py +375 -0
- loopx/control_plane/work_items/__init__.py +1 -0
- loopx/control_plane/work_items/attention_fields.py +56 -0
- loopx/control_plane/work_items/attention_item.py +77 -0
- loopx/control_plane/work_items/attention_queue.py +322 -0
- loopx/control_plane/work_items/attention_routing.py +213 -0
- loopx/control_plane/work_items/autonomous_candidates.py +135 -0
- loopx/control_plane/work_items/autonomous_replan_ack.py +276 -0
- loopx/control_plane/work_items/autonomous_replan_obligation.py +786 -0
- loopx/control_plane/work_items/backlog_hygiene.py +59 -0
- loopx/control_plane/work_items/capability_monitor_fallback.py +221 -0
- loopx/control_plane/work_items/delivery_batch_scale.py +66 -0
- loopx/control_plane/work_items/delivery_outcome.py +152 -0
- loopx/control_plane/work_items/delivery_signals.py +113 -0
- loopx/control_plane/work_items/execution_obligation.py +235 -0
- loopx/control_plane/work_items/goal_route_hint.py +320 -0
- loopx/control_plane/work_items/interaction_contract.py +1540 -0
- loopx/control_plane/work_items/issue_meta_surface.py +159 -0
- loopx/control_plane/work_items/lifecycle.py +139 -0
- loopx/control_plane/work_items/operator_inbox.py +266 -0
- loopx/control_plane/work_items/outcome_followthrough.py +69 -0
- loopx/control_plane/work_items/primary_action.py +326 -0
- loopx/control_plane/work_items/progress_observation.py +630 -0
- loopx/control_plane/work_items/project_asset.py +675 -0
- loopx/control_plane/work_items/repair_delta.py +693 -0
- loopx/control_plane/work_items/runtime_capability_reentry.py +168 -0
- loopx/control_plane/work_items/semantic_replan_writeback.py +177 -0
- loopx/control_plane/work_items/status_contract.py +49 -0
- loopx/control_plane/work_items/task_graph.py +1046 -0
- loopx/control_plane/work_items/task_lease.py +1254 -0
- loopx/control_plane/work_items/task_lease_settlement.py +422 -0
- loopx/control_plane/work_items/work_lane.py +510 -0
- loopx/control_plane/work_items/work_lane_context.py +161 -0
- loopx/demo.py +247 -0
- loopx/diagnose.py +633 -0
- loopx/doctor.py +1251 -0
- loopx/domain_packs/__init__.py +1 -0
- loopx/domain_packs/issue_fix.py +571 -0
- loopx/domain_packs/ml_experiment.py +854 -0
- loopx/domain_state.py +137 -0
- loopx/dreaming.py +706 -0
- loopx/entrypoint.py +16 -0
- loopx/event_sourced_state.py +981 -0
- loopx/execution_profile.py +286 -0
- loopx/experiments/__init__.py +1 -0
- loopx/experiments/planner_worker/__init__.py +1 -0
- loopx/experiments/planner_worker/contract.py +523 -0
- loopx/experiments/planner_worker/runtime.py +391 -0
- loopx/experiments/planner_worker/traex.py +461 -0
- loopx/explore_graph.py +11 -0
- loopx/extensions/__init__.py +1 -0
- loopx/extensions/bundled.py +28 -0
- loopx/extensions/execution_envelope.py +126 -0
- loopx/extensions/lark/__init__.py +11 -0
- loopx/extensions/lark/event_collector.py +478 -0
- loopx/extensions/lark/event_collector_runtime.py +506 -0
- loopx/extensions/lark/event_inbox.py +454 -0
- loopx/extensions/lark/extension.toml +88 -0
- loopx/extensions/lark/goal_channel.py +44 -0
- loopx/extensions/lark/goal_channel_contracts.py +388 -0
- loopx/extensions/lark/goal_channel_lifecycle.py +218 -0
- loopx/extensions/lark/goal_channel_runtime.py +792 -0
- loopx/extensions/lark/goal_channel_setup.py +805 -0
- loopx/extensions/lark/goal_channel_targets.py +215 -0
- loopx/extensions/lark/goal_channel_transport.py +281 -0
- loopx/extensions/lark/inbox_reactions.py +650 -0
- loopx/extensions/lark/inbox_reply.py +430 -0
- loopx/extensions/lark/presentation/__init__.py +11 -0
- loopx/extensions/lark/presentation/explore_results.py +2276 -0
- loopx/extensions/lark/presentation/explore_singleflight.py +127 -0
- loopx/extensions/lark/presentation/explore_source_guard.py +121 -0
- loopx/extensions/lark/presentation/explore_stage_document.py +703 -0
- loopx/extensions/lark/presentation/explore_visual_integrity.py +122 -0
- loopx/extensions/lark/presentation/explore_visual_readback.py +452 -0
- loopx/extensions/lark/presentation/explore_visual_styles.py +156 -0
- loopx/extensions/lark/presentation/issue_fix_surface.py +612 -0
- loopx/extensions/lark/presentation/kanban.py +2791 -0
- loopx/extensions/lark/presentation/message_card.py +112 -0
- loopx/extensions/lark/presentation/periodic_report.py +261 -0
- loopx/extensions/lark/presentation/projection_rows.py +600 -0
- loopx/extensions/lark/presentation/record_io.py +95 -0
- loopx/extensions/lark/presentation/sync_receipt.py +145 -0
- loopx/extensions/lark/private_json.py +40 -0
- loopx/extensions/lark/provider.py +86 -0
- loopx/extensions/lark/reviewer_notification.py +604 -0
- loopx/extensions/manifest.py +385 -0
- loopx/extensions/openviking_periodic_report/__init__.py +17 -0
- loopx/extensions/openviking_periodic_report/activation.py +173 -0
- loopx/extensions/openviking_periodic_report/extension.toml +17 -0
- loopx/extensions/openviking_periodic_report/provider.py +355 -0
- loopx/extensions/openviking_periodic_report/sink.py +117 -0
- loopx/extensions/openviking_semantic_preference/__init__.py +5 -0
- loopx/extensions/openviking_semantic_preference/extension.toml +16 -0
- loopx/extensions/openviking_semantic_preference/history_export.py +484 -0
- loopx/extensions/openviking_semantic_preference/project_peer.py +68 -0
- loopx/extensions/openviking_semantic_preference/provider.py +312 -0
- loopx/extensions/presentation.py +979 -0
- loopx/extensions/process_runtime.py +204 -0
- loopx/extensions/readiness.py +168 -0
- loopx/extensions/runtime.py +931 -0
- loopx/extensions/scaffold.py +335 -0
- loopx/feedback.py +581 -0
- loopx/file_lock.py +382 -0
- loopx/global_registry.py +842 -0
- loopx/global_risks.py +970 -0
- loopx/global_todos.py +568 -0
- loopx/handoff_budget.py +28 -0
- loopx/heartbeat_prequota.py +80 -0
- loopx/heartbeat_prompt.py +159 -0
- loopx/help_surface.py +516 -0
- loopx/history.py +1507 -0
- loopx/host_loop_activation.py +1311 -0
- loopx/host_mode_planner.py +991 -0
- loopx/install_contract.py +1 -0
- loopx/interface_budget.py +196 -0
- loopx/long_task_cadence.py +208 -0
- loopx/materials.py +185 -0
- loopx/ml_experiment.py +3 -0
- loopx/onboarding.py +214 -0
- loopx/opencode2_goal_mode/README.md +81 -0
- loopx/opencode2_goal_mode/__init__.py +9 -0
- loopx/opencode2_goal_mode/opencode2-goal-worker.mjs +1018 -0
- loopx/opencode_goal_mode/README.md +99 -0
- loopx/opencode_goal_mode/__init__.py +13 -0
- loopx/opencode_goal_mode/goal-bridge-runtime.mjs +858 -0
- loopx/opencode_goal_mode/loopx-goal.js +8 -0
- loopx/operator_gate.py +420 -0
- loopx/orchestration.py +127 -0
- loopx/paths.py +59 -0
- loopx/pi_goal_mode/README.md +67 -0
- loopx/pi_goal_mode/__init__.py +13 -0
- loopx/pi_goal_mode/loopx-goal.ts +254 -0
- loopx/pi_goal_mode/pi-goal-loop-runtime.mjs +574 -0
- loopx/pr_review.py +1206 -0
- loopx/presentation/__init__.py +1 -0
- loopx/presentation/explore_views.py +1334 -0
- loopx/presentation/markdown.py +61 -0
- loopx/presentation/projection_source_reconcile.py +140 -0
- loopx/presentation/public_safety.py +42 -0
- loopx/presentation/renderers/__init__.py +17 -0
- loopx/presentation/renderers/goal_channel_html.py +269 -0
- loopx/presentation/renderers/periodic_report_html.py +786 -0
- loopx/presentation/renderers/periodic_report_markdown.py +184 -0
- loopx/presentation/renderers/quota_event_markdown.py +116 -0
- loopx/presentation/renderers/quota_markdown.py +1112 -0
- loopx/presentation/renderers/status_markdown.py +1570 -0
- loopx/presentation/renderers/trajectory_hygiene_markdown.py +39 -0
- loopx/presentation/renderers/turn_envelope_markdown.py +33 -0
- loopx/presentation/sinks/__init__.py +5 -0
- loopx/presentation/sinks/openviking_periodic_report.py +7 -0
- loopx/presentation/static_site.py +691 -0
- loopx/presets.py +369 -0
- loopx/project_alias.py +217 -0
- loopx/project_map.py +589 -0
- loopx/project_prompt.py +1153 -0
- loopx/project_skill_cli.py +125 -0
- loopx/project_skill_delivery.py +470 -0
- loopx/project_uninstall.py +462 -0
- loopx/promotion_gate.py +197 -0
- loopx/quota.py +1197 -0
- loopx/ready_score.py +413 -0
- loopx/registry.py +621 -0
- loopx/registry_writability.py +64 -0
- loopx/release_candidate.py +148 -0
- loopx/release_manifest.py +316 -0
- loopx/repository_identity.py +100 -0
- loopx/review_packet.py +1024 -0
- loopx/rollout_event_log.py +505 -0
- loopx/runtime.py +112 -0
- loopx/self_update.py +750 -0
- loopx/session_runtime.py +418 -0
- loopx/skill_install_readback.py +500 -0
- loopx/slash_command_install.py +1393 -0
- loopx/slash_commands.py +264 -0
- loopx/state_backup.py +573 -0
- loopx/state_migration.py +350 -0
- loopx/state_projection.py +809 -0
- loopx/state_refresh.py +1416 -0
- loopx/status.py +1383 -0
- loopx/status_server.py +935 -0
- loopx/summary_all.py +725 -0
- loopx/terminal_bench_agent.py +2056 -0
- loopx/thread_agent_binding.py +408 -0
- loopx/todo_followups.py +168 -0
- loopx/todo_suggestion_prompt.py +204 -0
- loopx/todos.py +2229 -0
- loopx/turn_identity.py +17 -0
- loopx/upgrade.py +1083 -0
- loopx/visible_governance.py +667 -0
- loopx/visible_multi_agent_launcher.py +1253 -0
- loopx/visible_multi_agent_tmux.py +429 -0
- loopx/worker_bridge.py +1574 -0
- loopx-0.4.8.dist-info/METADATA +708 -0
- loopx-0.4.8.dist-info/RECORD +811 -0
- loopx-0.4.8.dist-info/WHEEL +5 -0
- loopx-0.4.8.dist-info/entry_points.txt +5 -0
- loopx-0.4.8.dist-info/licenses/LICENSE +202 -0
- loopx-0.4.8.dist-info/licenses/LICENSE-MIT +21 -0
- loopx-0.4.8.dist-info/licenses/NOTICE +6 -0
- loopx-0.4.8.dist-info/top_level.txt +1 -0
loopx/codex_cli_probe.py
ADDED
|
@@ -0,0 +1,1530 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Callable
|
|
5
|
+
|
|
6
|
+
from .bootstrap import default_goal_id
|
|
7
|
+
from .codex_cli_probe_markdown import (
|
|
8
|
+
render_codex_cli_bounded_visible_pilot_adapter_markdown as render_codex_cli_bounded_visible_pilot_adapter_markdown,
|
|
9
|
+
render_codex_cli_local_driver_plan_markdown as render_codex_cli_local_driver_plan_markdown,
|
|
10
|
+
render_codex_cli_local_scheduler_executor_markdown as render_codex_cli_local_scheduler_executor_markdown,
|
|
11
|
+
render_codex_cli_local_scheduler_tick_markdown as render_codex_cli_local_scheduler_tick_markdown,
|
|
12
|
+
render_codex_cli_one_message_loop_pilot_markdown as render_codex_cli_one_message_loop_pilot_markdown,
|
|
13
|
+
render_codex_cli_runtime_idle_detector_markdown as render_codex_cli_runtime_idle_detector_markdown,
|
|
14
|
+
render_codex_cli_session_probe_markdown as render_codex_cli_session_probe_markdown,
|
|
15
|
+
render_codex_cli_visible_attach_acceptance_markdown as render_codex_cli_visible_attach_acceptance_markdown,
|
|
16
|
+
render_codex_cli_visible_driver_plan_markdown as render_codex_cli_visible_driver_plan_markdown,
|
|
17
|
+
render_codex_cli_visible_driver_run_packet_markdown as render_codex_cli_visible_driver_run_packet_markdown,
|
|
18
|
+
render_codex_cli_visible_first_response_capture_plan_markdown as render_codex_cli_visible_first_response_capture_plan_markdown,
|
|
19
|
+
render_codex_cli_visible_local_driver_pilot_markdown as render_codex_cli_visible_local_driver_pilot_markdown,
|
|
20
|
+
render_codex_cli_visible_session_proof_markdown as render_codex_cli_visible_session_proof_markdown,
|
|
21
|
+
)
|
|
22
|
+
from .codex_cli_runtime_probe import (
|
|
23
|
+
DEFAULT_CODEX_BIN as DEFAULT_CODEX_BIN,
|
|
24
|
+
DEFAULT_EXECUTOR_TIMEOUT_SECONDS as DEFAULT_EXECUTOR_TIMEOUT_SECONDS,
|
|
25
|
+
DEFAULT_MIN_HUMAN_INPUT_IDLE_SECONDS as DEFAULT_MIN_HUMAN_INPUT_IDLE_SECONDS,
|
|
26
|
+
DEFAULT_TIMEOUT_SECONDS as DEFAULT_TIMEOUT_SECONDS,
|
|
27
|
+
HELP_COMMANDS as HELP_COMMANDS,
|
|
28
|
+
FIRST_RESPONSE_REQUIRED_FALSE_CHECKS,
|
|
29
|
+
FIRST_RESPONSE_REQUIRED_TRUE_CHECKS,
|
|
30
|
+
RUNTIME_IDLE_REQUIRED_FALSE_CHECKS,
|
|
31
|
+
RUNTIME_IDLE_REQUIRED_TRUE_CHECKS,
|
|
32
|
+
_nested_bool,
|
|
33
|
+
_nested_false,
|
|
34
|
+
_shell_arg,
|
|
35
|
+
build_codex_cli_runtime_idle_detector as build_codex_cli_runtime_idle_detector,
|
|
36
|
+
build_codex_cli_runtime_idle_observation_payload as build_codex_cli_runtime_idle_observation_payload,
|
|
37
|
+
build_codex_cli_visible_session_proof as build_codex_cli_visible_session_proof,
|
|
38
|
+
classify_codex_cli_session_surface as classify_codex_cli_session_surface,
|
|
39
|
+
load_codex_cli_first_response_fixture as load_codex_cli_first_response_fixture,
|
|
40
|
+
load_codex_cli_probe_fixture as load_codex_cli_probe_fixture,
|
|
41
|
+
load_codex_cli_runtime_idle_fixture as load_codex_cli_runtime_idle_fixture,
|
|
42
|
+
load_codex_cli_visible_session_proof_fixture as load_codex_cli_visible_session_proof_fixture,
|
|
43
|
+
probe_human_input_idle_seconds as probe_human_input_idle_seconds,
|
|
44
|
+
run_codex_cli_session_probe as run_codex_cli_session_probe,
|
|
45
|
+
)
|
|
46
|
+
from .project_prompt import (
|
|
47
|
+
CODEX_CLI_VISIBLE_SCHEDULER_CONTEXT,
|
|
48
|
+
build_codex_cli_bootstrap_message,
|
|
49
|
+
render_scheduler_execution_args,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
CODEX_CLI_SCHEDULER_ARGS = render_scheduler_execution_args(
|
|
54
|
+
scheduler_execution_context=CODEX_CLI_VISIBLE_SCHEDULER_CONTEXT
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def build_codex_cli_visible_attach_acceptance(
|
|
59
|
+
*,
|
|
60
|
+
project: Path,
|
|
61
|
+
goal_id: str | None,
|
|
62
|
+
agent_id: str | None,
|
|
63
|
+
cli_bin: str,
|
|
64
|
+
codex_bin: str,
|
|
65
|
+
probe_payload: dict[str, Any],
|
|
66
|
+
proof_payload: dict[str, Any] | None = None,
|
|
67
|
+
idle_payload: dict[str, Any] | None = None,
|
|
68
|
+
) -> dict[str, Any]:
|
|
69
|
+
"""Decide whether evidence is strong enough for same-TUI visible attach.
|
|
70
|
+
|
|
71
|
+
This packet is an acceptance gate, not an executor. It deliberately keeps
|
|
72
|
+
Codex CLI `resume` / `remote-control` surfaces in a spike lane unless a
|
|
73
|
+
public-safe proof shows a visible same-TUI attach and a fresh idle detector
|
|
74
|
+
proves the later turn is not racing the user or an existing turn.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
local_plan = build_codex_cli_local_driver_plan(
|
|
78
|
+
project=project,
|
|
79
|
+
goal_id=goal_id,
|
|
80
|
+
agent_id=agent_id,
|
|
81
|
+
cli_bin=cli_bin,
|
|
82
|
+
codex_bin=codex_bin,
|
|
83
|
+
probe_payload=probe_payload,
|
|
84
|
+
)
|
|
85
|
+
visible_plan = (
|
|
86
|
+
local_plan.get("visible_driver_plan")
|
|
87
|
+
if isinstance(local_plan.get("visible_driver_plan"), dict)
|
|
88
|
+
else {}
|
|
89
|
+
)
|
|
90
|
+
proof = build_codex_cli_visible_session_proof(
|
|
91
|
+
project=project,
|
|
92
|
+
goal_id=goal_id,
|
|
93
|
+
agent_id=agent_id,
|
|
94
|
+
cli_bin=cli_bin,
|
|
95
|
+
proof_payload=proof_payload,
|
|
96
|
+
)
|
|
97
|
+
idle_detector = build_codex_cli_runtime_idle_detector(
|
|
98
|
+
project=project,
|
|
99
|
+
goal_id=goal_id,
|
|
100
|
+
agent_id=agent_id,
|
|
101
|
+
cli_bin=cli_bin,
|
|
102
|
+
idle_payload=idle_payload,
|
|
103
|
+
)
|
|
104
|
+
resolved_project = str(local_plan["project"])
|
|
105
|
+
resolved_goal_id = str(local_plan["goal_id"])
|
|
106
|
+
agent_arg = f" --agent-id {_shell_arg(agent_id)}" if agent_id else ""
|
|
107
|
+
common_args = (
|
|
108
|
+
f"--project {_shell_arg(resolved_project)} "
|
|
109
|
+
f"--goal-id {_shell_arg(resolved_goal_id)}{agent_arg} "
|
|
110
|
+
f"--codex-bin {_shell_arg(codex_bin)}"
|
|
111
|
+
)
|
|
112
|
+
proof_approved = proof.get("approved_for_same_session_automation") is True
|
|
113
|
+
idle_approved = idle_detector.get("approved_for_visible_later_turn") is True
|
|
114
|
+
observed_surface = str(proof.get("observed_surface") or "unknown")
|
|
115
|
+
driver_mode = str(local_plan.get("driver_mode") or "tui_bootstrap_only")
|
|
116
|
+
same_tui_proof = proof_approved and observed_surface == "same_tui_visible_attach"
|
|
117
|
+
accepted_same_tui = same_tui_proof and idle_approved
|
|
118
|
+
visible_later_turn_candidate = proof_approved and idle_approved
|
|
119
|
+
|
|
120
|
+
blockers: list[str] = []
|
|
121
|
+
if accepted_same_tui:
|
|
122
|
+
decision = "same_tui_visible_attach_accepted"
|
|
123
|
+
acceptance_action = "allow_opt_in_same_tui_visible_turn_after_fresh_quota_guard"
|
|
124
|
+
next_safe_step = (
|
|
125
|
+
"wire the proven same-TUI visible attach primitive behind a fresh "
|
|
126
|
+
"quota guard, runtime idle detector, and explicit command boundary"
|
|
127
|
+
)
|
|
128
|
+
elif proof_approved and idle_approved:
|
|
129
|
+
decision = "visible_surface_spike_passed_not_same_tui"
|
|
130
|
+
acceptance_action = "keep_visible_surface_as_spike_candidate_not_same_tui_attach"
|
|
131
|
+
blockers.append("same_tui_visible_attach_not_proven")
|
|
132
|
+
next_safe_step = (
|
|
133
|
+
"keep one-message TUI bootstrap primary; treat the proven visible "
|
|
134
|
+
"resume/remote-control surface as an opt-in spike until same-TUI "
|
|
135
|
+
"attachment is demonstrated"
|
|
136
|
+
)
|
|
137
|
+
elif proof_approved:
|
|
138
|
+
decision = "runtime_idle_evidence_required"
|
|
139
|
+
acceptance_action = "capture_runtime_idle_evidence_before_later_visible_turn"
|
|
140
|
+
blockers.extend(idle_detector.get("failures") or ["runtime_idle_evidence_missing"])
|
|
141
|
+
next_safe_step = (
|
|
142
|
+
"capture a public-safe runtime idle fixture or local observation "
|
|
143
|
+
"before any later visible Codex CLI prompt"
|
|
144
|
+
)
|
|
145
|
+
elif driver_mode in {"session_attached_visible_turn", "visible_resume_or_remote_control_spike"}:
|
|
146
|
+
decision = "visible_session_proof_required"
|
|
147
|
+
acceptance_action = "capture_public_safe_visible_session_proof"
|
|
148
|
+
if proof_payload is None:
|
|
149
|
+
blockers.append("visible_session_proof_missing")
|
|
150
|
+
else:
|
|
151
|
+
blockers.extend(proof.get("failures") or ["visible_session_proof_incomplete"])
|
|
152
|
+
next_safe_step = (
|
|
153
|
+
"do not call this accepted automation yet; first prove visibility, "
|
|
154
|
+
"interruptibility, boundaries, and compact writeback planning"
|
|
155
|
+
)
|
|
156
|
+
else:
|
|
157
|
+
decision = "tui_bootstrap_only"
|
|
158
|
+
acceptance_action = "ask_user_to_start_inside_codex_cli_tui"
|
|
159
|
+
blockers.append("codex_cli_attach_surface_not_exposed_by_probe")
|
|
160
|
+
next_safe_step = (
|
|
161
|
+
"ask the user to start in Codex CLI TUI and paste the bootstrap message; "
|
|
162
|
+
"headless codex exec is disabled for this product path"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
commands = (
|
|
166
|
+
local_plan.get("commands")
|
|
167
|
+
if isinstance(local_plan.get("commands"), dict)
|
|
168
|
+
else {}
|
|
169
|
+
)
|
|
170
|
+
return {
|
|
171
|
+
"ok": True,
|
|
172
|
+
"schema_version": "codex_cli_visible_attach_acceptance_v0",
|
|
173
|
+
"project": resolved_project,
|
|
174
|
+
"goal_id": resolved_goal_id,
|
|
175
|
+
"agent_id": agent_id,
|
|
176
|
+
"cli_bin": cli_bin,
|
|
177
|
+
"codex_bin": codex_bin,
|
|
178
|
+
"decision": decision,
|
|
179
|
+
"acceptance_action": acceptance_action,
|
|
180
|
+
"accepted_for_same_tui_automation": accepted_same_tui,
|
|
181
|
+
"accepted_for_visible_later_turn": visible_later_turn_candidate,
|
|
182
|
+
"observed_surface": observed_surface,
|
|
183
|
+
"driver_mode": driver_mode,
|
|
184
|
+
"next_safe_step": next_safe_step,
|
|
185
|
+
"blockers": blockers,
|
|
186
|
+
"requirements": {
|
|
187
|
+
"help_probe_required": True,
|
|
188
|
+
"public_safe_visible_session_proof_required": True,
|
|
189
|
+
"runtime_idle_detector_required": True,
|
|
190
|
+
"same_tui_surface_required_for_same_tui_acceptance": True,
|
|
191
|
+
"fresh_quota_guard_required_before_execution": True,
|
|
192
|
+
"headless_execution_disabled": True,
|
|
193
|
+
},
|
|
194
|
+
"probe": {
|
|
195
|
+
"schema_version": probe_payload.get("schema_version"),
|
|
196
|
+
"source": probe_payload.get("source"),
|
|
197
|
+
"recommended_mode": probe_payload.get("recommended_mode"),
|
|
198
|
+
"capabilities": probe_payload.get("capabilities"),
|
|
199
|
+
"warnings": probe_payload.get("warnings") or [],
|
|
200
|
+
},
|
|
201
|
+
"visible_driver_plan": {
|
|
202
|
+
"schema_version": visible_plan.get("schema_version"),
|
|
203
|
+
"driver_mode": visible_plan.get("driver_mode"),
|
|
204
|
+
"automation_action": visible_plan.get("automation_action"),
|
|
205
|
+
"next_step": visible_plan.get("next_step"),
|
|
206
|
+
},
|
|
207
|
+
"visible_session_proof": {
|
|
208
|
+
"supplied": proof_payload is not None,
|
|
209
|
+
"approved": proof_approved,
|
|
210
|
+
"decision": proof.get("decision"),
|
|
211
|
+
"observed_surface": proof.get("observed_surface"),
|
|
212
|
+
"failures": proof.get("failures") or [],
|
|
213
|
+
},
|
|
214
|
+
"runtime_idle_detector": {
|
|
215
|
+
"supplied": idle_payload is not None,
|
|
216
|
+
"approved": idle_approved,
|
|
217
|
+
"decision": idle_detector.get("decision"),
|
|
218
|
+
"failures": idle_detector.get("failures") or [],
|
|
219
|
+
"source": idle_detector.get("source"),
|
|
220
|
+
},
|
|
221
|
+
"commands": {
|
|
222
|
+
"session_probe": f"{_shell_arg(cli_bin)} codex-cli-session-probe --codex-bin {_shell_arg(codex_bin)}",
|
|
223
|
+
"local_driver_plan": commands.get("local_driver_plan"),
|
|
224
|
+
"visible_driver_plan": commands.get("visible_driver_plan"),
|
|
225
|
+
"visible_attach_acceptance": (
|
|
226
|
+
f"{_shell_arg(cli_bin)} codex-cli-visible-attach-acceptance {common_args} "
|
|
227
|
+
"--proof-fixture <public-visible-proof.json> --idle-fixture <public-runtime-idle.json>"
|
|
228
|
+
),
|
|
229
|
+
"visible_session_proof": (
|
|
230
|
+
f"{_shell_arg(cli_bin)} codex-cli-visible-session-proof "
|
|
231
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
232
|
+
f"{agent_arg} --proof-fixture <public-visible-proof.json>"
|
|
233
|
+
),
|
|
234
|
+
"runtime_idle_detector_fixture": (
|
|
235
|
+
f"{_shell_arg(cli_bin)} codex-cli-runtime-idle-detector "
|
|
236
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
237
|
+
f"{agent_arg} --idle-fixture <public-runtime-idle.json>"
|
|
238
|
+
),
|
|
239
|
+
"tui_bootstrap_message": commands.get("tui_bootstrap_message"),
|
|
240
|
+
"explicit_headless_fallback": None,
|
|
241
|
+
"headless_fallback_disabled": commands.get("headless_fallback_disabled"),
|
|
242
|
+
},
|
|
243
|
+
"boundary": {
|
|
244
|
+
"acceptance_packet_only": True,
|
|
245
|
+
"runs_codex": False,
|
|
246
|
+
"reads_raw_transcripts": False,
|
|
247
|
+
"reads_credentials": False,
|
|
248
|
+
"reads_session_files": False,
|
|
249
|
+
"reads_stdout_stderr": False,
|
|
250
|
+
"mutates_codex_session": False,
|
|
251
|
+
"spends_loopx_quota": False,
|
|
252
|
+
"writes_loopx_state": False,
|
|
253
|
+
"requires_fresh_quota_guard_before_execution": True,
|
|
254
|
+
"headless_execution_disabled": True,
|
|
255
|
+
},
|
|
256
|
+
"warnings": list(probe_payload.get("warnings") or []),
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def build_codex_cli_visible_driver_plan(
|
|
261
|
+
*,
|
|
262
|
+
project: Path,
|
|
263
|
+
goal_id: str | None,
|
|
264
|
+
agent_id: str | None,
|
|
265
|
+
cli_bin: str,
|
|
266
|
+
codex_bin: str,
|
|
267
|
+
probe_payload: dict[str, Any],
|
|
268
|
+
) -> dict[str, Any]:
|
|
269
|
+
"""Build a public-safe plan for a visible Codex CLI automation driver.
|
|
270
|
+
|
|
271
|
+
The plan is intentionally read-only. It decides whether a future local
|
|
272
|
+
driver should attempt a visible session attachment, run a resume/remote
|
|
273
|
+
control spike, or keep the one-message TUI bootstrap as the product path.
|
|
274
|
+
"""
|
|
275
|
+
|
|
276
|
+
resolved_project = str(project.expanduser())
|
|
277
|
+
resolved_goal_id = goal_id or default_goal_id(project)
|
|
278
|
+
capabilities = probe_payload.get("capabilities") if isinstance(probe_payload.get("capabilities"), dict) else {}
|
|
279
|
+
safe_injection_supported = bool(capabilities.get("safe_injection_supported"))
|
|
280
|
+
visible_resume_supported = bool(capabilities.get("visible_resume_supported"))
|
|
281
|
+
remote_control_supported = bool(capabilities.get("remote_control_surface_detected"))
|
|
282
|
+
agent_arg = f" --agent-id {_shell_arg(agent_id)}" if agent_id else ""
|
|
283
|
+
quota_guard_command = (
|
|
284
|
+
f"{_shell_arg(cli_bin)} --format json quota should-run "
|
|
285
|
+
f"--goal-id {_shell_arg(resolved_goal_id)}{agent_arg}"
|
|
286
|
+
f"{CODEX_CLI_SCHEDULER_ARGS}"
|
|
287
|
+
)
|
|
288
|
+
bootstrap_command = (
|
|
289
|
+
f"{_shell_arg(cli_bin)} codex-cli-bootstrap-message "
|
|
290
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}{agent_arg}"
|
|
291
|
+
)
|
|
292
|
+
probe_command = f"{_shell_arg(cli_bin)} codex-cli-session-probe --codex-bin {_shell_arg(codex_bin)}"
|
|
293
|
+
|
|
294
|
+
if safe_injection_supported:
|
|
295
|
+
driver_mode = "session_attached_visible_turn"
|
|
296
|
+
automation_action = "try_visible_session_attach_with_idle_guard"
|
|
297
|
+
next_step = "wire the detected visible attach primitive behind idle guard and quota guard"
|
|
298
|
+
elif visible_resume_supported or remote_control_supported:
|
|
299
|
+
driver_mode = "visible_resume_or_remote_control_spike"
|
|
300
|
+
automation_action = "prototype_visible_resume_or_remote_control_with_idle_guard"
|
|
301
|
+
next_step = "run an explicit proof that resume or remote-control creates a visible interruptible turn"
|
|
302
|
+
else:
|
|
303
|
+
driver_mode = "tui_bootstrap_only"
|
|
304
|
+
automation_action = "ask_user_to_start_inside_codex_cli_tui"
|
|
305
|
+
next_step = "ask the user to start in Codex CLI TUI and paste the bootstrap message; headless fallback is disabled"
|
|
306
|
+
|
|
307
|
+
driver_steps = [
|
|
308
|
+
"run the session probe and quota guard before any delivery turn",
|
|
309
|
+
"if user_channel.action_required=true, surface only the concrete user gate",
|
|
310
|
+
"if delivery is allowed, verify idle_guard before any visible prompt",
|
|
311
|
+
"prefer a visible same-TUI turn; otherwise keep the one-message TUI bootstrap as the product path",
|
|
312
|
+
"write back compact evidence and spend quota only after validation",
|
|
313
|
+
]
|
|
314
|
+
if driver_mode == "visible_resume_or_remote_control_spike":
|
|
315
|
+
driver_steps.insert(
|
|
316
|
+
3,
|
|
317
|
+
"treat resume [PROMPT] or remote-control as unproven until a visible interruptible turn is observed",
|
|
318
|
+
)
|
|
319
|
+
if driver_mode == "session_attached_visible_turn":
|
|
320
|
+
driver_steps.insert(3, "use only the detected visible attach primitive; do not write hidden session state")
|
|
321
|
+
|
|
322
|
+
return {
|
|
323
|
+
"ok": True,
|
|
324
|
+
"schema_version": "codex_cli_visible_driver_plan_v0",
|
|
325
|
+
"project": resolved_project,
|
|
326
|
+
"goal_id": resolved_goal_id,
|
|
327
|
+
"agent_id": agent_id,
|
|
328
|
+
"cli_bin": cli_bin,
|
|
329
|
+
"codex_bin": codex_bin,
|
|
330
|
+
"probe_source": probe_payload.get("source"),
|
|
331
|
+
"probe_recommended_mode": probe_payload.get("recommended_mode"),
|
|
332
|
+
"driver_mode": driver_mode,
|
|
333
|
+
"automation_action": automation_action,
|
|
334
|
+
"next_step": next_step,
|
|
335
|
+
"capabilities": capabilities,
|
|
336
|
+
"commands": {
|
|
337
|
+
"probe": probe_command,
|
|
338
|
+
"quota_guard": quota_guard_command,
|
|
339
|
+
"tui_bootstrap_message": bootstrap_command,
|
|
340
|
+
"explicit_headless_fallback": None,
|
|
341
|
+
"headless_fallback_disabled": "headless codex exec is disabled for the default LoopX setup-then-goal bootstrap path",
|
|
342
|
+
},
|
|
343
|
+
"driver_steps": driver_steps,
|
|
344
|
+
"boundary": {
|
|
345
|
+
"dry_run_plan_only": True,
|
|
346
|
+
"runs_codex": False,
|
|
347
|
+
"reads_raw_transcripts": False,
|
|
348
|
+
"reads_credentials": False,
|
|
349
|
+
"reads_session_files": False,
|
|
350
|
+
"mutates_codex_session": False,
|
|
351
|
+
"spends_loopx_quota": False,
|
|
352
|
+
"requires_idle_guard_before_visible_prompt": True,
|
|
353
|
+
"requires_user_gate_stop": True,
|
|
354
|
+
"headless_execution_disabled": True,
|
|
355
|
+
},
|
|
356
|
+
"warnings": list(probe_payload.get("warnings") or []),
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def build_codex_cli_local_driver_plan(
|
|
361
|
+
*,
|
|
362
|
+
project: Path,
|
|
363
|
+
goal_id: str | None,
|
|
364
|
+
agent_id: str | None,
|
|
365
|
+
cli_bin: str,
|
|
366
|
+
codex_bin: str,
|
|
367
|
+
probe_payload: dict[str, Any],
|
|
368
|
+
) -> dict[str, Any]:
|
|
369
|
+
"""Build a dry-run-first local driver plan for Codex CLI.
|
|
370
|
+
|
|
371
|
+
This does not launch Codex or mutate any session. It composes the existing
|
|
372
|
+
one-message TUI bootstrap, visible-driver plan, quota guard, and the
|
|
373
|
+
headless-disabled boundary into one operator-facing decision packet.
|
|
374
|
+
"""
|
|
375
|
+
|
|
376
|
+
visible_plan = build_codex_cli_visible_driver_plan(
|
|
377
|
+
project=project,
|
|
378
|
+
goal_id=goal_id,
|
|
379
|
+
agent_id=agent_id,
|
|
380
|
+
cli_bin=cli_bin,
|
|
381
|
+
codex_bin=codex_bin,
|
|
382
|
+
probe_payload=probe_payload,
|
|
383
|
+
)
|
|
384
|
+
resolved_project = visible_plan["project"]
|
|
385
|
+
resolved_goal_id = visible_plan["goal_id"]
|
|
386
|
+
agent_arg = f" --agent-id {_shell_arg(agent_id)}" if agent_id else ""
|
|
387
|
+
visible_driver_plan_command = (
|
|
388
|
+
f"{_shell_arg(cli_bin)} codex-cli-visible-driver-plan "
|
|
389
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}{agent_arg} "
|
|
390
|
+
f"--codex-bin {_shell_arg(codex_bin)}"
|
|
391
|
+
)
|
|
392
|
+
quota_guard_command = (
|
|
393
|
+
f"{_shell_arg(cli_bin)} --format json "
|
|
394
|
+
"--registry \"$HOME/.codex/loopx/registry.global.json\" "
|
|
395
|
+
f"quota should-run --goal-id {_shell_arg(resolved_goal_id)}{agent_arg}"
|
|
396
|
+
f"{CODEX_CLI_SCHEDULER_ARGS}"
|
|
397
|
+
)
|
|
398
|
+
bootstrap_command = (
|
|
399
|
+
f"{_shell_arg(cli_bin)} codex-cli-bootstrap-message "
|
|
400
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}{agent_arg}"
|
|
401
|
+
)
|
|
402
|
+
driver_mode = str(visible_plan.get("driver_mode") or "tui_bootstrap_only")
|
|
403
|
+
|
|
404
|
+
if driver_mode == "session_attached_visible_turn":
|
|
405
|
+
decision = "attempt_visible_session_attach_after_idle_guard"
|
|
406
|
+
operator_instruction = (
|
|
407
|
+
"Run quota guard, verify idle guard, then attempt only the detected visible attach primitive."
|
|
408
|
+
)
|
|
409
|
+
elif driver_mode == "visible_resume_or_remote_control_spike":
|
|
410
|
+
decision = "run_visible_resume_or_remote_control_proof"
|
|
411
|
+
operator_instruction = (
|
|
412
|
+
"Treat resume or remote-control as a proof target, not production session attachment, until the turn is visible and interruptible."
|
|
413
|
+
)
|
|
414
|
+
else:
|
|
415
|
+
decision = "ask_user_to_start_from_tui"
|
|
416
|
+
operator_instruction = (
|
|
417
|
+
"Ask the user to start inside Codex CLI TUI and paste the bootstrap message; "
|
|
418
|
+
"headless codex exec is disabled for this product path."
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
"ok": True,
|
|
423
|
+
"schema_version": "codex_cli_local_driver_plan_v0",
|
|
424
|
+
"project": resolved_project,
|
|
425
|
+
"goal_id": resolved_goal_id,
|
|
426
|
+
"agent_id": agent_id,
|
|
427
|
+
"cli_bin": cli_bin,
|
|
428
|
+
"codex_bin": codex_bin,
|
|
429
|
+
"driver_phase": "dry_run_plan",
|
|
430
|
+
"driver_mode": driver_mode,
|
|
431
|
+
"decision": decision,
|
|
432
|
+
"operator_instruction": operator_instruction,
|
|
433
|
+
"visible_driver_plan": {
|
|
434
|
+
"schema_version": visible_plan.get("schema_version"),
|
|
435
|
+
"driver_mode": visible_plan.get("driver_mode"),
|
|
436
|
+
"automation_action": visible_plan.get("automation_action"),
|
|
437
|
+
"next_step": visible_plan.get("next_step"),
|
|
438
|
+
},
|
|
439
|
+
"commands": {
|
|
440
|
+
"quota_guard": quota_guard_command,
|
|
441
|
+
"local_driver_plan": (
|
|
442
|
+
f"{_shell_arg(cli_bin)} codex-cli-local-driver-plan "
|
|
443
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}{agent_arg} "
|
|
444
|
+
f"--codex-bin {_shell_arg(codex_bin)}"
|
|
445
|
+
),
|
|
446
|
+
"visible_driver_plan": visible_driver_plan_command,
|
|
447
|
+
"tui_bootstrap_message": bootstrap_command,
|
|
448
|
+
"explicit_headless_fallback": None,
|
|
449
|
+
"headless_fallback_disabled": "headless codex exec is disabled for the default LoopX setup-then-goal bootstrap path",
|
|
450
|
+
},
|
|
451
|
+
"driver_steps": [
|
|
452
|
+
"run quota_guard and stop when user_channel.action_required=true",
|
|
453
|
+
"run visible_driver_plan to classify TUI, resume, or remote-control mode",
|
|
454
|
+
"verify idle_guard before any visible resume or remote-control prompt",
|
|
455
|
+
"prefer one-message TUI bootstrap until visible attach is proven",
|
|
456
|
+
"do not offer headless codex exec from the default LoopX setup-then-goal bootstrap path",
|
|
457
|
+
"write back compact evidence or a precise blocker before quota spend",
|
|
458
|
+
],
|
|
459
|
+
"idle_guard": {
|
|
460
|
+
"required": True,
|
|
461
|
+
"implemented": False,
|
|
462
|
+
"placeholder": "future driver must prove no active human typing and no running turn before visible resume or remote-control prompt",
|
|
463
|
+
},
|
|
464
|
+
"execution_policy": {
|
|
465
|
+
"tui_bootstrap_primary": True,
|
|
466
|
+
"headless_execution_disabled": True,
|
|
467
|
+
"same_session_attachment_requires_visible_proof": True,
|
|
468
|
+
"quota_guard_required": True,
|
|
469
|
+
"spend_after_validated_writeback_only": True,
|
|
470
|
+
},
|
|
471
|
+
"boundary": {
|
|
472
|
+
"dry_run_plan_only": True,
|
|
473
|
+
"runs_codex": False,
|
|
474
|
+
"reads_raw_transcripts": False,
|
|
475
|
+
"reads_credentials": False,
|
|
476
|
+
"reads_session_files": False,
|
|
477
|
+
"mutates_codex_session": False,
|
|
478
|
+
"spends_loopx_quota": False,
|
|
479
|
+
"requires_idle_guard_before_visible_prompt": True,
|
|
480
|
+
"requires_user_gate_stop": True,
|
|
481
|
+
"headless_execution_disabled": True,
|
|
482
|
+
},
|
|
483
|
+
"warnings": list(visible_plan.get("warnings") or []),
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def build_codex_cli_visible_driver_run_packet(
|
|
488
|
+
*,
|
|
489
|
+
project: Path,
|
|
490
|
+
goal_id: str | None,
|
|
491
|
+
agent_id: str | None,
|
|
492
|
+
cli_bin: str,
|
|
493
|
+
codex_bin: str,
|
|
494
|
+
probe_payload: dict[str, Any],
|
|
495
|
+
proof_payload: dict[str, Any] | None = None,
|
|
496
|
+
allow_headless_fallback: bool = False,
|
|
497
|
+
) -> dict[str, Any]:
|
|
498
|
+
"""Build the v0 runner packet for one visible Codex CLI driver turn.
|
|
499
|
+
|
|
500
|
+
The packet is deliberately not an executor. It converts the dry-run local
|
|
501
|
+
driver plan and optional visible-session proof into the next safe command
|
|
502
|
+
boundary for a local scheduler or human operator. Headless fallback remains
|
|
503
|
+
disabled for this default LoopX setup-then-goal bootstrap path.
|
|
504
|
+
"""
|
|
505
|
+
|
|
506
|
+
local_plan = build_codex_cli_local_driver_plan(
|
|
507
|
+
project=project,
|
|
508
|
+
goal_id=goal_id,
|
|
509
|
+
agent_id=agent_id,
|
|
510
|
+
cli_bin=cli_bin,
|
|
511
|
+
codex_bin=codex_bin,
|
|
512
|
+
probe_payload=probe_payload,
|
|
513
|
+
)
|
|
514
|
+
resolved_project = str(local_plan["project"])
|
|
515
|
+
resolved_goal_id = str(local_plan["goal_id"])
|
|
516
|
+
driver_mode = str(local_plan.get("driver_mode") or "tui_bootstrap_only")
|
|
517
|
+
commands = local_plan.get("commands") if isinstance(local_plan.get("commands"), dict) else {}
|
|
518
|
+
proof = build_codex_cli_visible_session_proof(
|
|
519
|
+
project=project,
|
|
520
|
+
goal_id=goal_id,
|
|
521
|
+
agent_id=agent_id,
|
|
522
|
+
cli_bin=cli_bin,
|
|
523
|
+
proof_payload=proof_payload,
|
|
524
|
+
) if proof_payload is not None else None
|
|
525
|
+
proof_approved = bool(proof and proof.get("approved_for_same_session_automation") is True)
|
|
526
|
+
proof_command = (
|
|
527
|
+
f"{_shell_arg(cli_bin)} codex-cli-visible-session-proof "
|
|
528
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
529
|
+
f"{' --agent-id ' + _shell_arg(agent_id) if agent_id else ''} "
|
|
530
|
+
"--proof-fixture <public-visible-proof.json>"
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
if proof_approved:
|
|
534
|
+
decision = "visible_session_turn_candidate"
|
|
535
|
+
next_driver_action = "run_visible_session_turn_after_quota_and_idle_guard"
|
|
536
|
+
recommended_command = proof_payload.get("recommended_command") if isinstance(proof_payload, dict) else None
|
|
537
|
+
if not recommended_command:
|
|
538
|
+
recommended_command = "use the proven visible Codex CLI surface; do not read transcripts or hidden session files"
|
|
539
|
+
elif driver_mode in {"session_attached_visible_turn", "visible_resume_or_remote_control_spike"}:
|
|
540
|
+
decision = "visible_session_proof_required"
|
|
541
|
+
next_driver_action = "capture_public_safe_visible_session_proof"
|
|
542
|
+
recommended_command = proof_command
|
|
543
|
+
else:
|
|
544
|
+
decision = "tui_bootstrap_only"
|
|
545
|
+
next_driver_action = "ask_user_to_start_inside_codex_cli_tui"
|
|
546
|
+
recommended_command = commands.get("tui_bootstrap_message")
|
|
547
|
+
|
|
548
|
+
driver_steps = [
|
|
549
|
+
"run quota_guard and stop if user_channel.action_required=true",
|
|
550
|
+
"stop or relocate if workspace_guard blocks the current checkout",
|
|
551
|
+
"use a visible session only when proof_approved=true and an idle guard passes",
|
|
552
|
+
"do not use headless codex exec from the default LoopX setup-then-goal bootstrap path",
|
|
553
|
+
"after the Codex turn, validate evidence or blocker before refresh-state",
|
|
554
|
+
"spend quota exactly once after validated writeback, never for this packet alone",
|
|
555
|
+
]
|
|
556
|
+
warnings = list(local_plan.get("warnings") or [])
|
|
557
|
+
if allow_headless_fallback:
|
|
558
|
+
warnings.append(
|
|
559
|
+
"allow_headless_fallback was ignored because headless fallback is disabled for the default LoopX setup-then-goal bootstrap path."
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
return {
|
|
563
|
+
"ok": True,
|
|
564
|
+
"schema_version": "codex_cli_visible_driver_run_packet_v0",
|
|
565
|
+
"project": resolved_project,
|
|
566
|
+
"goal_id": resolved_goal_id,
|
|
567
|
+
"agent_id": agent_id,
|
|
568
|
+
"cli_bin": cli_bin,
|
|
569
|
+
"codex_bin": codex_bin,
|
|
570
|
+
"driver_phase": "run_packet_no_execution",
|
|
571
|
+
"driver_mode": driver_mode,
|
|
572
|
+
"decision": decision,
|
|
573
|
+
"next_driver_action": next_driver_action,
|
|
574
|
+
"recommended_command": recommended_command,
|
|
575
|
+
"allow_headless_fallback": allow_headless_fallback,
|
|
576
|
+
"visible_session_proof": {
|
|
577
|
+
"supplied": proof is not None,
|
|
578
|
+
"approved": proof_approved,
|
|
579
|
+
"decision": proof.get("decision") if proof else None,
|
|
580
|
+
"failures": proof.get("failures") if proof else [],
|
|
581
|
+
},
|
|
582
|
+
"local_driver_plan": {
|
|
583
|
+
"schema_version": local_plan.get("schema_version"),
|
|
584
|
+
"driver_mode": local_plan.get("driver_mode"),
|
|
585
|
+
"decision": local_plan.get("decision"),
|
|
586
|
+
"operator_instruction": local_plan.get("operator_instruction"),
|
|
587
|
+
},
|
|
588
|
+
"commands": {
|
|
589
|
+
"quota_guard": commands.get("quota_guard"),
|
|
590
|
+
"tui_bootstrap_message": commands.get("tui_bootstrap_message"),
|
|
591
|
+
"visible_session_proof": proof_command,
|
|
592
|
+
"explicit_headless_fallback": None,
|
|
593
|
+
"headless_fallback_disabled": commands.get("headless_fallback_disabled"),
|
|
594
|
+
},
|
|
595
|
+
"driver_steps": driver_steps,
|
|
596
|
+
"execution_policy": {
|
|
597
|
+
"tui_bootstrap_primary": True,
|
|
598
|
+
"same_session_attachment_requires_visible_proof": True,
|
|
599
|
+
"headless_execution_disabled": True,
|
|
600
|
+
"quota_guard_required": True,
|
|
601
|
+
"idle_guard_required_before_visible_prompt": True,
|
|
602
|
+
"spend_after_validated_writeback_only": True,
|
|
603
|
+
},
|
|
604
|
+
"boundary": {
|
|
605
|
+
"run_packet_only": True,
|
|
606
|
+
"runs_codex": False,
|
|
607
|
+
"reads_raw_transcripts": False,
|
|
608
|
+
"reads_credentials": False,
|
|
609
|
+
"reads_session_files": False,
|
|
610
|
+
"mutates_codex_session": False,
|
|
611
|
+
"spends_loopx_quota": False,
|
|
612
|
+
"requires_user_gate_stop": True,
|
|
613
|
+
"headless_execution_disabled": True,
|
|
614
|
+
},
|
|
615
|
+
"warnings": warnings,
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
SchedulerCommandRunner = Callable[..., dict[str, Any]]
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
def build_codex_cli_local_scheduler_tick(
|
|
623
|
+
*,
|
|
624
|
+
project: Path,
|
|
625
|
+
goal_id: str | None,
|
|
626
|
+
agent_id: str | None,
|
|
627
|
+
cli_bin: str,
|
|
628
|
+
codex_bin: str,
|
|
629
|
+
probe_payload: dict[str, Any],
|
|
630
|
+
quota_payload: dict[str, Any] | None = None,
|
|
631
|
+
proof_payload: dict[str, Any] | None = None,
|
|
632
|
+
idle_payload: dict[str, Any] | None = None,
|
|
633
|
+
allow_headless_fallback: bool = False,
|
|
634
|
+
) -> dict[str, Any]:
|
|
635
|
+
from .codex_cli_scheduler import build_codex_cli_local_scheduler_tick as _build
|
|
636
|
+
|
|
637
|
+
return _build(
|
|
638
|
+
project=project,
|
|
639
|
+
goal_id=goal_id,
|
|
640
|
+
agent_id=agent_id,
|
|
641
|
+
cli_bin=cli_bin,
|
|
642
|
+
codex_bin=codex_bin,
|
|
643
|
+
probe_payload=probe_payload,
|
|
644
|
+
quota_payload=quota_payload,
|
|
645
|
+
proof_payload=proof_payload,
|
|
646
|
+
idle_payload=idle_payload,
|
|
647
|
+
allow_headless_fallback=allow_headless_fallback,
|
|
648
|
+
)
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
def execute_codex_cli_local_scheduler_tick_result(
|
|
652
|
+
tick_payload: dict[str, Any],
|
|
653
|
+
*,
|
|
654
|
+
execute_candidate: bool = False,
|
|
655
|
+
execute_blocker_writeback: bool = False,
|
|
656
|
+
guard_checked: bool = False,
|
|
657
|
+
candidate_command_prefixes: list[str] | None = None,
|
|
658
|
+
executor_timeout_seconds: float = DEFAULT_EXECUTOR_TIMEOUT_SECONDS,
|
|
659
|
+
runner: SchedulerCommandRunner | None = None,
|
|
660
|
+
) -> dict[str, Any]:
|
|
661
|
+
from .codex_cli_scheduler import execute_codex_cli_local_scheduler_tick_result as _execute
|
|
662
|
+
|
|
663
|
+
return _execute(
|
|
664
|
+
tick_payload,
|
|
665
|
+
execute_candidate=execute_candidate,
|
|
666
|
+
execute_blocker_writeback=execute_blocker_writeback,
|
|
667
|
+
guard_checked=guard_checked,
|
|
668
|
+
candidate_command_prefixes=candidate_command_prefixes,
|
|
669
|
+
executor_timeout_seconds=executor_timeout_seconds,
|
|
670
|
+
runner=runner,
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
def build_codex_cli_local_scheduler_executor(
|
|
675
|
+
*,
|
|
676
|
+
project: Path,
|
|
677
|
+
goal_id: str | None,
|
|
678
|
+
agent_id: str | None,
|
|
679
|
+
cli_bin: str,
|
|
680
|
+
codex_bin: str,
|
|
681
|
+
probe_payload: dict[str, Any],
|
|
682
|
+
quota_payload: dict[str, Any] | None = None,
|
|
683
|
+
proof_payload: dict[str, Any] | None = None,
|
|
684
|
+
idle_payload: dict[str, Any] | None = None,
|
|
685
|
+
allow_headless_fallback: bool = False,
|
|
686
|
+
execute_candidate: bool = False,
|
|
687
|
+
execute_blocker_writeback: bool = False,
|
|
688
|
+
guard_checked: bool = False,
|
|
689
|
+
candidate_command_prefixes: list[str] | None = None,
|
|
690
|
+
executor_timeout_seconds: float = DEFAULT_EXECUTOR_TIMEOUT_SECONDS,
|
|
691
|
+
runner: SchedulerCommandRunner | None = None,
|
|
692
|
+
) -> dict[str, Any]:
|
|
693
|
+
from .codex_cli_scheduler import build_codex_cli_local_scheduler_executor as _build
|
|
694
|
+
|
|
695
|
+
return _build(
|
|
696
|
+
project=project,
|
|
697
|
+
goal_id=goal_id,
|
|
698
|
+
agent_id=agent_id,
|
|
699
|
+
cli_bin=cli_bin,
|
|
700
|
+
codex_bin=codex_bin,
|
|
701
|
+
probe_payload=probe_payload,
|
|
702
|
+
quota_payload=quota_payload,
|
|
703
|
+
proof_payload=proof_payload,
|
|
704
|
+
idle_payload=idle_payload,
|
|
705
|
+
allow_headless_fallback=allow_headless_fallback,
|
|
706
|
+
execute_candidate=execute_candidate,
|
|
707
|
+
execute_blocker_writeback=execute_blocker_writeback,
|
|
708
|
+
guard_checked=guard_checked,
|
|
709
|
+
candidate_command_prefixes=candidate_command_prefixes,
|
|
710
|
+
executor_timeout_seconds=executor_timeout_seconds,
|
|
711
|
+
runner=runner,
|
|
712
|
+
)
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
def build_codex_cli_one_message_loop_pilot(
|
|
716
|
+
*,
|
|
717
|
+
project: Path,
|
|
718
|
+
goal_id: str | None,
|
|
719
|
+
agent_id: str | None,
|
|
720
|
+
cli_bin: str,
|
|
721
|
+
codex_bin: str,
|
|
722
|
+
probe_payload: dict[str, Any],
|
|
723
|
+
proof_payload: dict[str, Any] | None = None,
|
|
724
|
+
idle_payload: dict[str, Any] | None = None,
|
|
725
|
+
allow_headless_fallback: bool = False,
|
|
726
|
+
) -> dict[str, Any]:
|
|
727
|
+
"""Compose the first-message TUI path with the safe scheduler bridge."""
|
|
728
|
+
|
|
729
|
+
bootstrap = build_codex_cli_bootstrap_message(
|
|
730
|
+
project=project,
|
|
731
|
+
goal_id=goal_id,
|
|
732
|
+
agent_id=agent_id,
|
|
733
|
+
cli_bin=cli_bin,
|
|
734
|
+
)
|
|
735
|
+
resolved_project = str(bootstrap["project"])
|
|
736
|
+
resolved_goal_id = str(bootstrap["goal_id"])
|
|
737
|
+
agent_arg = f" --agent-id {_shell_arg(agent_id)}" if agent_id else ""
|
|
738
|
+
common_args = (
|
|
739
|
+
f"--project {_shell_arg(resolved_project)} "
|
|
740
|
+
f"--goal-id {_shell_arg(resolved_goal_id)}{agent_arg} "
|
|
741
|
+
f"--codex-bin {_shell_arg(codex_bin)}"
|
|
742
|
+
)
|
|
743
|
+
scheduler_executor = build_codex_cli_local_scheduler_executor(
|
|
744
|
+
project=project,
|
|
745
|
+
goal_id=resolved_goal_id,
|
|
746
|
+
agent_id=agent_id,
|
|
747
|
+
cli_bin=cli_bin,
|
|
748
|
+
codex_bin=codex_bin,
|
|
749
|
+
probe_payload=probe_payload,
|
|
750
|
+
proof_payload=proof_payload,
|
|
751
|
+
idle_payload=idle_payload,
|
|
752
|
+
allow_headless_fallback=allow_headless_fallback,
|
|
753
|
+
execute_candidate=False,
|
|
754
|
+
execute_blocker_writeback=False,
|
|
755
|
+
)
|
|
756
|
+
scheduler_action = str(scheduler_executor.get("scheduler_action") or "")
|
|
757
|
+
scheduler_tick = (
|
|
758
|
+
scheduler_executor.get("scheduler_tick")
|
|
759
|
+
if isinstance(scheduler_executor.get("scheduler_tick"), dict)
|
|
760
|
+
else {}
|
|
761
|
+
)
|
|
762
|
+
scheduler_blocker = (
|
|
763
|
+
scheduler_tick.get("precise_blocker")
|
|
764
|
+
if isinstance(scheduler_tick.get("precise_blocker"), dict)
|
|
765
|
+
else {}
|
|
766
|
+
)
|
|
767
|
+
scheduler_blocker_reason = str(scheduler_blocker.get("reason") or "")
|
|
768
|
+
if scheduler_action == "external_visible_command_candidate":
|
|
769
|
+
pilot_decision = "first_message_then_candidate_available"
|
|
770
|
+
followup_mode = "local scheduler can show the candidate, but execution still requires guard and prefix opt-in"
|
|
771
|
+
elif scheduler_action == "write_precise_blocker" and scheduler_blocker_reason.startswith("runtime_idle_"):
|
|
772
|
+
pilot_decision = "first_message_then_runtime_idle_required"
|
|
773
|
+
followup_mode = (
|
|
774
|
+
"local scheduler must capture public-safe runtime idle observation before later visible automation"
|
|
775
|
+
)
|
|
776
|
+
elif scheduler_action == "write_precise_blocker":
|
|
777
|
+
pilot_decision = "first_message_then_visible_blocker_writeback"
|
|
778
|
+
followup_mode = "local scheduler can write the precise blocker after explicit guard-checked opt-in"
|
|
779
|
+
else:
|
|
780
|
+
pilot_decision = "first_message_tui_bootstrap_only"
|
|
781
|
+
followup_mode = "keep the TUI bootstrap as the product path until a visible proof exists"
|
|
782
|
+
|
|
783
|
+
bootstrap_command = (
|
|
784
|
+
f"{_shell_arg(cli_bin)} codex-cli-bootstrap-message "
|
|
785
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}{agent_arg}"
|
|
786
|
+
)
|
|
787
|
+
scheduler_exec_dry_run_command = (
|
|
788
|
+
f"{_shell_arg(cli_bin)} codex-cli-local-scheduler-exec {common_args}"
|
|
789
|
+
" --observe-local-runtime --observed-surface visible_resume_prompt "
|
|
790
|
+
"--turn-state idle --probe-human-input-idle --checked-before-prompt "
|
|
791
|
+
"--visible-to-user --user-can-interrupt --manual-takeover-available"
|
|
792
|
+
)
|
|
793
|
+
candidate_execute_template = (
|
|
794
|
+
f"{scheduler_exec_dry_run_command} --guard-checked --execute-candidate "
|
|
795
|
+
"--candidate-command-prefix <allowed-prefix>"
|
|
796
|
+
)
|
|
797
|
+
blocker_execute_template = (
|
|
798
|
+
f"{scheduler_exec_dry_run_command} --guard-checked --execute-blocker-writeback"
|
|
799
|
+
)
|
|
800
|
+
return {
|
|
801
|
+
"ok": True,
|
|
802
|
+
"schema_version": "codex_cli_one_message_loop_pilot_v0",
|
|
803
|
+
"project": resolved_project,
|
|
804
|
+
"goal_id": resolved_goal_id,
|
|
805
|
+
"agent_id": agent_id,
|
|
806
|
+
"cli_bin": cli_bin,
|
|
807
|
+
"codex_bin": codex_bin,
|
|
808
|
+
"pilot_decision": pilot_decision,
|
|
809
|
+
"followup_mode": followup_mode,
|
|
810
|
+
"start_surface": "codex_cli_tui_one_message",
|
|
811
|
+
"first_turn": {
|
|
812
|
+
"user_action": "paste_bootstrap_message_into_codex_cli_tui",
|
|
813
|
+
"autostarts_loopx_loop": True,
|
|
814
|
+
"setup_then_loop_activation": True,
|
|
815
|
+
"preserve_tui": True,
|
|
816
|
+
"loop_activation": {
|
|
817
|
+
"source_command": bootstrap.get("heartbeat_prompt_json_command"),
|
|
818
|
+
"codex_cli": "/goal <thin task_body>",
|
|
819
|
+
"codex_app": "<thin task_body> heartbeat automation",
|
|
820
|
+
},
|
|
821
|
+
"stop_only_for": [
|
|
822
|
+
"concrete_user_gate",
|
|
823
|
+
"workspace_guard",
|
|
824
|
+
"missing_capability",
|
|
825
|
+
"missing_installation_primitive",
|
|
826
|
+
"unsafe_boundary",
|
|
827
|
+
],
|
|
828
|
+
"message": bootstrap.get("message"),
|
|
829
|
+
"snapshot_required": [
|
|
830
|
+
"current goal id",
|
|
831
|
+
"concrete user gate or none",
|
|
832
|
+
"top user todo or none",
|
|
833
|
+
"top agent todo",
|
|
834
|
+
"next safe action",
|
|
835
|
+
],
|
|
836
|
+
},
|
|
837
|
+
"later_turn_contract": {
|
|
838
|
+
"preserve_visible_tui": True,
|
|
839
|
+
"visible_steering_requires": [
|
|
840
|
+
"public_safe_visible_session_proof",
|
|
841
|
+
"runtime_idle_evidence",
|
|
842
|
+
"fresh_quota_guard",
|
|
843
|
+
"guard_checked",
|
|
844
|
+
"explicit_execution_bounds",
|
|
845
|
+
],
|
|
846
|
+
"default_without_proof": "write_blocker_or_keep_tui_bootstrap_primary",
|
|
847
|
+
},
|
|
848
|
+
"automation_bridge": {
|
|
849
|
+
"command": "codex-cli-local-scheduler-exec",
|
|
850
|
+
"default_executes": False,
|
|
851
|
+
"scheduler_action": scheduler_action,
|
|
852
|
+
"executor_reason": (scheduler_executor.get("execution") or {}).get("reason")
|
|
853
|
+
if isinstance(scheduler_executor.get("execution"), dict)
|
|
854
|
+
else None,
|
|
855
|
+
"followup_mode": followup_mode,
|
|
856
|
+
},
|
|
857
|
+
"commands": {
|
|
858
|
+
"bootstrap_message": bootstrap_command,
|
|
859
|
+
"scheduler_exec_dry_run": scheduler_exec_dry_run_command,
|
|
860
|
+
"scheduler_exec_candidate_template": candidate_execute_template,
|
|
861
|
+
"scheduler_exec_blocker_template": blocker_execute_template,
|
|
862
|
+
},
|
|
863
|
+
"bootstrap_message": {
|
|
864
|
+
"schema_version": bootstrap.get("schema_version"),
|
|
865
|
+
"invocation_mode": bootstrap.get("invocation_mode"),
|
|
866
|
+
"heartbeat_prompt_json_command": bootstrap.get("heartbeat_prompt_json_command"),
|
|
867
|
+
"quota_guard_command": bootstrap.get("quota_guard_command"),
|
|
868
|
+
"progress_refresh_command": bootstrap.get("progress_refresh_command"),
|
|
869
|
+
"refresh_command": bootstrap.get("refresh_command"),
|
|
870
|
+
"quota_spend_command": bootstrap.get("quota_spend_command"),
|
|
871
|
+
},
|
|
872
|
+
"scheduler_executor": scheduler_executor,
|
|
873
|
+
"boundary": {
|
|
874
|
+
"pilot_packet_only": True,
|
|
875
|
+
"runs_codex": False,
|
|
876
|
+
"runs_scheduler_result": False,
|
|
877
|
+
"reads_raw_transcripts": False,
|
|
878
|
+
"reads_credentials": False,
|
|
879
|
+
"reads_session_files": False,
|
|
880
|
+
"mutates_codex_session": False,
|
|
881
|
+
"spends_loopx_quota": False,
|
|
882
|
+
"requires_user_visible_start": True,
|
|
883
|
+
"headless_execution_disabled": True,
|
|
884
|
+
"candidate_execution_requires_guard_and_prefix": True,
|
|
885
|
+
},
|
|
886
|
+
"warnings": list(scheduler_executor.get("warnings") or []),
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
def build_codex_cli_visible_local_driver_pilot(
|
|
891
|
+
*,
|
|
892
|
+
project: Path,
|
|
893
|
+
goal_id: str | None,
|
|
894
|
+
agent_id: str | None,
|
|
895
|
+
cli_bin: str,
|
|
896
|
+
codex_bin: str,
|
|
897
|
+
probe_payload: dict[str, Any],
|
|
898
|
+
proof_payload: dict[str, Any] | None = None,
|
|
899
|
+
idle_payload: dict[str, Any] | None = None,
|
|
900
|
+
allow_headless_fallback: bool = False,
|
|
901
|
+
) -> dict[str, Any]:
|
|
902
|
+
"""Prototype the visible local driver loop without executing Codex.
|
|
903
|
+
|
|
904
|
+
This composes the first visible TUI bootstrap, a no-execution scheduler
|
|
905
|
+
wrapper, and the public-safe proof boundary a returning user would need
|
|
906
|
+
before LoopX can steer later visible turns.
|
|
907
|
+
"""
|
|
908
|
+
|
|
909
|
+
one_message = build_codex_cli_one_message_loop_pilot(
|
|
910
|
+
project=project,
|
|
911
|
+
goal_id=goal_id,
|
|
912
|
+
agent_id=agent_id,
|
|
913
|
+
cli_bin=cli_bin,
|
|
914
|
+
codex_bin=codex_bin,
|
|
915
|
+
probe_payload=probe_payload,
|
|
916
|
+
proof_payload=proof_payload,
|
|
917
|
+
idle_payload=idle_payload,
|
|
918
|
+
allow_headless_fallback=allow_headless_fallback,
|
|
919
|
+
)
|
|
920
|
+
scheduler_executor = (
|
|
921
|
+
one_message.get("scheduler_executor")
|
|
922
|
+
if isinstance(one_message.get("scheduler_executor"), dict)
|
|
923
|
+
else {}
|
|
924
|
+
)
|
|
925
|
+
scheduler_tick = (
|
|
926
|
+
scheduler_executor.get("scheduler_tick")
|
|
927
|
+
if isinstance(scheduler_executor.get("scheduler_tick"), dict)
|
|
928
|
+
else {}
|
|
929
|
+
)
|
|
930
|
+
execution = (
|
|
931
|
+
scheduler_executor.get("execution")
|
|
932
|
+
if isinstance(scheduler_executor.get("execution"), dict)
|
|
933
|
+
else {}
|
|
934
|
+
)
|
|
935
|
+
resolved_project = str(one_message["project"])
|
|
936
|
+
resolved_goal_id = str(one_message["goal_id"])
|
|
937
|
+
scheduler_action = str(scheduler_executor.get("scheduler_action") or "")
|
|
938
|
+
scheduler_blocker = (
|
|
939
|
+
scheduler_tick.get("precise_blocker")
|
|
940
|
+
if isinstance(scheduler_tick.get("precise_blocker"), dict)
|
|
941
|
+
else {}
|
|
942
|
+
)
|
|
943
|
+
scheduler_blocker_reason = str(scheduler_blocker.get("reason") or "")
|
|
944
|
+
proof = (
|
|
945
|
+
scheduler_tick.get("visible_session_proof")
|
|
946
|
+
if isinstance(scheduler_tick.get("visible_session_proof"), dict)
|
|
947
|
+
else {}
|
|
948
|
+
)
|
|
949
|
+
proof_approved = bool(proof.get("approved") is True)
|
|
950
|
+
idle_detector = build_codex_cli_runtime_idle_detector(
|
|
951
|
+
project=project,
|
|
952
|
+
goal_id=goal_id,
|
|
953
|
+
agent_id=agent_id,
|
|
954
|
+
cli_bin=cli_bin,
|
|
955
|
+
idle_payload=idle_payload,
|
|
956
|
+
)
|
|
957
|
+
idle_approved = bool(idle_detector.get("approved_for_visible_later_turn") is True)
|
|
958
|
+
idle_detector_command = (
|
|
959
|
+
f"{_shell_arg(cli_bin)} codex-cli-runtime-idle-detector "
|
|
960
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
961
|
+
f"{' --agent-id ' + _shell_arg(agent_id) if agent_id else ''} "
|
|
962
|
+
"--observe-local-runtime --observed-surface visible_resume_prompt "
|
|
963
|
+
"--turn-state idle --probe-human-input-idle --checked-before-prompt "
|
|
964
|
+
"--visible-to-user --user-can-interrupt --manual-takeover-available"
|
|
965
|
+
)
|
|
966
|
+
idle_fixture_detector_command = (
|
|
967
|
+
f"{_shell_arg(cli_bin)} codex-cli-runtime-idle-detector "
|
|
968
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
969
|
+
f"{' --agent-id ' + _shell_arg(agent_id) if agent_id else ''} "
|
|
970
|
+
"--idle-fixture <public-runtime-idle.json>"
|
|
971
|
+
)
|
|
972
|
+
|
|
973
|
+
if proof_approved and scheduler_action == "external_visible_command_candidate" and idle_approved:
|
|
974
|
+
loop_decision = "visible_candidate_ready_for_guarded_execution"
|
|
975
|
+
next_driver_action = "run_scheduler_exec_candidate_after_fresh_guard_and_prefix"
|
|
976
|
+
elif proof_approved and (
|
|
977
|
+
scheduler_action == "external_visible_command_candidate"
|
|
978
|
+
or scheduler_blocker_reason.startswith("runtime_idle_")
|
|
979
|
+
):
|
|
980
|
+
loop_decision = "runtime_idle_detector_required"
|
|
981
|
+
next_driver_action = "capture_public_safe_runtime_idle_observation"
|
|
982
|
+
elif scheduler_action == "write_precise_blocker":
|
|
983
|
+
loop_decision = "visible_loop_blocker_writeback_ready"
|
|
984
|
+
next_driver_action = "write_precise_blocker_after_fresh_guard"
|
|
985
|
+
elif scheduler_action == "surface_tui_bootstrap":
|
|
986
|
+
loop_decision = "surface_tui_bootstrap_only"
|
|
987
|
+
next_driver_action = "keep_first_message_tui_path_visible"
|
|
988
|
+
else:
|
|
989
|
+
loop_decision = "review_scheduler_packet_before_execution"
|
|
990
|
+
next_driver_action = "inspect_scheduler_executor_packet"
|
|
991
|
+
|
|
992
|
+
commands = one_message.get("commands") if isinstance(one_message.get("commands"), dict) else {}
|
|
993
|
+
scheduler_commands = (
|
|
994
|
+
scheduler_executor.get("commands")
|
|
995
|
+
if isinstance(scheduler_executor.get("commands"), dict)
|
|
996
|
+
else {}
|
|
997
|
+
)
|
|
998
|
+
visible_loop_steps = [
|
|
999
|
+
"start from the visible Codex CLI TUI with the one-message bootstrap",
|
|
1000
|
+
"run quota should-run with the registered agent id before each scheduler tick",
|
|
1001
|
+
"stop on interaction_contract.user_channel.action_required=true and show the concrete user todo",
|
|
1002
|
+
"require public-safe local idle observation or a fixture before any visible resume, remote-control, or same-TUI prompt",
|
|
1003
|
+
"run codex-cli-local-scheduler-exec as dry-run unless guard and explicit execution flags are present",
|
|
1004
|
+
"for a visible candidate, require guard_checked plus an allowed candidate command prefix",
|
|
1005
|
+
"for a blocker, write compact LoopX state only after guard_checked",
|
|
1006
|
+
"never read raw transcripts, session files, credentials, stdout, or stderr for this pilot",
|
|
1007
|
+
]
|
|
1008
|
+
|
|
1009
|
+
return {
|
|
1010
|
+
"ok": True,
|
|
1011
|
+
"schema_version": "codex_cli_visible_local_driver_pilot_v0",
|
|
1012
|
+
"project": resolved_project,
|
|
1013
|
+
"goal_id": resolved_goal_id,
|
|
1014
|
+
"agent_id": agent_id,
|
|
1015
|
+
"cli_bin": cli_bin,
|
|
1016
|
+
"codex_bin": codex_bin,
|
|
1017
|
+
"pilot_phase": "visible_local_driver_loop_no_execution",
|
|
1018
|
+
"start_surface": "codex_cli_tui_one_message",
|
|
1019
|
+
"loop_decision": loop_decision,
|
|
1020
|
+
"next_driver_action": next_driver_action,
|
|
1021
|
+
"one_message_pilot": {
|
|
1022
|
+
"schema_version": one_message.get("schema_version"),
|
|
1023
|
+
"pilot_decision": one_message.get("pilot_decision"),
|
|
1024
|
+
"start_surface": one_message.get("start_surface"),
|
|
1025
|
+
"followup_mode": one_message.get("followup_mode"),
|
|
1026
|
+
},
|
|
1027
|
+
"scheduler_executor": {
|
|
1028
|
+
"schema_version": scheduler_executor.get("schema_version"),
|
|
1029
|
+
"scheduler_action": scheduler_action,
|
|
1030
|
+
"decision": scheduler_executor.get("decision"),
|
|
1031
|
+
"executor_reason": execution.get("reason"),
|
|
1032
|
+
"executed": execution.get("executed"),
|
|
1033
|
+
},
|
|
1034
|
+
"visible_session_proof": {
|
|
1035
|
+
"supplied": bool(proof.get("supplied")),
|
|
1036
|
+
"approved": proof_approved,
|
|
1037
|
+
"decision": proof.get("decision"),
|
|
1038
|
+
"failures": proof.get("failures") or [],
|
|
1039
|
+
},
|
|
1040
|
+
"runtime_idle_detector": {
|
|
1041
|
+
"supplied": idle_payload is not None,
|
|
1042
|
+
"approved": idle_approved,
|
|
1043
|
+
"decision": idle_detector.get("decision"),
|
|
1044
|
+
"failures": idle_detector.get("failures") or [],
|
|
1045
|
+
"command": idle_detector_command,
|
|
1046
|
+
},
|
|
1047
|
+
"idle_guard_contract": {
|
|
1048
|
+
"required_before_visible_prompt": True,
|
|
1049
|
+
"fixture_keys": [
|
|
1050
|
+
"idle_guard.no_active_human_typing",
|
|
1051
|
+
"idle_guard.no_running_turn",
|
|
1052
|
+
"idle_guard.checked_before_prompt",
|
|
1053
|
+
"turn_visibility.visible_to_user",
|
|
1054
|
+
"interruptibility.user_can_interrupt",
|
|
1055
|
+
"interruptibility.manual_takeover_available",
|
|
1056
|
+
],
|
|
1057
|
+
"current_pilot_implements_runtime_idle_detection": True,
|
|
1058
|
+
"fixture_backed_runtime_idle_detector": True,
|
|
1059
|
+
"runtime_sensor_implemented": True,
|
|
1060
|
+
"public_safe_fixture_supported": True,
|
|
1061
|
+
"local_observation_adapter_supported": True,
|
|
1062
|
+
"no_private_state_observation": True,
|
|
1063
|
+
},
|
|
1064
|
+
"visible_loop_steps": visible_loop_steps,
|
|
1065
|
+
"commands": {
|
|
1066
|
+
"bootstrap_message": commands.get("bootstrap_message"),
|
|
1067
|
+
"scheduler_exec_dry_run": commands.get("scheduler_exec_dry_run"),
|
|
1068
|
+
"scheduler_exec_candidate_template": commands.get("scheduler_exec_candidate_template"),
|
|
1069
|
+
"scheduler_exec_blocker_template": commands.get("scheduler_exec_blocker_template"),
|
|
1070
|
+
"scheduler_tick": scheduler_commands.get("scheduler_tick"),
|
|
1071
|
+
"candidate_command": scheduler_commands.get("candidate_command"),
|
|
1072
|
+
"blocker_writeback": scheduler_commands.get("blocker_writeback"),
|
|
1073
|
+
"runtime_idle_detector": idle_detector_command,
|
|
1074
|
+
"runtime_idle_detector_fixture": idle_fixture_detector_command,
|
|
1075
|
+
},
|
|
1076
|
+
"execution_policy": {
|
|
1077
|
+
"tui_bootstrap_primary": True,
|
|
1078
|
+
"later_turns_visible_to_user": True,
|
|
1079
|
+
"user_can_interrupt_or_take_over": True,
|
|
1080
|
+
"same_session_attachment_requires_visible_proof": True,
|
|
1081
|
+
"headless_execution_disabled": True,
|
|
1082
|
+
"quota_guard_required_each_tick": True,
|
|
1083
|
+
"spend_after_validated_writeback_only": True,
|
|
1084
|
+
},
|
|
1085
|
+
"boundary": {
|
|
1086
|
+
"pilot_packet_only": True,
|
|
1087
|
+
"runs_codex": False,
|
|
1088
|
+
"runs_scheduler_result": False,
|
|
1089
|
+
"reads_raw_transcripts": False,
|
|
1090
|
+
"reads_credentials": False,
|
|
1091
|
+
"reads_session_files": False,
|
|
1092
|
+
"reads_stdout_stderr": False,
|
|
1093
|
+
"mutates_codex_session": False,
|
|
1094
|
+
"writes_loopx_state": False,
|
|
1095
|
+
"spends_loopx_quota": False,
|
|
1096
|
+
"requires_fresh_guard_before_execution": True,
|
|
1097
|
+
"candidate_execution_requires_guard_and_prefix": True,
|
|
1098
|
+
"blocker_writeback_requires_guard_checked": True,
|
|
1099
|
+
"headless_execution_disabled": True,
|
|
1100
|
+
},
|
|
1101
|
+
"warnings": [
|
|
1102
|
+
*list(one_message.get("warnings") or []),
|
|
1103
|
+
*(
|
|
1104
|
+
["Runtime idle detector must pass before a later visible Codex CLI turn can run."]
|
|
1105
|
+
if proof_approved and not idle_approved
|
|
1106
|
+
else []
|
|
1107
|
+
),
|
|
1108
|
+
],
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
def build_codex_cli_visible_first_response_capture_plan(
|
|
1113
|
+
*,
|
|
1114
|
+
project: Path,
|
|
1115
|
+
goal_id: str | None,
|
|
1116
|
+
agent_id: str | None,
|
|
1117
|
+
cli_bin: str,
|
|
1118
|
+
first_response_path: str = "public-first-response.json",
|
|
1119
|
+
idle_path: str = "public-runtime-idle.json",
|
|
1120
|
+
) -> dict[str, Any]:
|
|
1121
|
+
"""Describe the safest public fixture capture path for visible TUI bootstrap.
|
|
1122
|
+
|
|
1123
|
+
This is deliberately a plan packet. It does not start Codex, read terminal
|
|
1124
|
+
buffers, inspect session files, or write fixtures. A human-visible TUI run
|
|
1125
|
+
supplies the observations, and the bounded visible adapter validates the
|
|
1126
|
+
resulting public-safe JSON before any success claim or quota spend.
|
|
1127
|
+
"""
|
|
1128
|
+
|
|
1129
|
+
adapter = build_codex_cli_bounded_visible_pilot_adapter(
|
|
1130
|
+
project=project,
|
|
1131
|
+
goal_id=goal_id,
|
|
1132
|
+
agent_id=agent_id,
|
|
1133
|
+
cli_bin=cli_bin,
|
|
1134
|
+
)
|
|
1135
|
+
resolved_project = str(adapter["project"])
|
|
1136
|
+
resolved_goal_id = str(adapter["goal_id"])
|
|
1137
|
+
agent_arg = f" --agent-id {_shell_arg(agent_id)}" if agent_id else ""
|
|
1138
|
+
first_response_fixture = {
|
|
1139
|
+
"observed_surface": "codex_cli_tui_visible_window",
|
|
1140
|
+
"prompt_delivery": {
|
|
1141
|
+
"manual_or_visible_delivery": True,
|
|
1142
|
+
"prompt_public_safe": True,
|
|
1143
|
+
"argv_prompt_used": False,
|
|
1144
|
+
},
|
|
1145
|
+
"first_response": {
|
|
1146
|
+
"goal_id_visible": True,
|
|
1147
|
+
"user_gate_or_none_visible": True,
|
|
1148
|
+
"top_user_todo_or_none_visible": True,
|
|
1149
|
+
"top_agent_todo_visible": True,
|
|
1150
|
+
"next_safe_action_visible": True,
|
|
1151
|
+
"bounded_segment_started_or_blocker_written": True,
|
|
1152
|
+
},
|
|
1153
|
+
"interruptibility": {
|
|
1154
|
+
"user_can_interrupt": True,
|
|
1155
|
+
"manual_takeover_available": True,
|
|
1156
|
+
},
|
|
1157
|
+
"writeback": {
|
|
1158
|
+
"compact_evidence_planned": True,
|
|
1159
|
+
"quota_spend_after_writeback_only": True,
|
|
1160
|
+
},
|
|
1161
|
+
"boundary": {
|
|
1162
|
+
"reads_raw_transcripts": False,
|
|
1163
|
+
"reads_session_files": False,
|
|
1164
|
+
"reads_stdout_stderr": False,
|
|
1165
|
+
"reads_credentials": False,
|
|
1166
|
+
"mutates_hidden_session_state": False,
|
|
1167
|
+
"spends_quota_before_writeback": False,
|
|
1168
|
+
},
|
|
1169
|
+
}
|
|
1170
|
+
runtime_idle_fixture = {
|
|
1171
|
+
"observed_surface": "codex_cli_tui_visible_window",
|
|
1172
|
+
"idle_guard": {
|
|
1173
|
+
"no_active_human_typing": True,
|
|
1174
|
+
"no_running_turn": True,
|
|
1175
|
+
"checked_before_prompt": True,
|
|
1176
|
+
},
|
|
1177
|
+
"turn_visibility": {"visible_to_user": True},
|
|
1178
|
+
"interruptibility": {
|
|
1179
|
+
"user_can_interrupt": True,
|
|
1180
|
+
"manual_takeover_available": True,
|
|
1181
|
+
},
|
|
1182
|
+
"boundary": {
|
|
1183
|
+
"reads_raw_transcripts": False,
|
|
1184
|
+
"reads_session_files": False,
|
|
1185
|
+
"reads_stdout_stderr": False,
|
|
1186
|
+
"reads_credentials": False,
|
|
1187
|
+
"mutates_hidden_session_state": False,
|
|
1188
|
+
},
|
|
1189
|
+
}
|
|
1190
|
+
first_response_checklist = [
|
|
1191
|
+
{
|
|
1192
|
+
"key": key,
|
|
1193
|
+
"required": True,
|
|
1194
|
+
"description": description,
|
|
1195
|
+
"path": ".".join(path),
|
|
1196
|
+
}
|
|
1197
|
+
for key, path, description in FIRST_RESPONSE_REQUIRED_TRUE_CHECKS
|
|
1198
|
+
] + [
|
|
1199
|
+
{
|
|
1200
|
+
"key": key,
|
|
1201
|
+
"required": False,
|
|
1202
|
+
"description": description,
|
|
1203
|
+
"path": ".".join(path),
|
|
1204
|
+
}
|
|
1205
|
+
for key, path, description in FIRST_RESPONSE_REQUIRED_FALSE_CHECKS
|
|
1206
|
+
]
|
|
1207
|
+
runtime_idle_checklist = [
|
|
1208
|
+
{
|
|
1209
|
+
"key": key,
|
|
1210
|
+
"required": True,
|
|
1211
|
+
"description": description,
|
|
1212
|
+
"path": ".".join(path),
|
|
1213
|
+
}
|
|
1214
|
+
for key, path, description in RUNTIME_IDLE_REQUIRED_TRUE_CHECKS
|
|
1215
|
+
] + [
|
|
1216
|
+
{
|
|
1217
|
+
"key": key,
|
|
1218
|
+
"required": False,
|
|
1219
|
+
"description": description,
|
|
1220
|
+
"path": ".".join(path),
|
|
1221
|
+
}
|
|
1222
|
+
for key, path, description in RUNTIME_IDLE_REQUIRED_FALSE_CHECKS
|
|
1223
|
+
]
|
|
1224
|
+
capture_steps = [
|
|
1225
|
+
"Run quota should-run for the goal and stop if a concrete user gate blocks this path.",
|
|
1226
|
+
"Open Codex CLI TUI yourself in the project repo; do not pass the bootstrap message as argv.",
|
|
1227
|
+
"Paste the generated LoopX bootstrap message into the visible TUI.",
|
|
1228
|
+
"Observe only whether the first response exposes the required public-safe fields; do not copy raw text.",
|
|
1229
|
+
f"Write those booleans to {first_response_path}.",
|
|
1230
|
+
"After the first response or blocker is visible, confirm the TUI is idle and the user is not typing.",
|
|
1231
|
+
f"Write those idle booleans to {idle_path}.",
|
|
1232
|
+
"Run the bounded visible pilot adapter with both fixtures before claiming success or spending quota.",
|
|
1233
|
+
]
|
|
1234
|
+
stop_conditions = [
|
|
1235
|
+
"the first response contains private paths, internal project names, credentials, or raw logs",
|
|
1236
|
+
"the bootstrap message would have to be passed as argv",
|
|
1237
|
+
"the user is typing or Codex is already running a visible turn",
|
|
1238
|
+
"the response does not show goal/todo/gate/next-action status clearly enough to fill the fixture",
|
|
1239
|
+
"any required boundary boolean would be false",
|
|
1240
|
+
]
|
|
1241
|
+
commands = {
|
|
1242
|
+
"quota_guard": (
|
|
1243
|
+
f"{_shell_arg(cli_bin)} --format json quota should-run "
|
|
1244
|
+
f"--goal-id {_shell_arg(resolved_goal_id)}{agent_arg}"
|
|
1245
|
+
f"{CODEX_CLI_SCHEDULER_ARGS}"
|
|
1246
|
+
),
|
|
1247
|
+
"bootstrap_message": (
|
|
1248
|
+
f"{_shell_arg(cli_bin)} codex-cli-bootstrap-message "
|
|
1249
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
1250
|
+
f"{agent_arg} --message-only"
|
|
1251
|
+
),
|
|
1252
|
+
"runtime_idle_detector": (
|
|
1253
|
+
f"{_shell_arg(cli_bin)} codex-cli-runtime-idle-detector "
|
|
1254
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
1255
|
+
f"{agent_arg} --idle-fixture {_shell_arg(idle_path)}"
|
|
1256
|
+
),
|
|
1257
|
+
"bounded_visible_pilot_adapter": (
|
|
1258
|
+
f"{_shell_arg(cli_bin)} codex-cli-bounded-visible-pilot-adapter "
|
|
1259
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
1260
|
+
f"{agent_arg} --first-response-fixture {_shell_arg(first_response_path)} "
|
|
1261
|
+
f"--idle-fixture {_shell_arg(idle_path)}"
|
|
1262
|
+
),
|
|
1263
|
+
"capture_plan": (
|
|
1264
|
+
f"{_shell_arg(cli_bin)} codex-cli-visible-first-response-capture-plan "
|
|
1265
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
1266
|
+
f"{agent_arg} --first-response-path {_shell_arg(first_response_path)} "
|
|
1267
|
+
f"--idle-path {_shell_arg(idle_path)}"
|
|
1268
|
+
),
|
|
1269
|
+
}
|
|
1270
|
+
return {
|
|
1271
|
+
"ok": True,
|
|
1272
|
+
"schema_version": "codex_cli_visible_first_response_capture_plan_v0",
|
|
1273
|
+
"project": resolved_project,
|
|
1274
|
+
"goal_id": resolved_goal_id,
|
|
1275
|
+
"agent_id": agent_id,
|
|
1276
|
+
"cli_bin": cli_bin,
|
|
1277
|
+
"decision": "manual_visible_capture_plan_ready",
|
|
1278
|
+
"start_surface": "codex_cli_tui_manual_paste",
|
|
1279
|
+
"next_safe_step": "paste the bootstrap message into a visible Codex CLI TUI and record only public-safe fixture booleans",
|
|
1280
|
+
"output_artifacts": {
|
|
1281
|
+
"first_response_fixture": first_response_path,
|
|
1282
|
+
"runtime_idle_fixture": idle_path,
|
|
1283
|
+
},
|
|
1284
|
+
"capture_steps": capture_steps,
|
|
1285
|
+
"stop_conditions": stop_conditions,
|
|
1286
|
+
"first_response_checklist": first_response_checklist,
|
|
1287
|
+
"runtime_idle_checklist": runtime_idle_checklist,
|
|
1288
|
+
"sample_first_response_fixture": first_response_fixture,
|
|
1289
|
+
"sample_runtime_idle_fixture": runtime_idle_fixture,
|
|
1290
|
+
"commands": commands,
|
|
1291
|
+
"adapter_decision_without_fixtures": adapter.get("decision"),
|
|
1292
|
+
"boundary": {
|
|
1293
|
+
"capture_plan_only": True,
|
|
1294
|
+
"runs_codex": False,
|
|
1295
|
+
"reads_raw_transcripts": False,
|
|
1296
|
+
"reads_session_files": False,
|
|
1297
|
+
"reads_stdout_stderr": False,
|
|
1298
|
+
"reads_credentials": False,
|
|
1299
|
+
"mutates_codex_session": False,
|
|
1300
|
+
"writes_loopx_state": False,
|
|
1301
|
+
"spends_loopx_quota": False,
|
|
1302
|
+
"requires_visible_delivery": True,
|
|
1303
|
+
"manual_paste_primary": True,
|
|
1304
|
+
"argv_prompt_rejected": True,
|
|
1305
|
+
"success_claim_requires_bounded_adapter": True,
|
|
1306
|
+
},
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
def build_codex_cli_bounded_visible_pilot_adapter(
|
|
1311
|
+
*,
|
|
1312
|
+
project: Path,
|
|
1313
|
+
goal_id: str | None,
|
|
1314
|
+
agent_id: str | None,
|
|
1315
|
+
cli_bin: str,
|
|
1316
|
+
first_response_payload: dict[str, Any] | None = None,
|
|
1317
|
+
idle_payload: dict[str, Any] | None = None,
|
|
1318
|
+
) -> dict[str, Any]:
|
|
1319
|
+
"""Validate the bounded evidence needed before claiming live TUI success.
|
|
1320
|
+
|
|
1321
|
+
The adapter is intentionally a packet builder and fixture validator. It
|
|
1322
|
+
does not start Codex, inspect transcripts, read session files, or capture
|
|
1323
|
+
stdout/stderr. A separate visible/manual run must supply a public-safe
|
|
1324
|
+
first-response fixture and a runtime-idle fixture before this packet can
|
|
1325
|
+
approve a live-TUI first-message success claim.
|
|
1326
|
+
"""
|
|
1327
|
+
|
|
1328
|
+
bootstrap = build_codex_cli_bootstrap_message(
|
|
1329
|
+
project=project,
|
|
1330
|
+
goal_id=goal_id,
|
|
1331
|
+
agent_id=agent_id,
|
|
1332
|
+
cli_bin=cli_bin,
|
|
1333
|
+
)
|
|
1334
|
+
resolved_project = str(bootstrap["project"])
|
|
1335
|
+
resolved_goal_id = str(bootstrap["goal_id"])
|
|
1336
|
+
agent_arg = f" --agent-id {_shell_arg(agent_id)}" if agent_id else ""
|
|
1337
|
+
required_first_response_shape = {
|
|
1338
|
+
"observed_surface": "codex_cli_tui_visible_window | visible_paste_adapter",
|
|
1339
|
+
"prompt_delivery": {
|
|
1340
|
+
"manual_or_visible_delivery": True,
|
|
1341
|
+
"prompt_public_safe": True,
|
|
1342
|
+
"argv_prompt_used": False,
|
|
1343
|
+
},
|
|
1344
|
+
"first_response": {
|
|
1345
|
+
"goal_id_visible": True,
|
|
1346
|
+
"user_gate_or_none_visible": True,
|
|
1347
|
+
"top_user_todo_or_none_visible": True,
|
|
1348
|
+
"top_agent_todo_visible": True,
|
|
1349
|
+
"next_safe_action_visible": True,
|
|
1350
|
+
"bounded_segment_started_or_blocker_written": True,
|
|
1351
|
+
},
|
|
1352
|
+
"interruptibility": {
|
|
1353
|
+
"user_can_interrupt": True,
|
|
1354
|
+
"manual_takeover_available": True,
|
|
1355
|
+
},
|
|
1356
|
+
"writeback": {
|
|
1357
|
+
"compact_evidence_planned": True,
|
|
1358
|
+
"quota_spend_after_writeback_only": True,
|
|
1359
|
+
},
|
|
1360
|
+
"boundary": {
|
|
1361
|
+
"reads_raw_transcripts": False,
|
|
1362
|
+
"reads_session_files": False,
|
|
1363
|
+
"reads_stdout_stderr": False,
|
|
1364
|
+
"reads_credentials": False,
|
|
1365
|
+
"mutates_hidden_session_state": False,
|
|
1366
|
+
"spends_quota_before_writeback": False,
|
|
1367
|
+
},
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
first_response_checks: list[dict[str, Any]] = []
|
|
1371
|
+
first_response_failures: list[str] = []
|
|
1372
|
+
observed_surface = "missing"
|
|
1373
|
+
if first_response_payload is None:
|
|
1374
|
+
first_response_failures.append("missing_first_response_evidence")
|
|
1375
|
+
else:
|
|
1376
|
+
observed_surface = str(first_response_payload.get("observed_surface") or "unknown")
|
|
1377
|
+
for key, path, description in FIRST_RESPONSE_REQUIRED_TRUE_CHECKS:
|
|
1378
|
+
passed = _nested_bool(first_response_payload, path)
|
|
1379
|
+
first_response_checks.append(
|
|
1380
|
+
{"key": key, "required": True, "passed": passed, "description": description}
|
|
1381
|
+
)
|
|
1382
|
+
if not passed:
|
|
1383
|
+
first_response_failures.append(key)
|
|
1384
|
+
for key, path, description in FIRST_RESPONSE_REQUIRED_FALSE_CHECKS:
|
|
1385
|
+
passed = _nested_false(first_response_payload, path)
|
|
1386
|
+
first_response_checks.append(
|
|
1387
|
+
{"key": key, "required": False, "passed": passed, "description": description}
|
|
1388
|
+
)
|
|
1389
|
+
if not passed:
|
|
1390
|
+
first_response_failures.append(key)
|
|
1391
|
+
supported_surface = observed_surface in {
|
|
1392
|
+
"codex_cli_tui_visible_window",
|
|
1393
|
+
"visible_paste_adapter",
|
|
1394
|
+
}
|
|
1395
|
+
first_response_checks.append(
|
|
1396
|
+
{
|
|
1397
|
+
"key": "supported_observed_surface",
|
|
1398
|
+
"required": sorted(["codex_cli_tui_visible_window", "visible_paste_adapter"]),
|
|
1399
|
+
"actual": observed_surface,
|
|
1400
|
+
"passed": supported_surface,
|
|
1401
|
+
"description": "first response was observed on a visible Codex CLI surface",
|
|
1402
|
+
}
|
|
1403
|
+
)
|
|
1404
|
+
if not supported_surface:
|
|
1405
|
+
first_response_failures.append("unsupported_observed_surface")
|
|
1406
|
+
if _nested_bool(first_response_payload, ("prompt_delivery", "argv_prompt_used")):
|
|
1407
|
+
first_response_failures.append("argv_prompt_leakage_risk")
|
|
1408
|
+
|
|
1409
|
+
idle_detector = build_codex_cli_runtime_idle_detector(
|
|
1410
|
+
project=project,
|
|
1411
|
+
goal_id=resolved_goal_id,
|
|
1412
|
+
agent_id=agent_id,
|
|
1413
|
+
cli_bin=cli_bin,
|
|
1414
|
+
idle_payload=idle_payload,
|
|
1415
|
+
)
|
|
1416
|
+
idle_approved = idle_detector.get("approved_for_visible_later_turn") is True
|
|
1417
|
+
first_response_approved = bool(first_response_payload is not None and not first_response_failures)
|
|
1418
|
+
blockers: list[str] = []
|
|
1419
|
+
blockers.extend(first_response_failures)
|
|
1420
|
+
if not idle_approved:
|
|
1421
|
+
blockers.extend(idle_detector.get("failures") or ["runtime_idle_evidence_required"])
|
|
1422
|
+
|
|
1423
|
+
if first_response_approved and idle_approved:
|
|
1424
|
+
decision = "bounded_visible_pilot_ready_for_success_claim"
|
|
1425
|
+
approved = True
|
|
1426
|
+
next_safe_step = (
|
|
1427
|
+
"write compact success evidence, refresh state with outcome_progress, "
|
|
1428
|
+
"then spend exactly one quota slot"
|
|
1429
|
+
)
|
|
1430
|
+
elif first_response_payload is None:
|
|
1431
|
+
decision = "bounded_visible_completion_evidence_required"
|
|
1432
|
+
approved = False
|
|
1433
|
+
next_safe_step = (
|
|
1434
|
+
"capture the first visible TUI response as the public-safe fixture shape "
|
|
1435
|
+
"below, then rerun this adapter before spending quota"
|
|
1436
|
+
)
|
|
1437
|
+
elif not first_response_approved:
|
|
1438
|
+
decision = "bounded_visible_first_response_incomplete"
|
|
1439
|
+
approved = False
|
|
1440
|
+
next_safe_step = (
|
|
1441
|
+
"treat the live TUI pilot as blocked and write the precise blocker; "
|
|
1442
|
+
"do not claim first-message success"
|
|
1443
|
+
)
|
|
1444
|
+
else:
|
|
1445
|
+
decision = "bounded_visible_runtime_idle_required"
|
|
1446
|
+
approved = False
|
|
1447
|
+
next_safe_step = (
|
|
1448
|
+
"capture runtime idle evidence proving no active typing or running turn "
|
|
1449
|
+
"before marking the visible pilot complete"
|
|
1450
|
+
)
|
|
1451
|
+
|
|
1452
|
+
bounded_adapter_command = (
|
|
1453
|
+
f"{_shell_arg(cli_bin)} codex-cli-bounded-visible-pilot-adapter "
|
|
1454
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
1455
|
+
f"{agent_arg} --first-response-fixture <public-first-response.json> "
|
|
1456
|
+
"--idle-fixture <public-runtime-idle.json>"
|
|
1457
|
+
)
|
|
1458
|
+
runtime_idle_command = (
|
|
1459
|
+
f"{_shell_arg(cli_bin)} codex-cli-runtime-idle-detector "
|
|
1460
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
1461
|
+
f"{agent_arg} --idle-fixture <public-runtime-idle.json>"
|
|
1462
|
+
)
|
|
1463
|
+
blocker_summary = blockers[0] if blockers else "none"
|
|
1464
|
+
blocker_writeback = (
|
|
1465
|
+
f"{_shell_arg(cli_bin)} refresh-state --goal-id {_shell_arg(resolved_goal_id)} "
|
|
1466
|
+
"--classification codex_cli_bounded_visible_pilot_blocker "
|
|
1467
|
+
"--delivery-batch-scale implementation --delivery-outcome outcome_gap "
|
|
1468
|
+
f"--recommended-action {_shell_arg('Codex CLI bounded visible pilot blocked: ' + blocker_summary)}"
|
|
1469
|
+
)
|
|
1470
|
+
success_writeback = (
|
|
1471
|
+
f"{_shell_arg(cli_bin)} refresh-state --goal-id {_shell_arg(resolved_goal_id)} "
|
|
1472
|
+
"--classification codex_cli_bounded_visible_pilot_success "
|
|
1473
|
+
"--delivery-batch-scale implementation --delivery-outcome outcome_progress "
|
|
1474
|
+
"--recommended-action "
|
|
1475
|
+
f"{_shell_arg('Promote Codex CLI one-message TUI bootstrap only after documented release-path validation.')}"
|
|
1476
|
+
)
|
|
1477
|
+
|
|
1478
|
+
return {
|
|
1479
|
+
"ok": True,
|
|
1480
|
+
"schema_version": "codex_cli_bounded_visible_pilot_adapter_v0",
|
|
1481
|
+
"project": resolved_project,
|
|
1482
|
+
"goal_id": resolved_goal_id,
|
|
1483
|
+
"agent_id": agent_id,
|
|
1484
|
+
"cli_bin": cli_bin,
|
|
1485
|
+
"decision": decision,
|
|
1486
|
+
"approved_for_live_tui_success_claim": approved,
|
|
1487
|
+
"observed_surface": observed_surface,
|
|
1488
|
+
"next_safe_step": next_safe_step,
|
|
1489
|
+
"blockers": blockers,
|
|
1490
|
+
"first_response": {
|
|
1491
|
+
"supplied": first_response_payload is not None,
|
|
1492
|
+
"approved": first_response_approved,
|
|
1493
|
+
"checks": first_response_checks,
|
|
1494
|
+
"failures": first_response_failures,
|
|
1495
|
+
},
|
|
1496
|
+
"runtime_idle_detector": {
|
|
1497
|
+
"supplied": idle_payload is not None,
|
|
1498
|
+
"approved": idle_approved,
|
|
1499
|
+
"decision": idle_detector.get("decision"),
|
|
1500
|
+
"failures": idle_detector.get("failures") or [],
|
|
1501
|
+
"source": idle_detector.get("source"),
|
|
1502
|
+
},
|
|
1503
|
+
"commands": {
|
|
1504
|
+
"bootstrap_message": (
|
|
1505
|
+
f"{_shell_arg(cli_bin)} codex-cli-bootstrap-message "
|
|
1506
|
+
f"--project {_shell_arg(resolved_project)} --goal-id {_shell_arg(resolved_goal_id)}"
|
|
1507
|
+
f"{agent_arg} --message-only"
|
|
1508
|
+
),
|
|
1509
|
+
"bounded_visible_pilot_adapter": bounded_adapter_command,
|
|
1510
|
+
"runtime_idle_detector": runtime_idle_command,
|
|
1511
|
+
"blocker_writeback": blocker_writeback,
|
|
1512
|
+
"success_writeback": success_writeback,
|
|
1513
|
+
},
|
|
1514
|
+
"required_first_response_shape": required_first_response_shape,
|
|
1515
|
+
"required_runtime_idle_shape": idle_detector.get("required_fixture_shape"),
|
|
1516
|
+
"boundary": {
|
|
1517
|
+
"adapter_packet_only": True,
|
|
1518
|
+
"runs_codex": False,
|
|
1519
|
+
"reads_raw_transcripts": False,
|
|
1520
|
+
"reads_credentials": False,
|
|
1521
|
+
"reads_session_files": False,
|
|
1522
|
+
"reads_stdout_stderr": False,
|
|
1523
|
+
"mutates_codex_session": False,
|
|
1524
|
+
"writes_loopx_state": False,
|
|
1525
|
+
"spends_loopx_quota": False,
|
|
1526
|
+
"requires_visible_delivery": True,
|
|
1527
|
+
"argv_prompt_rejected": True,
|
|
1528
|
+
"success_claim_requires_first_response_and_idle": True,
|
|
1529
|
+
},
|
|
1530
|
+
}
|