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/project_prompt.py
ADDED
|
@@ -0,0 +1,1153 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import shlex
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from .bootstrap import default_goal_id
|
|
8
|
+
from .control_plane.scheduler.execution_context import (
|
|
9
|
+
GENERIC_CLI_OUTER_CONTROLLER_SCHEDULER_CONTEXT,
|
|
10
|
+
render_scheduler_execution_args,
|
|
11
|
+
)
|
|
12
|
+
from .control_plane.todos.contract import normalize_required_capabilities
|
|
13
|
+
from .install_contract import NO_CLONE_INSTALL_URL
|
|
14
|
+
|
|
15
|
+
DEFAULT_HANDOFF_OBJECTIVE = "<OBJECTIVE_FROM_GOAL_DOC>"
|
|
16
|
+
DEFAULT_HANDOFF_DOMAIN = "<DOMAIN>"
|
|
17
|
+
DEFAULT_HANDOFF_ADAPTER_KIND = "read_only_project_map_v0"
|
|
18
|
+
DEFAULT_HANDOFF_ADAPTER_STATUS = "connected-read-only"
|
|
19
|
+
DEFAULT_HANDOFF_NEXT_PROBE = "(omit --next-probe until a read-only pre-tick command exists)"
|
|
20
|
+
SHARED_GLOBAL_REGISTRY = '"$HOME/.codex/loopx/registry.global.json"'
|
|
21
|
+
CODEX_CLI_VISIBLE_SCHEDULER_CONTEXT = {
|
|
22
|
+
"host_surface": "codex_cli",
|
|
23
|
+
"scheduler_owner": "agent_cli_loop",
|
|
24
|
+
"execution_mode": "interactive",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def shell_arg(value: str) -> str:
|
|
29
|
+
return shlex.quote(value)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def shell_arg_or_placeholder(value: str) -> str:
|
|
33
|
+
text = str(value)
|
|
34
|
+
if text.startswith("<") and text.endswith(">"):
|
|
35
|
+
return text
|
|
36
|
+
return shell_arg(text)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def render_available_capability_args(values: Any) -> str:
|
|
40
|
+
return "".join(
|
|
41
|
+
f" --available-capability {shell_arg(capability)}"
|
|
42
|
+
for capability in normalize_required_capabilities(values)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def render_cli_preflight(*, cli_bin: str = "loopx") -> str:
|
|
47
|
+
cli_bin_arg = shell_arg(cli_bin)
|
|
48
|
+
return f"""export PATH="$HOME/.local/bin:$PATH"
|
|
49
|
+
install_script="$HOME/loopx/scripts/install-local.sh"
|
|
50
|
+
if ! command -v {cli_bin_arg} >/dev/null 2>&1; then
|
|
51
|
+
if [ -x "$install_script" ]; then
|
|
52
|
+
"$install_script"
|
|
53
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
54
|
+
else
|
|
55
|
+
echo "loopx is not on PATH; clone the LoopX repo and run scripts/install-local.sh" >&2
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
{cli_bin_arg} doctor >/dev/null"""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def render_codex_cli_no_clone_preflight(
|
|
63
|
+
*,
|
|
64
|
+
cli_bin: str = "loopx",
|
|
65
|
+
doctor_agent_type: str | None = None,
|
|
66
|
+
) -> str:
|
|
67
|
+
cli_bin_arg = shell_arg(cli_bin)
|
|
68
|
+
doctor_agent_arg = (
|
|
69
|
+
f" --agent-type {shell_arg(doctor_agent_type)}"
|
|
70
|
+
if doctor_agent_type
|
|
71
|
+
else ""
|
|
72
|
+
)
|
|
73
|
+
return f"""export PATH="$HOME/.local/bin:$PATH"
|
|
74
|
+
if ! command -v {cli_bin_arg} >/dev/null 2>&1; then
|
|
75
|
+
if command -v curl >/dev/null 2>&1; then
|
|
76
|
+
curl -fsSL {NO_CLONE_INSTALL_URL} | bash
|
|
77
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
78
|
+
else
|
|
79
|
+
echo "loopx is not on PATH and curl is unavailable; install curl or use a contributor clone with scripts/install-local.sh" >&2
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
|
+
{cli_bin_arg} doctor{doctor_agent_arg} >/dev/null"""
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def render_quota_guard_command(
|
|
87
|
+
goal_id: str,
|
|
88
|
+
*,
|
|
89
|
+
cli_bin: str = "loopx",
|
|
90
|
+
agent_id: str | None = None,
|
|
91
|
+
available_capabilities: Any = None,
|
|
92
|
+
runtime_profile: str | None = None,
|
|
93
|
+
scheduler_execution_context: dict[str, Any] | None = None,
|
|
94
|
+
heartbeat_turn_receipt: bool = False,
|
|
95
|
+
) -> str:
|
|
96
|
+
agent_arg = f" --agent-id {shell_arg(agent_id)}" if agent_id else ""
|
|
97
|
+
capability_args = render_available_capability_args(available_capabilities)
|
|
98
|
+
scheduler_args = render_scheduler_execution_args(
|
|
99
|
+
runtime_profile=runtime_profile,
|
|
100
|
+
scheduler_execution_context=scheduler_execution_context,
|
|
101
|
+
)
|
|
102
|
+
turn_arg = (
|
|
103
|
+
' --turn-instance-id "${LOOPX_TURN:?}"'
|
|
104
|
+
if heartbeat_turn_receipt
|
|
105
|
+
else ""
|
|
106
|
+
)
|
|
107
|
+
return (
|
|
108
|
+
f"{shell_arg(cli_bin)} --format json "
|
|
109
|
+
f"--registry {SHARED_GLOBAL_REGISTRY} "
|
|
110
|
+
f"quota should-run --goal-id {shell_arg(goal_id)}{agent_arg}"
|
|
111
|
+
f"{capability_args}{scheduler_args}{turn_arg}"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def render_quota_spend_command(
|
|
116
|
+
goal_id: str,
|
|
117
|
+
*,
|
|
118
|
+
source: str = "adapter",
|
|
119
|
+
cli_bin: str = "loopx",
|
|
120
|
+
agent_id: str | None = None,
|
|
121
|
+
available_capabilities: Any = None,
|
|
122
|
+
) -> str:
|
|
123
|
+
agent_arg = f" --agent-id {shell_arg(agent_id)}" if agent_id else ""
|
|
124
|
+
capability_args = render_available_capability_args(available_capabilities)
|
|
125
|
+
return (
|
|
126
|
+
f"{shell_arg(cli_bin)} "
|
|
127
|
+
f"--registry {SHARED_GLOBAL_REGISTRY} "
|
|
128
|
+
"quota spend-slot "
|
|
129
|
+
f"--goal-id {shell_arg(goal_id)} "
|
|
130
|
+
f"--slots 1 --source {shell_arg(source)} --execute{agent_arg}{capability_args}"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def render_refresh_state_command(
|
|
135
|
+
goal_id: str,
|
|
136
|
+
*,
|
|
137
|
+
cli_bin: str = "loopx",
|
|
138
|
+
project: str | None = None,
|
|
139
|
+
agent_id: str | None = None,
|
|
140
|
+
progress_scope: str | None = None,
|
|
141
|
+
classification: str | None = None,
|
|
142
|
+
delivery_batch_scale: str | None = None,
|
|
143
|
+
delivery_outcome: str | None = None,
|
|
144
|
+
) -> str:
|
|
145
|
+
project_arg = f" --project {shell_arg(project)}" if project else ""
|
|
146
|
+
agent_arg = f" --agent-id {shell_arg(agent_id)}" if agent_id else ""
|
|
147
|
+
scope_arg = f" --progress-scope {shell_arg(progress_scope)}" if progress_scope else ""
|
|
148
|
+
classification_arg = (
|
|
149
|
+
f" --classification {shell_arg_or_placeholder(classification)}"
|
|
150
|
+
if classification
|
|
151
|
+
else ""
|
|
152
|
+
)
|
|
153
|
+
scale_arg = (
|
|
154
|
+
f" --delivery-batch-scale {shell_arg_or_placeholder(delivery_batch_scale)}"
|
|
155
|
+
if delivery_batch_scale
|
|
156
|
+
else ""
|
|
157
|
+
)
|
|
158
|
+
outcome_arg = (
|
|
159
|
+
f" --delivery-outcome {shell_arg_or_placeholder(delivery_outcome)}"
|
|
160
|
+
if delivery_outcome
|
|
161
|
+
else ""
|
|
162
|
+
)
|
|
163
|
+
return (
|
|
164
|
+
f"{shell_arg(cli_bin)} refresh-state --goal-id {shell_arg(goal_id)}"
|
|
165
|
+
f"{project_arg}{classification_arg}{scale_arg}{outcome_arg}{agent_arg}{scope_arg}"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def render_accountable_progress_refresh_command(
|
|
170
|
+
goal_id: str,
|
|
171
|
+
*,
|
|
172
|
+
cli_bin: str = "loopx",
|
|
173
|
+
agent_id: str | None = None,
|
|
174
|
+
progress_scope: str | None = None,
|
|
175
|
+
classification: str = "<PUBLIC_SAFE_PROGRESS_CLASSIFICATION>",
|
|
176
|
+
delivery_batch_scale: str = "<ACTUAL_DELIVERY_BATCH_SCALE>",
|
|
177
|
+
delivery_outcome: str = "<ACTUAL_DELIVERY_OUTCOME>",
|
|
178
|
+
) -> str:
|
|
179
|
+
return render_refresh_state_command(
|
|
180
|
+
goal_id,
|
|
181
|
+
cli_bin=cli_bin,
|
|
182
|
+
agent_id=agent_id,
|
|
183
|
+
progress_scope=progress_scope,
|
|
184
|
+
classification=classification,
|
|
185
|
+
delivery_batch_scale=delivery_batch_scale,
|
|
186
|
+
delivery_outcome=delivery_outcome,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def render_heartbeat_prompt_command(
|
|
191
|
+
goal_id: str,
|
|
192
|
+
*,
|
|
193
|
+
cli_bin: str = "loopx",
|
|
194
|
+
agent_id: str | None = None,
|
|
195
|
+
agent_scope: str = "Codex CLI /goal visible TUI loop",
|
|
196
|
+
body: str = "thin",
|
|
197
|
+
available_capabilities: Any = None,
|
|
198
|
+
runtime_profile: str | None = None,
|
|
199
|
+
scheduler_execution_context: dict[str, Any] | None = None,
|
|
200
|
+
visible_goal_host: str | None = None,
|
|
201
|
+
) -> str:
|
|
202
|
+
agent_arg = f" --agent-id {shell_arg(agent_id)}" if agent_id else ""
|
|
203
|
+
scope_arg = f" --agent-scope {shell_arg(agent_scope)}" if agent_id else ""
|
|
204
|
+
capability_args = render_available_capability_args(available_capabilities)
|
|
205
|
+
scheduler_args = render_scheduler_execution_args(
|
|
206
|
+
runtime_profile=runtime_profile,
|
|
207
|
+
scheduler_execution_context=scheduler_execution_context,
|
|
208
|
+
)
|
|
209
|
+
visible_goal_arg = (
|
|
210
|
+
f" --visible-goal-host {shell_arg(visible_goal_host)}"
|
|
211
|
+
if visible_goal_host
|
|
212
|
+
else ""
|
|
213
|
+
)
|
|
214
|
+
return (
|
|
215
|
+
f"{shell_arg(cli_bin)} heartbeat-prompt --{shell_arg(body)} "
|
|
216
|
+
f"--goal-id {shell_arg(goal_id)}{agent_arg}{scope_arg}{capability_args}"
|
|
217
|
+
f"{scheduler_args}{visible_goal_arg}"
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def render_heartbeat_prompt_json_command(
|
|
222
|
+
goal_id: str,
|
|
223
|
+
*,
|
|
224
|
+
cli_bin: str = "loopx",
|
|
225
|
+
agent_id: str | None = None,
|
|
226
|
+
agent_scope: str = "Codex CLI /goal visible TUI loop",
|
|
227
|
+
body: str = "thin",
|
|
228
|
+
available_capabilities: Any = None,
|
|
229
|
+
runtime_profile: str | None = None,
|
|
230
|
+
scheduler_execution_context: dict[str, Any] | None = None,
|
|
231
|
+
visible_goal_host: str | None = None,
|
|
232
|
+
) -> str:
|
|
233
|
+
agent_arg = f" --agent-id {shell_arg(agent_id)}" if agent_id else ""
|
|
234
|
+
scope_arg = f" --agent-scope {shell_arg(agent_scope)}" if agent_id else ""
|
|
235
|
+
capability_args = render_available_capability_args(available_capabilities)
|
|
236
|
+
scheduler_args = render_scheduler_execution_args(
|
|
237
|
+
runtime_profile=runtime_profile,
|
|
238
|
+
scheduler_execution_context=scheduler_execution_context,
|
|
239
|
+
)
|
|
240
|
+
visible_goal_arg = (
|
|
241
|
+
f" --visible-goal-host {shell_arg(visible_goal_host)}"
|
|
242
|
+
if visible_goal_host
|
|
243
|
+
else ""
|
|
244
|
+
)
|
|
245
|
+
return (
|
|
246
|
+
f"{shell_arg(cli_bin)} --format json heartbeat-prompt --{shell_arg(body)} "
|
|
247
|
+
f"--goal-id {shell_arg(goal_id)}{agent_arg}{scope_arg}{capability_args}"
|
|
248
|
+
f"{scheduler_args}{visible_goal_arg}"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def render_connect_command(
|
|
253
|
+
*,
|
|
254
|
+
project: str,
|
|
255
|
+
goal_doc: str,
|
|
256
|
+
goal_id: str,
|
|
257
|
+
objective: str,
|
|
258
|
+
domain: str,
|
|
259
|
+
adapter_kind: str,
|
|
260
|
+
adapter_status: str,
|
|
261
|
+
next_probe: str | None,
|
|
262
|
+
spawn_allowed: bool,
|
|
263
|
+
allowed_domains: list[str],
|
|
264
|
+
write_scope: list[str],
|
|
265
|
+
cli_bin: str = "loopx",
|
|
266
|
+
) -> str:
|
|
267
|
+
lines = [
|
|
268
|
+
f"cd {shell_arg(project)}",
|
|
269
|
+
f"{shell_arg(cli_bin)} connect \\",
|
|
270
|
+
f" --goal-id {shell_arg(goal_id)} \\",
|
|
271
|
+
f" --objective {shell_arg(objective)} \\",
|
|
272
|
+
f" --domain {shell_arg(domain)} \\",
|
|
273
|
+
f" --goal-doc {shell_arg(goal_doc)} \\",
|
|
274
|
+
f" --adapter-kind {shell_arg(adapter_kind)} \\",
|
|
275
|
+
f" --adapter-status {shell_arg(adapter_status)}",
|
|
276
|
+
]
|
|
277
|
+
if next_probe:
|
|
278
|
+
lines[-1] += " \\"
|
|
279
|
+
lines.append(f" --next-probe {shell_arg(next_probe)}")
|
|
280
|
+
if spawn_allowed:
|
|
281
|
+
lines[-1] += " \\"
|
|
282
|
+
lines.append(" --spawn-allowed")
|
|
283
|
+
for allowed_domain in allowed_domains:
|
|
284
|
+
lines[-1] += " \\"
|
|
285
|
+
lines.append(f" --allowed-domain {shell_arg(allowed_domain)}")
|
|
286
|
+
for scope in write_scope:
|
|
287
|
+
lines[-1] += " \\"
|
|
288
|
+
lines.append(f" --write-scope {shell_arg(scope)}")
|
|
289
|
+
return "\n".join(lines)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def build_new_project_prompt(
|
|
293
|
+
*,
|
|
294
|
+
project: Path,
|
|
295
|
+
goal_doc: Path,
|
|
296
|
+
goal_id: str | None,
|
|
297
|
+
objective: str | None,
|
|
298
|
+
domain: str | None,
|
|
299
|
+
adapter_kind: str,
|
|
300
|
+
adapter_status: str,
|
|
301
|
+
next_probe: str | None,
|
|
302
|
+
spawn_allowed: bool,
|
|
303
|
+
allowed_domains: list[str] | None,
|
|
304
|
+
write_scope: list[str] | None,
|
|
305
|
+
) -> dict[str, Any]:
|
|
306
|
+
project_text = str(project.expanduser())
|
|
307
|
+
goal_doc_text = str(goal_doc.expanduser())
|
|
308
|
+
resolved_goal_id = goal_id or default_goal_id(project)
|
|
309
|
+
resolved_objective = objective or DEFAULT_HANDOFF_OBJECTIVE
|
|
310
|
+
resolved_domain = domain or DEFAULT_HANDOFF_DOMAIN
|
|
311
|
+
resolved_next_probe = next_probe or DEFAULT_HANDOFF_NEXT_PROBE
|
|
312
|
+
allowed_domains = allowed_domains or []
|
|
313
|
+
write_scope = write_scope or []
|
|
314
|
+
connect_command = render_connect_command(
|
|
315
|
+
project=project_text,
|
|
316
|
+
goal_doc=goal_doc_text,
|
|
317
|
+
goal_id=resolved_goal_id,
|
|
318
|
+
objective=resolved_objective,
|
|
319
|
+
domain=resolved_domain,
|
|
320
|
+
adapter_kind=adapter_kind,
|
|
321
|
+
adapter_status=adapter_status,
|
|
322
|
+
next_probe=next_probe,
|
|
323
|
+
spawn_allowed=spawn_allowed,
|
|
324
|
+
allowed_domains=allowed_domains,
|
|
325
|
+
write_scope=write_scope,
|
|
326
|
+
cli_bin="loopx",
|
|
327
|
+
)
|
|
328
|
+
quota_guard_command = render_quota_guard_command(
|
|
329
|
+
resolved_goal_id,
|
|
330
|
+
scheduler_execution_context=(
|
|
331
|
+
GENERIC_CLI_OUTER_CONTROLLER_SCHEDULER_CONTEXT
|
|
332
|
+
),
|
|
333
|
+
)
|
|
334
|
+
quota_spend_command = render_quota_spend_command(resolved_goal_id)
|
|
335
|
+
refresh_command = render_refresh_state_command(resolved_goal_id)
|
|
336
|
+
progress_refresh_command = render_accountable_progress_refresh_command(
|
|
337
|
+
resolved_goal_id
|
|
338
|
+
)
|
|
339
|
+
prompt = render_prompt_text(
|
|
340
|
+
project=project_text,
|
|
341
|
+
goal_doc=goal_doc_text,
|
|
342
|
+
goal_id=resolved_goal_id,
|
|
343
|
+
objective=resolved_objective,
|
|
344
|
+
domain=resolved_domain,
|
|
345
|
+
adapter_kind=adapter_kind,
|
|
346
|
+
adapter_status=adapter_status,
|
|
347
|
+
next_probe=resolved_next_probe,
|
|
348
|
+
cli_preflight=render_cli_preflight(),
|
|
349
|
+
connect_command=connect_command,
|
|
350
|
+
quota_guard_command=quota_guard_command,
|
|
351
|
+
quota_spend_command=quota_spend_command,
|
|
352
|
+
refresh_command=refresh_command,
|
|
353
|
+
progress_refresh_command=progress_refresh_command,
|
|
354
|
+
cli_bin="loopx",
|
|
355
|
+
spawn_allowed=spawn_allowed,
|
|
356
|
+
allowed_domains=allowed_domains,
|
|
357
|
+
write_scope=write_scope,
|
|
358
|
+
)
|
|
359
|
+
return {
|
|
360
|
+
"ok": True,
|
|
361
|
+
"project": project_text,
|
|
362
|
+
"goal_doc": goal_doc_text,
|
|
363
|
+
"goal_id": resolved_goal_id,
|
|
364
|
+
"objective": resolved_objective,
|
|
365
|
+
"domain": resolved_domain,
|
|
366
|
+
"adapter_kind": adapter_kind,
|
|
367
|
+
"adapter_status": adapter_status,
|
|
368
|
+
"next_probe": resolved_next_probe,
|
|
369
|
+
"spawn_allowed": spawn_allowed,
|
|
370
|
+
"allowed_domains": allowed_domains,
|
|
371
|
+
"write_scope": write_scope,
|
|
372
|
+
"connect_command": connect_command,
|
|
373
|
+
"quota_guard_command": quota_guard_command,
|
|
374
|
+
"quota_spend_command": quota_spend_command,
|
|
375
|
+
"refresh_command": refresh_command,
|
|
376
|
+
"progress_refresh_command": progress_refresh_command,
|
|
377
|
+
"cli_preflight": render_cli_preflight(),
|
|
378
|
+
"prompt": prompt,
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def render_codex_cli_bootstrap_connect_command(
|
|
383
|
+
*,
|
|
384
|
+
project: str,
|
|
385
|
+
goal_id: str,
|
|
386
|
+
cli_bin: str,
|
|
387
|
+
) -> str:
|
|
388
|
+
return "\n".join(
|
|
389
|
+
[
|
|
390
|
+
f"cd {shell_arg(project)}",
|
|
391
|
+
f"{shell_arg(cli_bin)} bootstrap \\",
|
|
392
|
+
" --project . \\",
|
|
393
|
+
f" --goal-id {shell_arg(goal_id)} \\",
|
|
394
|
+
f" --adapter-kind {shell_arg(DEFAULT_HANDOFF_ADAPTER_KIND)} \\",
|
|
395
|
+
f" --adapter-status {shell_arg(DEFAULT_HANDOFF_ADAPTER_STATUS)}",
|
|
396
|
+
]
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def build_codex_cli_bootstrap_message(
|
|
401
|
+
*,
|
|
402
|
+
project: Path,
|
|
403
|
+
goal_id: str | None,
|
|
404
|
+
agent_id: str | None,
|
|
405
|
+
cli_bin: str,
|
|
406
|
+
) -> dict[str, Any]:
|
|
407
|
+
resolved_project = str(project.expanduser())
|
|
408
|
+
resolved_goal_id = goal_id or default_goal_id(project)
|
|
409
|
+
connect_command = render_codex_cli_bootstrap_connect_command(
|
|
410
|
+
project=resolved_project,
|
|
411
|
+
goal_id=resolved_goal_id,
|
|
412
|
+
cli_bin=cli_bin,
|
|
413
|
+
)
|
|
414
|
+
quota_guard_command = render_quota_guard_command(
|
|
415
|
+
resolved_goal_id,
|
|
416
|
+
cli_bin=cli_bin,
|
|
417
|
+
agent_id=agent_id,
|
|
418
|
+
scheduler_execution_context=CODEX_CLI_VISIBLE_SCHEDULER_CONTEXT,
|
|
419
|
+
)
|
|
420
|
+
quota_spend_command = render_quota_spend_command(
|
|
421
|
+
resolved_goal_id,
|
|
422
|
+
source="heartbeat",
|
|
423
|
+
cli_bin=cli_bin,
|
|
424
|
+
agent_id=agent_id,
|
|
425
|
+
)
|
|
426
|
+
heartbeat_prompt_command = render_heartbeat_prompt_command(
|
|
427
|
+
resolved_goal_id,
|
|
428
|
+
cli_bin=cli_bin,
|
|
429
|
+
agent_id=agent_id,
|
|
430
|
+
scheduler_execution_context=CODEX_CLI_VISIBLE_SCHEDULER_CONTEXT,
|
|
431
|
+
)
|
|
432
|
+
heartbeat_prompt_json_command = render_heartbeat_prompt_json_command(
|
|
433
|
+
resolved_goal_id,
|
|
434
|
+
cli_bin=cli_bin,
|
|
435
|
+
agent_id=agent_id,
|
|
436
|
+
scheduler_execution_context=CODEX_CLI_VISIBLE_SCHEDULER_CONTEXT,
|
|
437
|
+
)
|
|
438
|
+
install_repair_command = render_codex_cli_no_clone_preflight(cli_bin=cli_bin)
|
|
439
|
+
refresh_command = render_refresh_state_command(
|
|
440
|
+
resolved_goal_id,
|
|
441
|
+
cli_bin=cli_bin,
|
|
442
|
+
agent_id=agent_id,
|
|
443
|
+
progress_scope="agent_lane" if agent_id else None,
|
|
444
|
+
)
|
|
445
|
+
progress_refresh_command = render_accountable_progress_refresh_command(
|
|
446
|
+
resolved_goal_id,
|
|
447
|
+
cli_bin=cli_bin,
|
|
448
|
+
agent_id=agent_id,
|
|
449
|
+
progress_scope="agent_lane" if agent_id else None,
|
|
450
|
+
)
|
|
451
|
+
first_run_validation_checklist = [
|
|
452
|
+
f"{cli_bin} doctor passed after no-clone install repair or existing install",
|
|
453
|
+
"repo bootstrap/connect completed conservatively or a concrete install/connect blocker was shown",
|
|
454
|
+
f"thin heartbeat task_body generated from {cli_bin} heartbeat-prompt --thin, not hand-written",
|
|
455
|
+
"host loop surface activated from the thin task_body: Codex CLI /goal or Codex App heartbeat automation initially every 3 minutes, then following quota scheduler_hint",
|
|
456
|
+
"setup was not reported complete from registry/quota identity alone; missing host-loop mutation was reported as a concrete gate",
|
|
457
|
+
"quota/status guard checked with the registered agent id when available after bootstrap/connect",
|
|
458
|
+
"current goal, concrete user gate or none, top todos, and next safe action shown in the TUI",
|
|
459
|
+
"no raw Codex transcripts, session files, credentials, private paths, stdout, or stderr persisted",
|
|
460
|
+
]
|
|
461
|
+
message = render_codex_cli_bootstrap_message_text(
|
|
462
|
+
project=resolved_project,
|
|
463
|
+
goal_id=resolved_goal_id,
|
|
464
|
+
agent_id=agent_id,
|
|
465
|
+
cli_preflight=install_repair_command,
|
|
466
|
+
existing_goal_probe_command=quota_guard_command,
|
|
467
|
+
connect_command=connect_command,
|
|
468
|
+
heartbeat_prompt_json_command=heartbeat_prompt_json_command,
|
|
469
|
+
heartbeat_prompt_command=heartbeat_prompt_command,
|
|
470
|
+
quota_guard_command=quota_guard_command,
|
|
471
|
+
refresh_command=refresh_command,
|
|
472
|
+
progress_refresh_command=progress_refresh_command,
|
|
473
|
+
quota_spend_command=quota_spend_command,
|
|
474
|
+
first_run_validation_checklist=first_run_validation_checklist,
|
|
475
|
+
)
|
|
476
|
+
return {
|
|
477
|
+
"ok": True,
|
|
478
|
+
"schema_version": "codex_cli_bootstrap_message_v1",
|
|
479
|
+
"invocation_mode": "codex_cli_setup_then_goal_mode",
|
|
480
|
+
"project": resolved_project,
|
|
481
|
+
"goal_id": resolved_goal_id,
|
|
482
|
+
"agent_id": agent_id,
|
|
483
|
+
"cli_bin": cli_bin,
|
|
484
|
+
"install_repair_command": install_repair_command,
|
|
485
|
+
"existing_goal_probe_command": quota_guard_command,
|
|
486
|
+
"connect_command": connect_command,
|
|
487
|
+
"heartbeat_prompt_command": heartbeat_prompt_command,
|
|
488
|
+
"heartbeat_prompt_json_command": heartbeat_prompt_json_command,
|
|
489
|
+
"codex_cli_goal_prefix": "/goal ",
|
|
490
|
+
"codex_app_loop_surface": "heartbeat automation task_body",
|
|
491
|
+
"codex_app_default_heartbeat_cadence": "initially 3 minutes, then follow quota scheduler_hint",
|
|
492
|
+
"quota_guard_command": quota_guard_command,
|
|
493
|
+
"refresh_command": refresh_command,
|
|
494
|
+
"progress_refresh_command": progress_refresh_command,
|
|
495
|
+
"quota_spend_command": quota_spend_command,
|
|
496
|
+
"first_run_validation_checklist": first_run_validation_checklist,
|
|
497
|
+
"message": message,
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
def build_codex_cli_tui_bootstrap_smoke_bundle(
|
|
502
|
+
*,
|
|
503
|
+
project: Path,
|
|
504
|
+
goal_id: str | None,
|
|
505
|
+
agent_id: str | None,
|
|
506
|
+
cli_bin: str,
|
|
507
|
+
) -> dict[str, Any]:
|
|
508
|
+
bootstrap = build_codex_cli_bootstrap_message(
|
|
509
|
+
project=project,
|
|
510
|
+
goal_id=goal_id,
|
|
511
|
+
agent_id=agent_id,
|
|
512
|
+
cli_bin=cli_bin,
|
|
513
|
+
)
|
|
514
|
+
resolved_project = str(bootstrap["project"])
|
|
515
|
+
resolved_goal_id = str(bootstrap["goal_id"])
|
|
516
|
+
agent_arg = f" --agent-id {shell_arg(agent_id)}" if agent_id else ""
|
|
517
|
+
message_only_command = (
|
|
518
|
+
f"{shell_arg(cli_bin)} codex-cli-bootstrap-message "
|
|
519
|
+
f"--project {shell_arg(resolved_project)} "
|
|
520
|
+
f"--goal-id {shell_arg(resolved_goal_id)}{agent_arg} --message-only"
|
|
521
|
+
)
|
|
522
|
+
review_packet_command = (
|
|
523
|
+
f"{shell_arg(cli_bin)} codex-cli-bootstrap-message "
|
|
524
|
+
f"--project {shell_arg(resolved_project)} "
|
|
525
|
+
f"--goal-id {shell_arg(resolved_goal_id)}{agent_arg}"
|
|
526
|
+
)
|
|
527
|
+
boundary = {
|
|
528
|
+
"runs_codex": False,
|
|
529
|
+
"reads_raw_transcripts": False,
|
|
530
|
+
"reads_session_files": False,
|
|
531
|
+
"reads_credentials": False,
|
|
532
|
+
"mutates_codex_session": False,
|
|
533
|
+
"spends_loopx_quota": False,
|
|
534
|
+
"requires_loopx_repo_clone": False,
|
|
535
|
+
}
|
|
536
|
+
validation_checklist = [
|
|
537
|
+
"archive installer works from a temporary GitHub-style tarball or existing install",
|
|
538
|
+
"message-only command prints only the setup paste block, not the Markdown review packet",
|
|
539
|
+
"paste block includes no-clone install repair, project bootstrap/connect, thin heartbeat generation, loop activation, and quota guard",
|
|
540
|
+
"accountable progress refresh then quota spend remain later post-delivery commands inside the paste block, not setup or smoke side effects",
|
|
541
|
+
"no raw Codex transcripts, session files, credentials, stdout, stderr, or private paths are read",
|
|
542
|
+
]
|
|
543
|
+
return {
|
|
544
|
+
"ok": True,
|
|
545
|
+
"schema_version": "codex_cli_tui_bootstrap_smoke_bundle_v0",
|
|
546
|
+
"project": resolved_project,
|
|
547
|
+
"goal_id": resolved_goal_id,
|
|
548
|
+
"agent_id": agent_id,
|
|
549
|
+
"cli_bin": cli_bin,
|
|
550
|
+
"install_repair_command": bootstrap["install_repair_command"],
|
|
551
|
+
"review_packet_command": review_packet_command,
|
|
552
|
+
"message_only_command": message_only_command,
|
|
553
|
+
"heartbeat_prompt_command": bootstrap["heartbeat_prompt_command"],
|
|
554
|
+
"heartbeat_prompt_json_command": bootstrap["heartbeat_prompt_json_command"],
|
|
555
|
+
"quota_guard_command": bootstrap["quota_guard_command"],
|
|
556
|
+
"refresh_command": bootstrap["refresh_command"],
|
|
557
|
+
"progress_refresh_command": bootstrap["progress_refresh_command"],
|
|
558
|
+
"quota_spend_command": bootstrap["quota_spend_command"],
|
|
559
|
+
"validation_checklist": validation_checklist,
|
|
560
|
+
"boundary": boundary,
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
def build_codex_cli_exec_handoff(
|
|
565
|
+
*,
|
|
566
|
+
project: Path,
|
|
567
|
+
goal_id: str | None,
|
|
568
|
+
agent_id: str | None,
|
|
569
|
+
cli_bin: str,
|
|
570
|
+
codex_bin: str,
|
|
571
|
+
) -> dict[str, Any]:
|
|
572
|
+
bootstrap = build_codex_cli_bootstrap_message(
|
|
573
|
+
project=project,
|
|
574
|
+
goal_id=goal_id,
|
|
575
|
+
agent_id=agent_id,
|
|
576
|
+
cli_bin=cli_bin,
|
|
577
|
+
)
|
|
578
|
+
resolved_project = str(project.expanduser())
|
|
579
|
+
resolved_goal_id = str(bootstrap["goal_id"])
|
|
580
|
+
agent_arg = f" --agent-id {shell_arg(agent_id)}" if agent_id else ""
|
|
581
|
+
message_only_command = (
|
|
582
|
+
f"{shell_arg(cli_bin)} codex-cli-bootstrap-message "
|
|
583
|
+
f"--project {shell_arg(resolved_project)} "
|
|
584
|
+
f"--goal-id {shell_arg(resolved_goal_id)}{agent_arg} --message-only"
|
|
585
|
+
)
|
|
586
|
+
return {
|
|
587
|
+
"ok": True,
|
|
588
|
+
"schema_version": "codex_cli_exec_handoff_v0",
|
|
589
|
+
"mode": "headless_fallback_disabled_for_goal_mode_bootstrap",
|
|
590
|
+
"primary_experience": "codex_cli_tui_goal_bootstrap",
|
|
591
|
+
"project": resolved_project,
|
|
592
|
+
"goal_id": resolved_goal_id,
|
|
593
|
+
"agent_id": agent_id,
|
|
594
|
+
"cli_bin": cli_bin,
|
|
595
|
+
"codex_bin": codex_bin,
|
|
596
|
+
"disabled_reason": (
|
|
597
|
+
"Default Codex CLI LoopX bootstrap must stay visible in the TUI; "
|
|
598
|
+
"headless codex exec handoff is disabled to avoid accidental hidden execution."
|
|
599
|
+
),
|
|
600
|
+
"session_probe_command": f"{shell_arg(cli_bin)} codex-cli-session-probe --codex-bin {shell_arg(codex_bin)}",
|
|
601
|
+
"quota_guard_command": bootstrap["quota_guard_command"],
|
|
602
|
+
"progress_refresh_command": bootstrap["progress_refresh_command"],
|
|
603
|
+
"refresh_command": bootstrap["refresh_command"],
|
|
604
|
+
"quota_spend_command": bootstrap["quota_spend_command"],
|
|
605
|
+
"heartbeat_prompt_json_command": bootstrap["heartbeat_prompt_json_command"],
|
|
606
|
+
"message_only_command": message_only_command,
|
|
607
|
+
"handoff_command": "",
|
|
608
|
+
"boundary": {
|
|
609
|
+
"runs_codex": False,
|
|
610
|
+
"reads_raw_transcripts": False,
|
|
611
|
+
"reads_credentials": False,
|
|
612
|
+
"reads_session_files": False,
|
|
613
|
+
"mutates_codex_session": False,
|
|
614
|
+
"spends_loopx_quota": False,
|
|
615
|
+
"headless_execution_disabled": True,
|
|
616
|
+
"provides_executable_headless_command": False,
|
|
617
|
+
},
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
def render_codex_cli_bootstrap_message_text(
|
|
622
|
+
*,
|
|
623
|
+
project: str,
|
|
624
|
+
goal_id: str,
|
|
625
|
+
agent_id: str | None,
|
|
626
|
+
cli_preflight: str,
|
|
627
|
+
existing_goal_probe_command: str,
|
|
628
|
+
connect_command: str,
|
|
629
|
+
heartbeat_prompt_json_command: str,
|
|
630
|
+
heartbeat_prompt_command: str,
|
|
631
|
+
quota_guard_command: str,
|
|
632
|
+
refresh_command: str,
|
|
633
|
+
progress_refresh_command: str,
|
|
634
|
+
quota_spend_command: str,
|
|
635
|
+
first_run_validation_checklist: list[str],
|
|
636
|
+
) -> str:
|
|
637
|
+
agent_line = f"Use registered LoopX agent id `{agent_id}` when claiming or spending." if agent_id else (
|
|
638
|
+
"If this project has registered agents, inspect the registry and use the correct registered agent id before claiming todos."
|
|
639
|
+
)
|
|
640
|
+
checklist = "\n".join(f"- {item}" for item in first_run_validation_checklist)
|
|
641
|
+
return f"""Install and connect LoopX for this repo from this same Codex CLI TUI session.
|
|
642
|
+
|
|
643
|
+
Goal: one-message setup, then loop activation. Keep this TUI as the visible
|
|
644
|
+
place where I can watch, steer, review, and take over. Do not use hidden
|
|
645
|
+
headless `codex exec` for this bootstrap path.
|
|
646
|
+
|
|
647
|
+
This first message is the setup/bootstrap instruction, not the reusable
|
|
648
|
+
heartbeat prompt. Complete the setup in order: install or repair LoopX
|
|
649
|
+
if needed; probe whether this goal already exists in the shared global
|
|
650
|
+
registry; only bootstrap/connect this project when the goal is absent; then
|
|
651
|
+
configure the current loop surface from the generated thin heartbeat prompt.
|
|
652
|
+
For Codex CLI, set the current TUI goal to `/goal ` plus the thin `task_body`.
|
|
653
|
+
For Codex App, set or refresh the heartbeat automation to start at 3 minutes
|
|
654
|
+
with that same thin `task_body`, then follow quota `scheduler_hint` for
|
|
655
|
+
backoff. If the current surface cannot be mutated from this session, show the
|
|
656
|
+
exact pasteable `/goal` or automation body and report that as a concrete user
|
|
657
|
+
gate; do not claim setup success.
|
|
658
|
+
|
|
659
|
+
Project: `{project}`
|
|
660
|
+
Goal id: `{goal_id}`
|
|
661
|
+
{agent_line}
|
|
662
|
+
|
|
663
|
+
Success criteria for this first setup turn:
|
|
664
|
+
- I should not need to inspect registry paths, runtime roots, JSON payloads, or
|
|
665
|
+
hidden session files.
|
|
666
|
+
- If LoopX is already installed and this goal is already present in the shared
|
|
667
|
+
global registry, reuse the existing `source_registry` route and do not
|
|
668
|
+
duplicate bootstrap from this worktree.
|
|
669
|
+
- Configure the loop target after bootstrap: Codex CLI `/goal <thin task_body>`
|
|
670
|
+
or Codex App heartbeat automation starting at 3 minutes with
|
|
671
|
+
`<thin task_body>`, then follow quota `scheduler_hint`.
|
|
672
|
+
- Do not claim setup success from registry/quota identity alone. Setup is
|
|
673
|
+
complete only when the host loop surface is active, or when you report the
|
|
674
|
+
exact host-tool gate that prevented setting Codex CLI `/goal` or creating the
|
|
675
|
+
Codex App heartbeat automation.
|
|
676
|
+
- Show me the current goal id, concrete user gate if any, top user todo if any,
|
|
677
|
+
top agent todo, and next safe action.
|
|
678
|
+
- Do not do longer delivery work in the setup turn unless I explicitly ask; the
|
|
679
|
+
configured thin loop owns later quota/spend delivery turns.
|
|
680
|
+
|
|
681
|
+
1. Ensure the LoopX CLI works. Prefer the no-clone GitHub archive
|
|
682
|
+
installer; do not ask me to clone the LoopX repo just to try the first
|
|
683
|
+
run:
|
|
684
|
+
|
|
685
|
+
```bash
|
|
686
|
+
{cli_preflight}
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
2. Before bootstrap/connect, probe the shared global registry for this goal:
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
{existing_goal_probe_command}
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
If this command returns a known goal, even with a normal delivery gate or
|
|
696
|
+
workspace guard, treat the goal as already connected and reuse the existing
|
|
697
|
+
global route/source_registry. In an independent peer-agent worktree, do not
|
|
698
|
+
run `loopx bootstrap` for the same `goal_id`; that can create a route collision
|
|
699
|
+
between the primary checkout and the worktree. Only run bootstrap when the
|
|
700
|
+
probe clearly says the goal is absent from the registered quota plan.
|
|
701
|
+
|
|
702
|
+
3. If the goal is absent and this repo is not connected to LoopX yet, connect
|
|
703
|
+
it conservatively:
|
|
704
|
+
|
|
705
|
+
```bash
|
|
706
|
+
{connect_command}
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
If the connect output includes onboarding candidate todos, summarize them in
|
|
710
|
+
this TUI and ask me which ones to accept before starting autonomous delivery.
|
|
711
|
+
|
|
712
|
+
4. Generate the thin loop prompt after route reuse or bootstrap/connect, not before. Do not
|
|
713
|
+
hand-write or copy an old heartbeat body:
|
|
714
|
+
|
|
715
|
+
```bash
|
|
716
|
+
{heartbeat_prompt_json_command}
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
Read `task_body` from the JSON result. Then configure the current surface:
|
|
720
|
+
- Codex CLI TUI: set the current goal to `/goal ` followed by that `task_body`.
|
|
721
|
+
- Codex App: create or update the heartbeat automation to start at 3 minutes
|
|
722
|
+
with that `task_body`, then follow quota `scheduler_hint`. If this session
|
|
723
|
+
cannot mutate Codex App automations, report that exact gate and do not say
|
|
724
|
+
LoopX automation is enabled.
|
|
725
|
+
|
|
726
|
+
For review, the Markdown form is:
|
|
727
|
+
|
|
728
|
+
```bash
|
|
729
|
+
{heartbeat_prompt_command}
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
5. After install/connect and loop activation, run the quota/status guard for
|
|
733
|
+
the first control-plane snapshot:
|
|
734
|
+
|
|
735
|
+
```bash
|
|
736
|
+
{quota_guard_command}
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
Follow `interaction_contract` exactly:
|
|
740
|
+
- If `user_channel.action_required=true` or open user todos exist, ask only the
|
|
741
|
+
concrete user gate or todo payload.
|
|
742
|
+
- If `workspace_guard` blocks delivery, move to an independent worktree and
|
|
743
|
+
rerun the same guard before editing.
|
|
744
|
+
- If delivery is allowed, choose one runnable agent todo after a short steering
|
|
745
|
+
audit, preferably a current-agent claimed advancement todo.
|
|
746
|
+
|
|
747
|
+
6. Report the current goal/gate/todo/next-action snapshot in this TUI. Stop
|
|
748
|
+
after setup unless I explicitly asked for delivery in this same turn. Do not
|
|
749
|
+
store raw Codex transcripts, credentials, private paths, raw logs, or
|
|
750
|
+
production artifacts in public docs or LoopX state.
|
|
751
|
+
|
|
752
|
+
7. Before writeback, use this transcript-free validation checklist:
|
|
753
|
+
|
|
754
|
+
{checklist}
|
|
755
|
+
|
|
756
|
+
8. After setup writeback, refresh state if needed. Do not spend quota for a
|
|
757
|
+
setup-only turn. The configured thin loop spends only after a later validated
|
|
758
|
+
delivery writeback. If I explicitly asked you to do delivery in this same turn
|
|
759
|
+
and you completed a validated delivery segment, replace all three placeholders
|
|
760
|
+
with this turn's actual validated classification, batch scale, and outcome.
|
|
761
|
+
Never default or upgrade them to `multi_surface` / `outcome_progress`. Then write
|
|
762
|
+
one accountable progress refresh and spend exactly once against that record:
|
|
763
|
+
|
|
764
|
+
```bash
|
|
765
|
+
{progress_refresh_command}
|
|
766
|
+
{quota_spend_command}
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
If the dashboard or controller needs another update after spend, run the plain
|
|
770
|
+
state-only refresh below. It is quota-neutral and must not carry a delivery
|
|
771
|
+
outcome:
|
|
772
|
+
|
|
773
|
+
```bash
|
|
774
|
+
{refresh_command}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
Do not append another accountable progress refresh after spend; it would become
|
|
778
|
+
a new unspent delivery record.
|
|
779
|
+
|
|
780
|
+
End with changed files, validation result, current gate/todo state, and next
|
|
781
|
+
safe action. Later automation may add visible steering turns to this session
|
|
782
|
+
only after public-safe visible proof, runtime idle evidence, a fresh guard, and
|
|
783
|
+
explicit execution bounds. Keep optional automation checks such as
|
|
784
|
+
local-driver-plan or visible-session-proof as follow-up diagnostics, not
|
|
785
|
+
first-run prerequisites.
|
|
786
|
+
"""
|
|
787
|
+
|
|
788
|
+
def render_prompt_text(
|
|
789
|
+
*,
|
|
790
|
+
project: str,
|
|
791
|
+
goal_doc: str,
|
|
792
|
+
goal_id: str,
|
|
793
|
+
objective: str,
|
|
794
|
+
domain: str,
|
|
795
|
+
adapter_kind: str,
|
|
796
|
+
adapter_status: str,
|
|
797
|
+
next_probe: str,
|
|
798
|
+
cli_preflight: str,
|
|
799
|
+
connect_command: str,
|
|
800
|
+
quota_guard_command: str,
|
|
801
|
+
quota_spend_command: str,
|
|
802
|
+
refresh_command: str,
|
|
803
|
+
progress_refresh_command: str,
|
|
804
|
+
cli_bin: str,
|
|
805
|
+
spawn_allowed: bool,
|
|
806
|
+
allowed_domains: list[str],
|
|
807
|
+
write_scope: list[str],
|
|
808
|
+
) -> str:
|
|
809
|
+
spawn_note = "本项目初始不需要主控拆 sub-agent;除非目标文档另有授权,先保持单 controller read-only 接入。"
|
|
810
|
+
if spawn_allowed:
|
|
811
|
+
spawn_note = (
|
|
812
|
+
"本项目允许主控拆 sub-agent;子 agent 只能进入已声明 allowed-domain,"
|
|
813
|
+
"写入范围只能落在已声明 write-scope。"
|
|
814
|
+
)
|
|
815
|
+
allowed_domains_text = ", ".join(allowed_domains) if allowed_domains else "(none)"
|
|
816
|
+
write_scope_text = ", ".join(write_scope) if write_scope else "(none)"
|
|
817
|
+
return f"""我有一个新项目要接入 LoopX。
|
|
818
|
+
|
|
819
|
+
项目文件夹:
|
|
820
|
+
{project}
|
|
821
|
+
|
|
822
|
+
项目目标文档:
|
|
823
|
+
{goal_doc}
|
|
824
|
+
|
|
825
|
+
请你按下面步骤推进,不要停在方案讨论;如果信息缺失,先从目标文档和项目结构中做保守抽取,并在最后说明假设。
|
|
826
|
+
重要:`{cli_bin} connect` 默认会做一次快速 onboarding scan,基于 git status、最近 commit、顶层项目信号生成候选 agent todo。
|
|
827
|
+
接入后不要直接开始 delivery;先把候选 todo 展示给我,并问我两件事:
|
|
828
|
+
1. 接受、编辑或拒绝哪些候选 agent todo;
|
|
829
|
+
2. 是否允许你从接受的 todo 开始自主推进。
|
|
830
|
+
|
|
831
|
+
0. 先确认当前 shell 能调用 LoopX CLI;如果提示 `loopx` 不在 PATH,运行本机安装脚本再继续:
|
|
832
|
+
|
|
833
|
+
```bash
|
|
834
|
+
{cli_preflight}
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
1. 再只读检查项目文件夹和目标文档,抽取:
|
|
838
|
+
- stable goal id;
|
|
839
|
+
- 一句话 objective;
|
|
840
|
+
- domain;
|
|
841
|
+
- authority sources;
|
|
842
|
+
- work clusters;
|
|
843
|
+
- validation surfaces;
|
|
844
|
+
- private/public boundary;
|
|
845
|
+
- 第一个 recommended_action。
|
|
846
|
+
2. 用这些初始参数作为默认值;如果目标文档给出更好的命名或边界,可以修正:
|
|
847
|
+
- stable goal id: `{goal_id}`
|
|
848
|
+
- objective: `{objective}`
|
|
849
|
+
- domain: `{domain}`
|
|
850
|
+
- adapter_kind: `{adapter_kind}`
|
|
851
|
+
- adapter_status: `{adapter_status}`
|
|
852
|
+
- goal_doc: `{goal_doc}`
|
|
853
|
+
- next_probe: `{next_probe}`
|
|
854
|
+
- spawn_allowed: `{spawn_allowed}`
|
|
855
|
+
- allowed_domains: `{allowed_domains_text}`
|
|
856
|
+
- write_scope: `{write_scope_text}`
|
|
857
|
+
3. 运行 LoopX 接入命令:
|
|
858
|
+
|
|
859
|
+
```bash
|
|
860
|
+
{connect_command}
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
4. 确认 `.loopx/registry.json` 和 `.codex/goals/{goal_id}/ACTIVE_GOAL_STATE.md` 已创建或更新。
|
|
864
|
+
阅读输出里的 `Onboarding Scan`、`Proposed Onboarding Candidates`、`Accept Candidate Commands`
|
|
865
|
+
和 `Autonomy Choice`。不要让用户手动执行这些命令;你应当用中文简要解释候选 todo,
|
|
866
|
+
然后询问用户:
|
|
867
|
+
- 接受哪些编号,是否需要改写;
|
|
868
|
+
- 是否 `autonomous=yes`,允许你在 quota guard 通过后开始执行第一个接受的 agent todo。
|
|
869
|
+
如果用户接受候选 todo,用输出里的 `{cli_bin} todo add ...` 命令写入 agent todo;
|
|
870
|
+
如果用户允许自主推进,先运行 quota guard,再执行第一个已接受 agent todo。
|
|
871
|
+
如果用户不允许自主推进,只写入接受的 todo 并运行 `{refresh_command}`,
|
|
872
|
+
然后停下来汇报。
|
|
873
|
+
如果目标状态包含私有证据,把 `.loopx/` 和 `.codex/goals/` 加入该项目 `.gitignore`。
|
|
874
|
+
`{cli_bin} connect` 默认会同步到共享全局 registry;不要手动编辑其他项目的 registry。
|
|
875
|
+
接入后检查 registry 里的 `execution_profile`:它是本项目后续 heartbeat / adapter 的执行画像。
|
|
876
|
+
默认 cadence 是 `bounded_progress_segment`,连续小步达到阈值后,下一轮必须扩展到
|
|
877
|
+
`minimum_scale` 并包含 `must_include` 里的真实 artifact、targeted validation、state writeback;
|
|
878
|
+
如果做不到,先报 blocker,不 append quota spend。
|
|
879
|
+
5. 在任何 heartbeat、scheduled tick、long-running adapter 或自主 delivery 前,先问 compute guard:
|
|
880
|
+
|
|
881
|
+
```bash
|
|
882
|
+
{quota_guard_command}
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
如果返回 `state=operator_gate`,把它当成人/控制器交互,而不是安静 skip:优先读取 payload 里的
|
|
886
|
+
`gate_prompt`、`operator_question`、`recommended_action`、`next_handoff_condition`、`missing_gates`、
|
|
887
|
+
`user_todo_summary` 和 `agent_todo_summary`,用中文主动告诉用户当前卡在哪个 gate、期望怎样回复;
|
|
888
|
+
同时把 `agent_todo_summary` 当作项目 agent 自己的安全后续清单。不要执行任何
|
|
889
|
+
`agent_command`、adapter work、write-control、生产动作或该 gated action。
|
|
890
|
+
如果同一个未决 gate 最近已经问过,且返回 `safe_bypass_allowed=true`,该 gate 只阻塞被 gate 覆盖的
|
|
891
|
+
delivery path;可以从 active state / Priority Stack 里选择一个不依赖该 gate 的 bounded 只读分析、
|
|
892
|
+
steering、文档或 P0/P1 工作。若实际完成 safe-bypass 工作,仍需验证、写回进展,并 append 一次
|
|
893
|
+
quota spend。
|
|
894
|
+
如果 payload 返回 `notify_user_on_open_todo=true`,把开放 user todo 当作 blocker-push,而不是
|
|
895
|
+
静默 skip:用中文最多列 3 个开放项和期望回复格式,并且本轮不做 delivery、不 append quota spend,
|
|
896
|
+
除非同一个 blocker 最近已经问过。
|
|
897
|
+
无论 `should_run` 是 true 还是 false,都先看 `execution_obligation`、
|
|
898
|
+
`effective_action`、`recovery_delivery_allowed`、`safe_bypass_kind` 和
|
|
899
|
+
`heartbeat_recommendation`。`heartbeat_recommendation.notify` 只是用户通知策略,
|
|
900
|
+
不是执行 gate;如果 `execution_obligation.must_attempt_work=true`,即使
|
|
901
|
+
`notify=DONT_NOTIFY` 也要尝试一个 bounded segment,只有
|
|
902
|
+
`must_attempt_work=false` 才能 quiet no-op。
|
|
903
|
+
如果是 `outcome_floor_recovery`,这是 Codex 可执行 recovery turn:只允许做一次所需
|
|
904
|
+
ranker/cross-domain evidence recovery,或写回阻止该 evidence 的具体 blocker;
|
|
905
|
+
不做 surface-only / synthetic-only 循环,验证并写回后才能 append 一次 quota spend。
|
|
906
|
+
如果不是 operator gate / blocker-push / outcome-floor recovery / 明确 safe-bypass,本轮不要做实现或 adapter 工作,
|
|
907
|
+
只记录 public-safe reason;不要执行任何 `agent_command`,即使 status 或 review packet 里提到过命令。
|
|
908
|
+
只有当返回 `should_run=true` 且 payload 里包含 `agent_command` 时,才执行该命令。
|
|
909
|
+
如果 `should_run=true` 但没有 `agent_command`,按
|
|
910
|
+
`execution_obligation` / `recommended_action` / `goal_boundary` 选择下一个
|
|
911
|
+
安全 bounded 动作;只读目标保持只读,delivery 目标按已授权 write scope 执行。
|
|
912
|
+
如果命令非零,fail closed,先修 `{cli_bin} doctor` / `{cli_bin} status`。
|
|
913
|
+
这个 guard 不等于写权限、不绕过 operator gate、也不替代 human reward。
|
|
914
|
+
任何时候,如果你通过 read-only 分析、review doc、gate checklist 或 P0/P1 steering 发现新的
|
|
915
|
+
用户/owner 待办,不要只写在 `Next Action`、外部 review 文档或聊天里。立刻把它写进 active state
|
|
916
|
+
的 user todo 权威区:
|
|
917
|
+
|
|
918
|
+
```bash
|
|
919
|
+
{cli_bin} todo add --goal-id {goal_id} --role user --task-class user_gate --blocks-agent <agent-id> --text "<public-safe blocking user/owner decision>"
|
|
920
|
+
{cli_bin} todo add --goal-id {goal_id} --role user --task-class user_action --text "<public-safe non-blocking user/owner todo>"
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
agent 自己的后续动作写成 `--role agent`。写入后如果 dashboard 需要看到最新状态,运行
|
|
924
|
+
`{refresh_command}`。
|
|
925
|
+
完整契约见 LoopX 仓库里的 `docs/project-agent-todo-contract.md`。
|
|
926
|
+
6. 如果需要把当前 packet 或已批准命令交给项目 agent,优先生成最小 handoff,不要从旧聊天、
|
|
927
|
+
旧 review packet 或 `run_history.latest_runs` 拼当前状态。当前权威状态来自
|
|
928
|
+
`attention_queue.items` / `project_asset`;如果缺少 `project_asset` 或标记为
|
|
929
|
+
`legacy/raw fallback`,不要把 raw queue 字段当作 owner/gate/stop authority:
|
|
930
|
+
|
|
931
|
+
```bash
|
|
932
|
+
{cli_bin} review-packet --goal-id {goal_id} --handoff-only
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
只把输出的 handoff 交给目标项目 agent;完整 review packet 留给 operator view / evidence drill-down。
|
|
936
|
+
7. 如果要给这个项目设置 recurring Codex App heartbeat,默认每 3 分钟一次,后续跟随 `quota should-run.scheduler_hint` 降频;不要手抄 guard 和 spend 协议;先生成 task body,再把输出复制进 automation:
|
|
937
|
+
|
|
938
|
+
```bash
|
|
939
|
+
{cli_bin} heartbeat-prompt --goal-id {goal_id} --active-state .codex/goals/{goal_id}/ACTIVE_GOAL_STATE.md
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
8. 生成一个 read-only project map 或 first pre-tick run。不要启动线上任务、不同步外部系统、不要写生产状态,除非目标文档明确授权。通用接入优先跑:
|
|
943
|
+
|
|
944
|
+
```bash
|
|
945
|
+
{cli_bin} read-only-map --goal-id {goal_id}
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
9. 如果本轮只更新了 active state、ledger 或外部规划文档,没有产生新的
|
|
949
|
+
adapter run,追加一个 state-only refresh run,然后停止且不记 quota spend。
|
|
950
|
+
如果本轮实际消耗了 automatic delivery compute,先不要运行这个 state-only
|
|
951
|
+
refresh;把它留到第 11 步记账之后:
|
|
952
|
+
|
|
953
|
+
```bash
|
|
954
|
+
{refresh_command}
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
这个命令也会自动同步全局 registry。
|
|
958
|
+
|
|
959
|
+
10. 跑验证:
|
|
960
|
+
- `{cli_bin} registry`
|
|
961
|
+
- `{cli_bin} status`(在没有项目局部 registry 的目录里也应自动读共享全局 registry)
|
|
962
|
+
- `{cli_bin} check --scan-path <PUBLIC_SAFE_FILE_OR_DIR>`
|
|
963
|
+
11. 如果本轮实际花了 automatic delivery compute(例如 read-only map、adapter
|
|
964
|
+
tick、实现推进或验证推进),在 validation / writeback 完成后,把命令中的
|
|
965
|
+
三个 placeholder 替换为本轮实际验证过的 classification、batch scale 和
|
|
966
|
+
outcome;不要默认或拔高成 `multi_surface` / `outcome_progress`。然后记录本轮
|
|
967
|
+
accountable delivery:
|
|
968
|
+
|
|
969
|
+
```bash
|
|
970
|
+
{progress_refresh_command}
|
|
971
|
+
```
|
|
972
|
+
|
|
973
|
+
这是 `spend-slot` 将消费的因果记录;普通 state-only refresh 不能替代它。
|
|
974
|
+
然后只 append 一次 quota spend:
|
|
975
|
+
|
|
976
|
+
```bash
|
|
977
|
+
{quota_spend_command}
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
如果 dashboard 或 controller 在 spend 后仍需状态更新,再运行第 9 步的
|
|
981
|
+
`{refresh_command}`。不要在 spend 后追加另一个 accountable progress
|
|
982
|
+
refresh,否则它会成为新的未记账 delivery。
|
|
983
|
+
|
|
984
|
+
不要为 quiet `should_run=false` skip、preflight 失败、或纯 dry-run preview 记账;如果
|
|
985
|
+
`should_run=false` 但实际完成了 `safe_bypass_allowed=true` 的 bounded safe-bypass 工作,要记一次账。
|
|
986
|
+
accountable `refresh-state` 应从实际交付 worktree 运行;若 registry/state 投影只能从另一个
|
|
987
|
+
checkout 执行,显式加 `--delivery-workspace-path <delivery-worktree>`,不要让 canonical checkout
|
|
988
|
+
覆盖交付归因。
|
|
989
|
+
不要重复执行。
|
|
990
|
+
12. 最后用中文汇报:
|
|
991
|
+
- changed files;
|
|
992
|
+
- validation output;
|
|
993
|
+
- 当前 goal 在 dashboard / attention queue 里会怎么显示;
|
|
994
|
+
- next safe action;
|
|
995
|
+
- 如果还不能接入 decision-advisor,明确缺哪些 gates。
|
|
996
|
+
|
|
997
|
+
并行/权限边界:
|
|
998
|
+
{spawn_note}
|
|
999
|
+
"""
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
def render_new_project_prompt_markdown(payload: dict[str, Any]) -> str:
|
|
1003
|
+
return f"""# New Project Codex Handoff Prompt
|
|
1004
|
+
|
|
1005
|
+
Copy the block below into the Codex session that can access the target project.
|
|
1006
|
+
|
|
1007
|
+
````text
|
|
1008
|
+
{payload.get("prompt", "")}
|
|
1009
|
+
````
|
|
1010
|
+
|
|
1011
|
+
## Generator Inputs
|
|
1012
|
+
|
|
1013
|
+
- project: `{payload.get("project")}`
|
|
1014
|
+
- goal_doc: `{payload.get("goal_doc")}`
|
|
1015
|
+
- goal_id: `{payload.get("goal_id")}`
|
|
1016
|
+
- domain: `{payload.get("domain")}`
|
|
1017
|
+
- adapter: `{payload.get("adapter_kind")}:{payload.get("adapter_status")}`
|
|
1018
|
+
"""
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
def render_codex_cli_bootstrap_message_markdown(payload: dict[str, Any]) -> str:
|
|
1022
|
+
checklist = "\n".join(
|
|
1023
|
+
f"- {item}" for item in payload.get("first_run_validation_checklist", [])
|
|
1024
|
+
)
|
|
1025
|
+
goal_mode_note = ""
|
|
1026
|
+
if payload.get("invocation_mode") == "codex_cli_setup_then_goal_mode":
|
|
1027
|
+
goal_mode_note = (
|
|
1028
|
+
"\nThe generated block is a setup message, not the reusable heartbeat body. "
|
|
1029
|
+
"After install/bootstrap, it tells the agent to set Codex CLI goal mode "
|
|
1030
|
+
"to `/goal <thin task_body>` or Codex App automation starting at 3 minutes "
|
|
1031
|
+
"with `<thin task_body>`.\n"
|
|
1032
|
+
)
|
|
1033
|
+
return f"""# Codex CLI LoopX Bootstrap Message
|
|
1034
|
+
|
|
1035
|
+
Copy the block below into Codex CLI TUI from the project repo.
|
|
1036
|
+
{goal_mode_note}
|
|
1037
|
+
|
|
1038
|
+
````text
|
|
1039
|
+
{payload.get("message", "")}
|
|
1040
|
+
````
|
|
1041
|
+
|
|
1042
|
+
## Fresh Repo Install Repair
|
|
1043
|
+
|
|
1044
|
+
The generated message uses the no-clone GitHub archive installer before asking
|
|
1045
|
+
for a contributor clone:
|
|
1046
|
+
|
|
1047
|
+
```bash
|
|
1048
|
+
{payload.get("install_repair_command", "")}
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
## Post-Bootstrap Thin Loop Prompt
|
|
1052
|
+
|
|
1053
|
+
Generate the thin task body after the project is connected:
|
|
1054
|
+
|
|
1055
|
+
```bash
|
|
1056
|
+
{payload.get("heartbeat_prompt_json_command", "")}
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
- Codex CLI TUI loop: set `/goal <task_body>`.
|
|
1060
|
+
- Codex App loop: set heartbeat automation initially every 3 minutes with
|
|
1061
|
+
`<task_body>`, then follow quota `scheduler_hint`.
|
|
1062
|
+
|
|
1063
|
+
## Transcript-Free Validation Checklist
|
|
1064
|
+
|
|
1065
|
+
{checklist}
|
|
1066
|
+
|
|
1067
|
+
## Generator Inputs
|
|
1068
|
+
|
|
1069
|
+
- project: `{payload.get("project")}`
|
|
1070
|
+
- goal_id: `{payload.get("goal_id")}`
|
|
1071
|
+
- agent_id: `{payload.get("agent_id") or "(not provided)"}`
|
|
1072
|
+
- cli_bin: `{payload.get("cli_bin")}`
|
|
1073
|
+
- heartbeat_prompt_drift_check: `{payload.get("heartbeat_prompt_command")}`
|
|
1074
|
+
"""
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
def render_codex_cli_tui_bootstrap_smoke_bundle_markdown(payload: dict[str, Any]) -> str:
|
|
1078
|
+
boundary = payload.get("boundary") or {}
|
|
1079
|
+
checklist = "\n".join(f"- {item}" for item in payload.get("validation_checklist", []))
|
|
1080
|
+
return f"""# Codex CLI TUI Bootstrap Smoke Bundle
|
|
1081
|
+
|
|
1082
|
+
This packet is for validating the first-run Codex CLI path without launching or
|
|
1083
|
+
mutating a real Codex session.
|
|
1084
|
+
|
|
1085
|
+
## Commands
|
|
1086
|
+
|
|
1087
|
+
```bash
|
|
1088
|
+
{payload.get("message_only_command", "")}
|
|
1089
|
+
```
|
|
1090
|
+
|
|
1091
|
+
- review_packet: `{payload.get("review_packet_command")}`
|
|
1092
|
+
- heartbeat_prompt: `{payload.get("heartbeat_prompt_command")}`
|
|
1093
|
+
- heartbeat_prompt_json: `{payload.get("heartbeat_prompt_json_command")}`
|
|
1094
|
+
- quota_guard: `{payload.get("quota_guard_command")}`
|
|
1095
|
+
- accountable_progress_refresh: `{payload.get("progress_refresh_command")}`
|
|
1096
|
+
- quota_spend_after_validation: `{payload.get("quota_spend_command")}`
|
|
1097
|
+
- optional_state_only_refresh_after_spend: `{payload.get("refresh_command")}`
|
|
1098
|
+
|
|
1099
|
+
## Fresh Repo Install Repair
|
|
1100
|
+
|
|
1101
|
+
```bash
|
|
1102
|
+
{payload.get("install_repair_command", "")}
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
## Transcript-Free Boundary
|
|
1106
|
+
|
|
1107
|
+
- runs_codex: `{boundary.get("runs_codex")}`
|
|
1108
|
+
- reads_raw_transcripts: `{boundary.get("reads_raw_transcripts")}`
|
|
1109
|
+
- reads_session_files: `{boundary.get("reads_session_files")}`
|
|
1110
|
+
- reads_credentials: `{boundary.get("reads_credentials")}`
|
|
1111
|
+
- mutates_codex_session: `{boundary.get("mutates_codex_session")}`
|
|
1112
|
+
- spends_loopx_quota: `{boundary.get("spends_loopx_quota")}`
|
|
1113
|
+
- requires_loopx_repo_clone: `{boundary.get("requires_loopx_repo_clone")}`
|
|
1114
|
+
|
|
1115
|
+
## Validation Checklist
|
|
1116
|
+
|
|
1117
|
+
{checklist}
|
|
1118
|
+
"""
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
def render_codex_cli_exec_handoff_markdown(payload: dict[str, Any]) -> str:
|
|
1122
|
+
boundary = payload.get("boundary") or {}
|
|
1123
|
+
return f"""# Codex CLI Exec Handoff Disabled
|
|
1124
|
+
|
|
1125
|
+
The default Codex CLI LoopX bootstrap is visible setup, then thin
|
|
1126
|
+
`/goal <task_body>` activation. Headless `codex exec` handoff is disabled here
|
|
1127
|
+
to avoid accidental hidden execution. Use the message-only command below inside
|
|
1128
|
+
the visible Codex CLI TUI.
|
|
1129
|
+
|
|
1130
|
+
````bash
|
|
1131
|
+
{payload.get("message_only_command", "")}
|
|
1132
|
+
````
|
|
1133
|
+
|
|
1134
|
+
## Guard Commands
|
|
1135
|
+
|
|
1136
|
+
- session_probe: `{payload.get("session_probe_command")}`
|
|
1137
|
+
- quota_guard: `{payload.get("quota_guard_command")}`
|
|
1138
|
+
- accountable_progress_refresh: `{payload.get("progress_refresh_command")}`
|
|
1139
|
+
- quota_spend: `{payload.get("quota_spend_command")}`
|
|
1140
|
+
- optional_state_only_refresh_after_spend: `{payload.get("refresh_command")}`
|
|
1141
|
+
- disabled_reason: {payload.get("disabled_reason")}
|
|
1142
|
+
|
|
1143
|
+
## Boundary
|
|
1144
|
+
|
|
1145
|
+
- runs_codex: `{boundary.get("runs_codex")}`
|
|
1146
|
+
- reads_raw_transcripts: `{boundary.get("reads_raw_transcripts")}`
|
|
1147
|
+
- reads_credentials: `{boundary.get("reads_credentials")}`
|
|
1148
|
+
- reads_session_files: `{boundary.get("reads_session_files")}`
|
|
1149
|
+
- mutates_codex_session: `{boundary.get("mutates_codex_session")}`
|
|
1150
|
+
- spends_loopx_quota: `{boundary.get("spends_loopx_quota")}`
|
|
1151
|
+
- headless_execution_disabled: `{boundary.get("headless_execution_disabled")}`
|
|
1152
|
+
- provides_executable_headless_command: `{boundary.get("provides_executable_headless_command")}`
|
|
1153
|
+
"""
|