okstra 0.186.7 → 0.188.0
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.
- package/README.md +1 -1
- package/dist/cli-registry.d.mts +88 -1
- package/dist/cli-registry.mjs +68 -111
- package/dist/cli-registry.mjs.map +1 -1
- package/dist/commands/execute/render-bundle.mjs +0 -1
- package/dist/commands/execute/render-bundle.mjs.map +1 -1
- package/dist/commands/execute/run.mjs +8 -3
- package/dist/commands/execute/run.mjs.map +1 -1
- package/dist/commands/lifecycle/check-project.mjs +1 -14
- package/dist/commands/lifecycle/check-project.mjs.map +1 -1
- package/dist/commands/lifecycle/config.mjs +38 -40
- package/dist/commands/lifecycle/config.mjs.map +1 -1
- package/dist/commands/lifecycle/doctor.d.mts +22 -7
- package/dist/commands/lifecycle/doctor.mjs +77 -49
- package/dist/commands/lifecycle/doctor.mjs.map +1 -1
- package/dist/commands/lifecycle/install.d.mts +12 -10
- package/dist/commands/lifecycle/install.mjs +107 -40
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/dist/commands/lifecycle/paths.mjs +8 -3
- package/dist/commands/lifecycle/paths.mjs.map +1 -1
- package/dist/commands/lifecycle/preflight.mjs +2 -1
- package/dist/commands/lifecycle/preflight.mjs.map +1 -1
- package/dist/commands/lifecycle/setup.mjs +22 -36
- package/dist/commands/lifecycle/setup.mjs.map +1 -1
- package/dist/commands/lifecycle/uninstall.d.mts +4 -2
- package/dist/commands/lifecycle/uninstall.mjs +59 -15
- package/dist/commands/lifecycle/uninstall.mjs.map +1 -1
- package/dist/commands/memory/memory.mjs +7 -1
- package/dist/commands/memory/memory.mjs.map +1 -1
- package/dist/lib/helper-scripts.d.mts +1 -1
- package/dist/lib/helper-scripts.mjs +10 -18
- package/dist/lib/helper-scripts.mjs.map +1 -1
- package/dist/lib/host-config.d.mts +72 -0
- package/dist/lib/host-config.mjs +404 -0
- package/dist/lib/host-config.mjs.map +1 -0
- package/dist/lib/host-registry-client.d.mts +2 -2
- package/dist/lib/host-registry-client.mjs +0 -3
- package/dist/lib/host-registry-client.mjs.map +1 -1
- package/dist/lib/install-assets.d.mts +1 -0
- package/dist/lib/install-assets.mjs +4 -0
- package/dist/lib/install-assets.mjs.map +1 -1
- package/dist/lib/proc.d.mts +2 -0
- package/dist/lib/proc.mjs +12 -0
- package/dist/lib/proc.mjs.map +1 -1
- package/dist/lib/python-command.d.mts +2 -0
- package/dist/lib/python-command.mjs +52 -0
- package/dist/lib/python-command.mjs.map +1 -0
- package/dist/lib/python-helper.d.mts +2 -5
- package/dist/lib/python-helper.mjs +3 -52
- package/dist/lib/python-helper.mjs.map +1 -1
- package/dist/lib/runtime-payload.d.mts +23 -0
- package/dist/lib/runtime-payload.mjs +57 -0
- package/dist/lib/runtime-payload.mjs.map +1 -0
- package/dist/lib/types.d.mts +24 -13
- package/docs/architecture/storage-model.md +21 -5
- package/docs/architecture.md +39 -38
- package/docs/cli.md +55 -76
- package/docs/coding-rules.md +295 -0
- package/docs/container.md +10 -36
- package/docs/contributor-change-matrix.md +1 -1
- package/docs/for-ai/skills/okstra-code-review.md +0 -1
- package/docs/for-ai/skills/okstra-container-build.md +8 -41
- package/docs/for-ai/skills/okstra-inspect.md +4 -4
- package/docs/for-ai/skills/okstra-manager.md +2 -2
- package/docs/for-ai/skills/okstra-rollup.md +0 -1
- package/docs/for-ai/skills/okstra-run.md +3 -3
- package/docs/for-ai/skills/okstra-user-response.md +0 -1
- package/docs/performance-improvement-plan-v2.md +1 -1
- package/docs/project-structure-overview.md +62 -62
- package/docs/task-process/README.md +3 -3
- package/docs/task-process/common-flow.md +1 -1
- package/docs/task-process/error-analysis.md +3 -3
- package/docs/task-process/implementation-planning.md +3 -1
- package/docs/task-process/release-handoff.md +1 -1
- package/package.json +3 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/claude-worker.md +6 -11
- package/runtime/agents/workers/report-writer-worker.md +1 -1
- package/runtime/bin/lib/okstra/cli.sh +4 -0
- package/runtime/bin/lib/okstra/globals.sh +2 -0
- package/runtime/bin/lib/okstra/interactive.sh +26 -173
- package/runtime/bin/lib/okstra/project-resolver.sh +23 -61
- package/runtime/bin/lib/okstra/usage.sh +3 -3
- package/runtime/bin/okstra-compact-reminder.sh +1 -5
- package/runtime/bin/okstra-error-log.py +19 -2
- package/runtime/bin/okstra-import-check.py +26 -0
- package/runtime/bin/okstra-inject-report-index.py +5 -4
- package/runtime/bin/okstra-provider-exec.py +22 -17
- package/runtime/bin/okstra-render-final-report.py +16 -6
- package/runtime/bin/okstra-render-report-views.py +47 -22
- package/runtime/bin/okstra-report-translate.py +30 -18
- package/runtime/bin/okstra-spawn-followups.py +4 -0
- package/runtime/bin/okstra-token-usage.py +3 -0
- package/runtime/bin/okstra.sh +4 -2
- package/runtime/bin/okstra_bootstrap.py +58 -0
- package/runtime/prompts/coding-preflight/overview.md +1 -1
- package/runtime/prompts/duties/planning-worker.md +1 -1
- package/runtime/prompts/launch.template.md +35 -9
- package/runtime/prompts/lead/adapters/cmux.md +3 -3
- package/runtime/prompts/lead/convergence.md +99 -88
- package/runtime/prompts/lead/okstra-lead-contract.md +63 -12
- package/runtime/prompts/lead/plan-body-verification.md +65 -46
- package/runtime/prompts/lead/report-writer.md +35 -5
- package/runtime/prompts/lead/team-contract.md +4 -1
- package/runtime/prompts/profiles/_clarification-recommendation.md +2 -1
- package/runtime/prompts/profiles/_coding-conventions-preflight.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +3 -3
- package/runtime/prompts/profiles/_coverage-critic.md +1 -1
- package/runtime/prompts/profiles/_implementation-deliverable.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +3 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +16 -2
- package/runtime/prompts/profiles/error-analysis.md +4 -3
- package/runtime/prompts/profiles/final-verification.md +2 -2
- package/runtime/prompts/profiles/implementation-planning.md +22 -17
- package/runtime/prompts/profiles/implementation.md +3 -2
- package/runtime/prompts/profiles/requirements-discovery.md +2 -1
- package/runtime/prompts/wizard/prompts.ko.json +29 -8
- package/runtime/python/okstra_ctl/__init__.py +6 -27
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -5
- package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +21 -2
- package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +3 -12
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +63 -22
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +20 -21
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +37 -20
- package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +86 -14
- package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +12 -12
- package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +4 -7
- package/runtime/python/okstra_ctl/agent/__init__.py +1 -0
- package/runtime/python/okstra_ctl/{agent_activity.py → agent/activity.py} +16 -2
- package/runtime/python/okstra_ctl/{agent_invocation.py → agent/invocation.py} +34 -5
- package/runtime/python/okstra_ctl/agent/prompt_cli/__init__.py +19 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/__main__.py +11 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +228 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/dynamic_verifier.py +155 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/emit.py +66 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/inputs.py +138 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +605 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/results.py +197 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +107 -0
- package/runtime/python/okstra_ctl/analysis_packet.py +47 -4
- package/runtime/python/okstra_ctl/approval_decisions.py +287 -10
- package/runtime/python/okstra_ctl/assignment_resolver.py +0 -12
- package/runtime/python/okstra_ctl/attempt_evidence.py +12 -24
- package/runtime/python/okstra_ctl/blocking_checks.py +251 -0
- package/runtime/python/okstra_ctl/brief_frontmatter.py +0 -7
- package/runtime/python/okstra_ctl/clarification_items/__init__.py +102 -0
- package/runtime/python/okstra_ctl/clarification_items/carry.py +224 -0
- package/runtime/python/okstra_ctl/clarification_items/dispositions.py +135 -0
- package/runtime/python/okstra_ctl/clarification_items/parsing.py +253 -0
- package/runtime/python/okstra_ctl/clarification_items/rows.py +115 -0
- package/runtime/python/okstra_ctl/clarification_items/scan.py +215 -0
- package/runtime/python/okstra_ctl/clarification_items/sidecars.py +211 -0
- package/runtime/python/okstra_ctl/cmux.py +38 -31
- package/runtime/python/okstra_ctl/code_review_target.py +163 -1
- package/runtime/python/okstra_ctl/conformance.py +23 -0
- package/runtime/python/okstra_ctl/container.py +38 -421
- package/runtime/python/okstra_ctl/context_cost.py +32 -4
- package/runtime/python/okstra_ctl/contract_graph_cli.py +7 -0
- package/runtime/python/okstra_ctl/convergence.py +107 -16
- package/runtime/python/okstra_ctl/convergence_critic_prompt.py +345 -0
- package/runtime/python/okstra_ctl/convergence_engine.py +382 -70
- package/runtime/python/okstra_ctl/convergence_store.py +5 -29
- package/runtime/python/okstra_ctl/design_prep.py +108 -12
- package/runtime/python/okstra_ctl/design_snapshot.py +11 -1
- package/runtime/python/okstra_ctl/design_surfaces.py +29 -2
- package/runtime/python/okstra_ctl/dispatch_core.py +236 -49
- package/runtime/python/okstra_ctl/dispatch_state.py +417 -41
- package/runtime/python/okstra_ctl/doctor_cli.py +48 -0
- package/runtime/python/okstra_ctl/domain/worker_exec.py +10 -5
- package/runtime/python/okstra_ctl/domain/worker_presentation.py +28 -1
- package/runtime/python/okstra_ctl/domain/worker_stream.py +52 -21
- package/runtime/python/okstra_ctl/domain/write_policy.py +219 -0
- package/runtime/python/okstra_ctl/entrypoints/hosts.py +9 -2
- package/runtime/python/okstra_ctl/error_log_core.py +1 -1
- package/runtime/python/okstra_ctl/error_report.py +14 -0
- package/runtime/python/okstra_ctl/error_zip.py +18 -2
- package/runtime/python/okstra_ctl/exact_coverage.py +5 -0
- package/runtime/python/okstra_ctl/execution_identity.py +100 -7
- package/runtime/python/okstra_ctl/execution_manifest.py +67 -20
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +90 -8
- package/runtime/python/okstra_ctl/final_report_paths.py +17 -0
- package/runtime/python/okstra_ctl/final_report_schema.py +319 -17
- package/runtime/python/okstra_ctl/git_reconcile.py +22 -2
- package/runtime/python/okstra_ctl/handoff.py +24 -1
- package/runtime/python/okstra_ctl/ids.py +6 -16
- package/runtime/python/okstra_ctl/implementation_direction.py +142 -33
- package/runtime/python/okstra_ctl/implementation_options.py +32 -13
- package/runtime/python/okstra_ctl/implementation_outcome.py +5 -2
- package/runtime/python/okstra_ctl/improvement_lenses.py +0 -14
- package/runtime/python/okstra_ctl/incremental_carry.py +69 -8
- package/runtime/python/okstra_ctl/incremental_scope.py +173 -12
- package/runtime/python/okstra_ctl/index.py +2 -2
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +48 -8
- package/runtime/python/okstra_ctl/interactive_cli.py +223 -0
- package/runtime/python/okstra_ctl/json_boundary.py +10 -0
- package/runtime/python/okstra_ctl/listing.py +0 -91
- package/runtime/python/okstra_ctl/locks.py +5 -19
- package/runtime/python/okstra_ctl/log_report.py +14 -0
- package/runtime/python/okstra_ctl/manager_cli.py +22 -3
- package/runtime/python/okstra_ctl/manager_launch.py +4 -8
- package/runtime/python/okstra_ctl/material.py +2 -2
- package/runtime/python/okstra_ctl/migrate.py +23 -1
- package/runtime/python/okstra_ctl/model_cli.py +19 -5
- package/runtime/python/okstra_ctl/model_discovery.py +46 -47
- package/runtime/python/okstra_ctl/model_io/__init__.py +1 -0
- package/runtime/python/okstra_ctl/model_io/lines.py +163 -0
- package/runtime/python/okstra_ctl/model_io/references.py +370 -0
- package/runtime/python/okstra_ctl/model_io/renderers.py +498 -0
- package/runtime/python/okstra_ctl/model_io_cli.py +30 -945
- package/runtime/python/okstra_ctl/model_pool.py +10 -6
- package/runtime/python/okstra_ctl/models.py +8 -8
- package/runtime/python/okstra_ctl/mutation_recovery.py +5 -63
- package/runtime/python/okstra_ctl/next_phase.py +121 -69
- package/runtime/python/okstra_ctl/pane_reclaim.py +23 -0
- package/runtime/python/okstra_ctl/pane_title.py +11 -8
- package/runtime/python/okstra_ctl/path_hints.py +36 -11
- package/runtime/python/okstra_ctl/paths.py +76 -8
- package/runtime/python/okstra_ctl/plan_items.py +132 -16
- package/runtime/python/okstra_ctl/plan_items_cli.py +486 -36
- package/runtime/python/okstra_ctl/plan_run_root.py +1 -1
- package/runtime/python/okstra_ctl/plan_validate_cli.py +51 -0
- package/runtime/python/okstra_ctl/plan_verify_cli.py +80 -0
- package/runtime/python/okstra_ctl/prepare_error.py +20 -0
- package/runtime/python/okstra_ctl/prior_planning.py +157 -0
- package/runtime/python/okstra_ctl/profile_show.py +18 -1
- package/runtime/python/okstra_ctl/project_setup_cli.py +140 -0
- package/runtime/python/okstra_ctl/recap.py +22 -1
- package/runtime/python/okstra_ctl/reconcile.py +84 -0
- package/runtime/python/okstra_ctl/registry/host_registry.py +18 -1
- package/runtime/python/okstra_ctl/render.py +98 -32
- package/runtime/python/okstra_ctl/render_final_report.py +4 -8
- package/runtime/python/okstra_ctl/report_assembly.py +297 -7
- package/runtime/python/okstra_ctl/report_contract.py +30 -7
- package/runtime/python/okstra_ctl/report_finalize.py +213 -16
- package/runtime/python/okstra_ctl/report_html/common.py +2 -2
- package/runtime/python/okstra_ctl/report_html/render.py +8 -12
- package/runtime/python/okstra_ctl/report_language.py +8 -4
- package/runtime/python/okstra_ctl/report_narrative.py +220 -34
- package/runtime/python/okstra_ctl/report_projections.py +8 -2
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +393 -1
- package/runtime/python/okstra_ctl/report_translation.py +2 -35
- package/runtime/python/okstra_ctl/report_view_artifacts.py +42 -2
- package/runtime/python/okstra_ctl/report_views.py +4 -22
- package/runtime/python/okstra_ctl/resolve_task_key.py +13 -0
- package/runtime/python/okstra_ctl/rollup.py +13 -0
- package/runtime/python/okstra_ctl/run.py +639 -138
- package/runtime/python/okstra_ctl/run_audit.py +13 -0
- package/runtime/python/okstra_ctl/run_index_row.py +0 -12
- package/runtime/python/okstra_ctl/seeding.py +21 -11
- package/runtime/python/okstra_ctl/sequence.py +1 -1
- package/runtime/python/okstra_ctl/session.py +64 -14
- package/runtime/python/okstra_ctl/set_work_status.py +18 -0
- package/runtime/python/okstra_ctl/stage_integrate.py +15 -1
- package/runtime/python/okstra_ctl/stage_ledger.py +1 -1
- package/runtime/python/okstra_ctl/stage_map.py +57 -11
- package/runtime/python/okstra_ctl/stage_map_cli.py +83 -0
- package/runtime/python/okstra_ctl/stage_map_view.py +65 -0
- package/runtime/python/okstra_ctl/stage_targets.py +3 -12
- package/runtime/python/okstra_ctl/task_list_cli.py +138 -0
- package/runtime/python/okstra_ctl/task_show_cli.py +66 -0
- package/runtime/python/okstra_ctl/task_target.py +4 -16
- package/runtime/python/okstra_ctl/team.py +49 -2
- package/runtime/python/okstra_ctl/time_report.py +17 -2
- package/runtime/python/okstra_ctl/usage_report.py +11 -0
- package/runtime/python/okstra_ctl/user_response.py +55 -218
- package/runtime/python/okstra_ctl/user_response_values.py +242 -0
- package/runtime/python/okstra_ctl/validation_contract.py +3 -0
- package/runtime/python/okstra_ctl/verdict_blocks.py +28 -8
- package/runtime/python/okstra_ctl/verification_target.py +68 -0
- package/runtime/python/okstra_ctl/wizard.py +457 -92
- package/runtime/python/okstra_ctl/worker_artifacts.py +75 -16
- package/runtime/python/okstra_ctl/worker_audit_check.py +22 -0
- package/runtime/python/okstra_ctl/worker_dispatch.py +21 -0
- package/runtime/python/okstra_ctl/worker_liveness.py +33 -0
- package/runtime/python/okstra_ctl/worker_prompt_body.py +15 -2
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +98 -7
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +24 -2
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +18 -3
- package/runtime/python/okstra_ctl/worker_request.py +2 -1
- package/runtime/python/okstra_ctl/worker_runner.py +58 -17
- package/runtime/python/okstra_ctl/worker_state.py +16 -1
- package/runtime/python/okstra_ctl/workflow.py +18 -1
- package/runtime/python/okstra_ctl/worktree/__init__.py +92 -0
- package/runtime/python/okstra_ctl/worktree/cleanliness.py +89 -0
- package/runtime/python/okstra_ctl/worktree/decisions.py +127 -0
- package/runtime/python/okstra_ctl/worktree/git_ops.py +165 -0
- package/runtime/python/okstra_ctl/worktree/linking.py +249 -0
- package/runtime/python/okstra_ctl/worktree/naming.py +91 -0
- package/runtime/python/okstra_ctl/worktree/provision.py +385 -0
- package/runtime/python/okstra_ctl/worktree/sync_config.py +181 -0
- package/runtime/python/okstra_ctl/worktree_cli.py +75 -0
- package/runtime/python/okstra_ctl/worktree_lookup_cli.py +39 -0
- package/runtime/python/okstra_ctl/worktree_registry.py +7 -0
- package/runtime/python/okstra_ctl/worktree_status_cli.py +53 -0
- package/runtime/python/okstra_ctl/write_policy.py +90 -213
- package/runtime/python/okstra_project/__init__.py +0 -4
- package/runtime/python/okstra_project/dirs.py +2 -2
- package/runtime/python/okstra_project/phase_pointer.py +84 -0
- package/runtime/python/okstra_project/slug.py +24 -0
- package/runtime/python/okstra_project/state.py +22 -230
- package/runtime/python/okstra_token_usage/antigravity.py +50 -12
- package/runtime/python/okstra_token_usage/claude.py +9 -1
- package/runtime/python/okstra_token_usage/cli.py +3 -1
- package/runtime/python/okstra_token_usage/collect.py +171 -36
- package/runtime/python/okstra_token_usage/cursor.py +2 -0
- package/runtime/python/okstra_token_usage/grok.py +1 -5
- package/runtime/python/okstra_token_usage/paths.py +26 -0
- package/runtime/python/okstra_token_usage/pricing.py +23 -8
- package/runtime/schemas/convergence-critic-results-v1.0.schema.json +5 -0
- package/runtime/schemas/execution-manifest-v2.schema.json +10 -10
- package/runtime/schemas/final-report-v2.0.schema.json +9 -26
- package/runtime/schemas/final-report-v3.0.schema.json +173 -41
- package/runtime/schemas/report-narrative-v3.0.schema.json +3 -2
- package/runtime/skills/okstra-brief-gen/SKILL.md +35 -2
- package/runtime/skills/okstra-container-build/SKILL.md +16 -47
- package/runtime/skills/okstra-inspect/facets/history.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +7 -6
- package/runtime/skills/okstra-pr-gen/SKILL.md +1 -1
- package/runtime/skills/okstra-run/SKILL.md +7 -5
- package/runtime/templates/report-writer-prompt-preamble.md +3 -1
- package/runtime/templates/reports/brief.template.md +6 -2
- package/runtime/templates/reports/error-analysis-input.template.md +2 -0
- package/runtime/templates/reports/final-verification-input.template.md +2 -0
- package/runtime/templates/reports/implementation-input.template.md +7 -1
- package/runtime/templates/reports/implementation-planning-input.template.md +4 -0
- package/runtime/templates/reports/quick-input.template.md +2 -0
- package/runtime/templates/reports/release-handoff-input.template.md +6 -1
- package/runtime/templates/reports/report.js +20 -3
- package/runtime/templates/reports/schedule.template.md +2 -0
- package/runtime/templates/reports/settings.template.json +0 -10
- package/runtime/templates/reports/task-brief.template.md +3 -0
- package/runtime/templates/reports/user-response.template.md +7 -3
- package/runtime/validators/checks/fixtures-01.py +57 -0
- package/runtime/validators/checks/fixtures-02.py +565 -0
- package/runtime/validators/checks/runners-01.py +108 -0
- package/runtime/validators/checks/validate-assets-01.py +60 -0
- package/runtime/validators/checks/validate-prompt-metadata-01.py +261 -0
- package/runtime/validators/checks/validate-tasks-01.py +46 -0
- package/runtime/validators/checks/validate-tasks-02.py +85 -0
- package/runtime/validators/checks/validate-tasks-03.py +61 -0
- package/runtime/validators/checks/validate-tasks-04.py +118 -0
- package/runtime/validators/forbidden_actions.py +73 -3
- package/runtime/validators/lib/common.sh +5 -0
- package/runtime/validators/lib/fixtures.sh +7 -591
- package/runtime/validators/lib/paths.sh +13 -0
- package/runtime/validators/lib/runners.sh +6 -104
- package/runtime/validators/lib/summary.sh +1 -1
- package/runtime/validators/lib/validate-assets.sh +6 -56
- package/runtime/validators/lib/validate-prompt-metadata.sh +6 -257
- package/runtime/validators/lib/validate-tasks.sh +9 -294
- package/runtime/validators/validate-implementation-plan-stages.py +4 -4
- package/runtime/validators/validate-run.py +1363 -2643
- package/runtime/validators/validate-workflow.sh +56 -16
- package/runtime/validators/validate_improvement_report.py +2 -1
- package/runtime/validators/validate_session_conformance.py +295 -49
- package/dist/commands/execute/agent-prompt.d.mts +0 -1
- package/dist/commands/execute/agent-prompt.mjs +0 -24
- package/dist/commands/execute/agent-prompt.mjs.map +0 -1
- package/dist/commands/execute/codex-dispatch.d.mts +0 -3
- package/dist/commands/execute/codex-dispatch.mjs +0 -6
- package/dist/commands/execute/codex-dispatch.mjs.map +0 -1
- package/dist/commands/execute/codex-run.d.mts +0 -3
- package/dist/commands/execute/codex-run.mjs +0 -62
- package/dist/commands/execute/codex-run.mjs.map +0 -1
- package/dist/commands/execute/convergence.d.mts +0 -1
- package/dist/commands/execute/convergence.mjs +0 -38
- package/dist/commands/execute/convergence.mjs.map +0 -1
- package/dist/commands/execute/error-log.d.mts +0 -1
- package/dist/commands/execute/error-log.mjs +0 -18
- package/dist/commands/execute/error-log.mjs.map +0 -1
- package/dist/commands/execute/git-reconcile.d.mts +0 -1
- package/dist/commands/execute/git-reconcile.mjs +0 -30
- package/dist/commands/execute/git-reconcile.mjs.map +0 -1
- package/dist/commands/execute/handoff.d.mts +0 -1
- package/dist/commands/execute/handoff.mjs +0 -31
- package/dist/commands/execute/handoff.mjs.map +0 -1
- package/dist/commands/execute/incremental-carry.d.mts +0 -1
- package/dist/commands/execute/incremental-carry.mjs +0 -20
- package/dist/commands/execute/incremental-carry.mjs.map +0 -1
- package/dist/commands/execute/incremental-scope.d.mts +0 -1
- package/dist/commands/execute/incremental-scope.mjs +0 -29
- package/dist/commands/execute/incremental-scope.mjs.map +0 -1
- package/dist/commands/execute/integrate-stages.d.mts +0 -1
- package/dist/commands/execute/integrate-stages.mjs +0 -24
- package/dist/commands/execute/integrate-stages.mjs.map +0 -1
- package/dist/commands/execute/pane-title.d.mts +0 -1
- package/dist/commands/execute/pane-title.mjs +0 -20
- package/dist/commands/execute/pane-title.mjs.map +0 -1
- package/dist/commands/execute/plan-items.d.mts +0 -1
- package/dist/commands/execute/plan-items.mjs +0 -9
- package/dist/commands/execute/plan-items.mjs.map +0 -1
- package/dist/commands/execute/plan-validate.d.mts +0 -1
- package/dist/commands/execute/plan-validate.mjs +0 -68
- package/dist/commands/execute/plan-validate.mjs.map +0 -1
- package/dist/commands/execute/plan-verify.d.mts +0 -1
- package/dist/commands/execute/plan-verify.mjs +0 -43
- package/dist/commands/execute/plan-verify.mjs.map +0 -1
- package/dist/commands/execute/spawn-followups.d.mts +0 -1
- package/dist/commands/execute/spawn-followups.mjs +0 -22
- package/dist/commands/execute/spawn-followups.mjs.map +0 -1
- package/dist/commands/execute/team.d.mts +0 -3
- package/dist/commands/execute/team.mjs +0 -66
- package/dist/commands/execute/team.mjs.map +0 -1
- package/dist/commands/execute/token-usage.d.mts +0 -1
- package/dist/commands/execute/token-usage.mjs +0 -19
- package/dist/commands/execute/token-usage.mjs.map +0 -1
- package/dist/commands/execute/worker-audit-check.d.mts +0 -1
- package/dist/commands/execute/worker-audit-check.mjs +0 -34
- package/dist/commands/execute/worker-audit-check.mjs.map +0 -1
- package/dist/commands/execute/worker-dispatch.d.mts +0 -7
- package/dist/commands/execute/worker-dispatch.mjs +0 -64
- package/dist/commands/execute/worker-dispatch.mjs.map +0 -1
- package/dist/commands/execute/worker-state.d.mts +0 -1
- package/dist/commands/execute/worker-state.mjs +0 -28
- package/dist/commands/execute/worker-state.mjs.map +0 -1
- package/dist/commands/execute/worktree-lookup.d.mts +0 -1
- package/dist/commands/execute/worktree-lookup.mjs +0 -92
- package/dist/commands/execute/worktree-lookup.mjs.map +0 -1
- package/dist/commands/execute/worktree-status.d.mts +0 -1
- package/dist/commands/execute/worktree-status.mjs +0 -121
- package/dist/commands/execute/worktree-status.mjs.map +0 -1
- package/dist/commands/inspect/code-review.d.mts +0 -1
- package/dist/commands/inspect/code-review.mjs +0 -32
- package/dist/commands/inspect/code-review.mjs.map +0 -1
- package/dist/commands/inspect/container.d.mts +0 -1
- package/dist/commands/inspect/container.mjs +0 -25
- package/dist/commands/inspect/container.mjs.map +0 -1
- package/dist/commands/inspect/context-cost.d.mts +0 -1
- package/dist/commands/inspect/context-cost.mjs +0 -25
- package/dist/commands/inspect/context-cost.mjs.map +0 -1
- package/dist/commands/inspect/design-prep.d.mts +0 -1
- package/dist/commands/inspect/design-prep.mjs +0 -22
- package/dist/commands/inspect/design-prep.mjs.map +0 -1
- package/dist/commands/inspect/error-report.d.mts +0 -1
- package/dist/commands/inspect/error-report.mjs +0 -25
- package/dist/commands/inspect/error-report.mjs.map +0 -1
- package/dist/commands/inspect/error-zip.d.mts +0 -1
- package/dist/commands/inspect/error-zip.mjs +0 -24
- package/dist/commands/inspect/error-zip.mjs.map +0 -1
- package/dist/commands/inspect/log-report.d.mts +0 -1
- package/dist/commands/inspect/log-report.mjs +0 -26
- package/dist/commands/inspect/log-report.mjs.map +0 -1
- package/dist/commands/inspect/model-io.d.mts +0 -1
- package/dist/commands/inspect/model-io.mjs +0 -25
- package/dist/commands/inspect/model-io.mjs.map +0 -1
- package/dist/commands/inspect/profile-show.d.mts +0 -1
- package/dist/commands/inspect/profile-show.mjs +0 -28
- package/dist/commands/inspect/profile-show.mjs.map +0 -1
- package/dist/commands/inspect/recap.d.mts +0 -1
- package/dist/commands/inspect/recap.mjs +0 -30
- package/dist/commands/inspect/recap.mjs.map +0 -1
- package/dist/commands/inspect/resolve-task-key.d.mts +0 -1
- package/dist/commands/inspect/resolve-task-key.mjs +0 -24
- package/dist/commands/inspect/resolve-task-key.mjs.map +0 -1
- package/dist/commands/inspect/rollup.d.mts +0 -1
- package/dist/commands/inspect/rollup.mjs +0 -25
- package/dist/commands/inspect/rollup.mjs.map +0 -1
- package/dist/commands/inspect/run-audit.d.mts +0 -1
- package/dist/commands/inspect/run-audit.mjs +0 -25
- package/dist/commands/inspect/run-audit.mjs.map +0 -1
- package/dist/commands/inspect/set-work-status.d.mts +0 -1
- package/dist/commands/inspect/set-work-status.mjs +0 -29
- package/dist/commands/inspect/set-work-status.mjs.map +0 -1
- package/dist/commands/inspect/stage-map.d.mts +0 -1
- package/dist/commands/inspect/stage-map.mjs +0 -131
- package/dist/commands/inspect/stage-map.mjs.map +0 -1
- package/dist/commands/inspect/task-list.d.mts +0 -1
- package/dist/commands/inspect/task-list.mjs +0 -149
- package/dist/commands/inspect/task-list.mjs.map +0 -1
- package/dist/commands/inspect/task-show.d.mts +0 -1
- package/dist/commands/inspect/task-show.mjs +0 -108
- package/dist/commands/inspect/task-show.mjs.map +0 -1
- package/dist/commands/inspect/time-report.d.mts +0 -1
- package/dist/commands/inspect/time-report.mjs +0 -24
- package/dist/commands/inspect/time-report.mjs.map +0 -1
- package/dist/commands/inspect/usage-report.d.mts +0 -1
- package/dist/commands/inspect/usage-report.mjs +0 -23
- package/dist/commands/inspect/usage-report.mjs.map +0 -1
- package/dist/commands/inspect/user-response.d.mts +0 -1
- package/dist/commands/inspect/user-response.mjs +0 -35
- package/dist/commands/inspect/user-response.mjs.map +0 -1
- package/dist/commands/inspect/worker-liveness.d.mts +0 -1
- package/dist/commands/inspect/worker-liveness.mjs +0 -45
- package/dist/commands/inspect/worker-liveness.mjs.map +0 -1
- package/dist/commands/lifecycle/contract-check.d.mts +0 -1
- package/dist/commands/lifecycle/contract-check.mjs +0 -18
- package/dist/commands/lifecycle/contract-check.mjs.map +0 -1
- package/dist/commands/lifecycle/migrate.d.mts +0 -1
- package/dist/commands/lifecycle/migrate.mjs +0 -30
- package/dist/commands/lifecycle/migrate.mjs.map +0 -1
- package/dist/commands/lifecycle/model.d.mts +0 -1
- package/dist/commands/lifecycle/model.mjs +0 -22
- package/dist/commands/lifecycle/model.mjs.map +0 -1
- package/dist/commands/manager.d.mts +0 -3
- package/dist/commands/manager.mjs +0 -50
- package/dist/commands/manager.mjs.map +0 -1
- package/dist/commands/report/agent-activity.d.mts +0 -1
- package/dist/commands/report/agent-activity.mjs +0 -20
- package/dist/commands/report/agent-activity.mjs.map +0 -1
- package/dist/commands/report/approval-decision.d.mts +0 -1
- package/dist/commands/report/approval-decision.mjs +0 -21
- package/dist/commands/report/approval-decision.mjs.map +0 -1
- package/dist/commands/report/design-snapshot.d.mts +0 -1
- package/dist/commands/report/design-snapshot.mjs +0 -19
- package/dist/commands/report/design-snapshot.mjs.map +0 -1
- package/dist/commands/report/finalize.d.mts +0 -4
- package/dist/commands/report/finalize.mjs +0 -64
- package/dist/commands/report/finalize.mjs.map +0 -1
- package/dist/commands/report/inject-report-index.d.mts +0 -1
- package/dist/commands/report/inject-report-index.mjs +0 -21
- package/dist/commands/report/inject-report-index.mjs.map +0 -1
- package/dist/commands/report/render-final-report.d.mts +0 -1
- package/dist/commands/report/render-final-report.mjs +0 -23
- package/dist/commands/report/render-final-report.mjs.map +0 -1
- package/dist/commands/report/render-views.d.mts +0 -1
- package/dist/commands/report/render-views.mjs +0 -27
- package/dist/commands/report/render-views.mjs.map +0 -1
- package/dist/commands/report/translate.d.mts +0 -1
- package/dist/commands/report/translate.mjs +0 -33
- package/dist/commands/report/translate.mjs.map +0 -1
- package/runtime/bin/lib/okstra/tmux-pane.sh +0 -40
- package/runtime/bin/lib/okstra-ctl/cmd-batch.sh +0 -59
- package/runtime/bin/lib/okstra-ctl/cmd-list.sh +0 -35
- package/runtime/bin/lib/okstra-ctl/cmd-open.sh +0 -36
- package/runtime/bin/lib/okstra-ctl/cmd-projects.sh +0 -26
- package/runtime/bin/lib/okstra-ctl/cmd-reconcile.sh +0 -29
- package/runtime/bin/lib/okstra-ctl/cmd-reindex.sh +0 -38
- package/runtime/bin/lib/okstra-ctl/cmd-rerun.sh +0 -345
- package/runtime/bin/lib/okstra-ctl/cmd-show.sh +0 -27
- package/runtime/bin/lib/okstra-ctl/cmd-tail.sh +0 -92
- package/runtime/bin/lib/okstra-ctl/main.sh +0 -41
- package/runtime/bin/lib/okstra-ctl/prepare.sh +0 -31
- package/runtime/bin/lib/okstra-ctl/usage.sh +0 -23
- package/runtime/bin/okstra-central.sh +0 -152
- package/runtime/bin/okstra-incremental-carry.py +0 -10
- package/runtime/bin/okstra-incremental-scope.py +0 -10
- package/runtime/bin/okstra-team-reconcile.sh +0 -36
- package/runtime/python/okstra_ctl/agent_prompt_cli.py +0 -1156
- package/runtime/python/okstra_ctl/batch.py +0 -60
- package/runtime/python/okstra_ctl/clarification_items.py +0 -1050
- package/runtime/python/okstra_ctl/container_registry.py +0 -72
- package/runtime/python/okstra_ctl/improvement_assignment.py +0 -61
- package/runtime/python/okstra_ctl/resolver.py +0 -54
- package/runtime/python/okstra_ctl/team_reconcile.py +0 -275
- package/runtime/python/okstra_ctl/tmux.py +0 -134
- package/runtime/python/okstra_ctl/worktree.py +0 -1099
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""`python3 -m okstra_ctl.agent.prompt_cli` 진입점.
|
|
2
|
+
|
|
3
|
+
CLI 레지스트리(`src/cli-registry.mts`)가 이 모듈을 `-m` 으로 띄운다. 단일
|
|
4
|
+
파일이던 시절에는 모듈 본문 끝의 `__name__` 가드가 그 역할을 했고, 패키지가
|
|
5
|
+
되면서 그 자리가 여기로 왔다.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from .cli import main
|
|
10
|
+
|
|
11
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"""argparse 표면과 명령 분배.
|
|
2
|
+
|
|
3
|
+
여기 있는 것은 인자 정의와 `main` 의 분기뿐이다. 각 명령의 실제 동작은
|
|
4
|
+
`materialize` 와 `results` 에 있다. `_CLI_EPILOG` 는 이 명령의 사용법 정본이다 —
|
|
5
|
+
TypeScript 포워더가 들고 있던 USAGE 문자열이 여기로 왔다.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
from ..invocation import AgentInvocationError
|
|
14
|
+
from ...worker_prompt_headers import WorkerPromptHeaderError
|
|
15
|
+
from ...dispatch_state import BACKEND_CLI_WRAPPER, BACKEND_CMUX_PANE, DispatchError
|
|
16
|
+
from .emit import _emit, _prepared_payload
|
|
17
|
+
from .inputs import AgentPromptCliError
|
|
18
|
+
from .materialize import _materialize
|
|
19
|
+
from .results import (
|
|
20
|
+
_complete,
|
|
21
|
+
_link_result,
|
|
22
|
+
_materialize_result,
|
|
23
|
+
_record_dispatch,
|
|
24
|
+
_abandon_attempt,
|
|
25
|
+
_reject_result,
|
|
26
|
+
_verify,
|
|
27
|
+
_verify_completion,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
_CLI_EPILOG = r"""Usage:
|
|
32
|
+
okstra agent-prompt materialize [options]
|
|
33
|
+
okstra agent-prompt verify [options]
|
|
34
|
+
okstra agent-prompt materialize-result [options]
|
|
35
|
+
okstra agent-prompt complete [options]
|
|
36
|
+
okstra agent-prompt verify-completion [options]
|
|
37
|
+
okstra agent-prompt record-dispatch [options]
|
|
38
|
+
okstra agent-prompt link-result [options]
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
_CLI_DESCRIPTION = "Materialize and verify auditable agent invocations."
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _parser() -> argparse.ArgumentParser:
|
|
46
|
+
parser = argparse.ArgumentParser(
|
|
47
|
+
description=_CLI_DESCRIPTION,
|
|
48
|
+
epilog=_CLI_EPILOG,
|
|
49
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
50
|
+
prog="okstra agent-prompt")
|
|
51
|
+
commands = parser.add_subparsers(dest="command", required=True)
|
|
52
|
+
_add_materialize_parser(commands)
|
|
53
|
+
_add_completion_parsers(commands)
|
|
54
|
+
_add_dispatch_parsers(commands)
|
|
55
|
+
return parser
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _add_materialize_parser(commands: argparse._SubParsersAction) -> None:
|
|
59
|
+
materialize = commands.add_parser("materialize")
|
|
60
|
+
_common_paths(materialize)
|
|
61
|
+
materialize.add_argument("--invocation-id", required=True)
|
|
62
|
+
materialize.add_argument("--audience", required=True)
|
|
63
|
+
materialize.add_argument("--instruction", required=True)
|
|
64
|
+
materialize.add_argument("--prompt", required=True)
|
|
65
|
+
# 두 갈래의 인자를 한 파서가 받는다. 어느 갈래의 것인지 help 에 적지 않으면
|
|
66
|
+
# `--help` 가 조건 없이 나열한 인자를 run 갈래가 거절해 놀라게 된다.
|
|
67
|
+
run_only = "run mode only (with --run-manifest)"
|
|
68
|
+
standalone_only = "standalone mode only; refused together with --run-manifest"
|
|
69
|
+
materialize.add_argument(
|
|
70
|
+
"--run-manifest",
|
|
71
|
+
help="selects run mode: identity, paths and duty snapshot come from this "
|
|
72
|
+
"manifest, and the standalone-only flags below are refused",
|
|
73
|
+
)
|
|
74
|
+
materialize.add_argument("--worker-id", help=run_only)
|
|
75
|
+
materialize.add_argument("--dispatch-kind", help=run_only)
|
|
76
|
+
materialize.add_argument("--assignment-ref", help=run_only)
|
|
77
|
+
materialize.add_argument("--source-role-execution-ref", help=run_only)
|
|
78
|
+
materialize.add_argument("--result", help=run_only)
|
|
79
|
+
materialize.add_argument(
|
|
80
|
+
"--audit-source",
|
|
81
|
+
help=run_only + "; accepted only for report-writer and translator, whose "
|
|
82
|
+
"result is not their own worker result",
|
|
83
|
+
)
|
|
84
|
+
materialize.add_argument("--host-runtime", help=standalone_only)
|
|
85
|
+
materialize.add_argument(
|
|
86
|
+
"--terminal-backend",
|
|
87
|
+
choices=(BACKEND_CLI_WRAPPER, BACKEND_CMUX_PANE),
|
|
88
|
+
help=standalone_only,
|
|
89
|
+
)
|
|
90
|
+
materialize.add_argument("--provider", help=standalone_only)
|
|
91
|
+
materialize.add_argument("--model-role", help=standalone_only)
|
|
92
|
+
materialize.add_argument("--model", default="", help=standalone_only)
|
|
93
|
+
materialize.add_argument("--purpose", help=standalone_only)
|
|
94
|
+
materialize.add_argument(
|
|
95
|
+
"--replace-undispatched",
|
|
96
|
+
action="store_true",
|
|
97
|
+
help="rewrite a prompt this invocation id already wrote, allowed only "
|
|
98
|
+
"while no dispatch has referenced it — the exit for a prompt that "
|
|
99
|
+
"failed a pre-dispatch gate and never ran. Not available for v2 "
|
|
100
|
+
"reverify prompts (--assignment-ref reverify/…): their reservation "
|
|
101
|
+
"records the prompt's input digest in the run manifest and "
|
|
102
|
+
"reservations are append-only, so a rewrite needs a fresh "
|
|
103
|
+
"invocation id and prompt path",
|
|
104
|
+
)
|
|
105
|
+
materialize.add_argument("--json", action="store_true")
|
|
106
|
+
|
|
107
|
+
verify = commands.add_parser("verify")
|
|
108
|
+
_common_paths(verify)
|
|
109
|
+
verify.add_argument("--run-manifest")
|
|
110
|
+
verify.add_argument("--metadata", required=True)
|
|
111
|
+
verify.add_argument("--json", action="store_true")
|
|
112
|
+
verify.add_argument("--text", action="store_true")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _add_completion_parsers(commands: argparse._SubParsersAction) -> None:
|
|
116
|
+
materialize_result = commands.add_parser("materialize-result")
|
|
117
|
+
_standalone_completion_args(materialize_result)
|
|
118
|
+
materialize_result.add_argument("--returned-body-file", required=True)
|
|
119
|
+
|
|
120
|
+
complete = commands.add_parser("complete")
|
|
121
|
+
_standalone_completion_args(complete)
|
|
122
|
+
|
|
123
|
+
verify_completion = commands.add_parser("verify-completion")
|
|
124
|
+
_common_paths(verify_completion)
|
|
125
|
+
verify_completion.add_argument("--purpose", required=True)
|
|
126
|
+
verify_completion.add_argument("--completion", required=True)
|
|
127
|
+
verify_completion.add_argument("--json", action="store_true")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _add_dispatch_parsers(commands: argparse._SubParsersAction) -> None:
|
|
131
|
+
record_dispatch = commands.add_parser("record-dispatch")
|
|
132
|
+
_common_paths(record_dispatch)
|
|
133
|
+
record_dispatch.add_argument("--run-manifest", required=True)
|
|
134
|
+
record_dispatch.add_argument("--metadata", required=True)
|
|
135
|
+
record_dispatch.add_argument(
|
|
136
|
+
"--enforcement-mode",
|
|
137
|
+
required=True,
|
|
138
|
+
choices=("core-pre-dispatch", "host-native-spec-link-gate"),
|
|
139
|
+
)
|
|
140
|
+
record_dispatch.add_argument("--json", action="store_true")
|
|
141
|
+
|
|
142
|
+
reject_result = commands.add_parser(
|
|
143
|
+
"reject-result",
|
|
144
|
+
help="mark a linked result rejected so a corrective re-dispatch can "
|
|
145
|
+
"claim its path",
|
|
146
|
+
)
|
|
147
|
+
_common_paths(reject_result)
|
|
148
|
+
reject_result.add_argument("--run-manifest", required=True)
|
|
149
|
+
reject_result.add_argument("--dispatch-id", required=True)
|
|
150
|
+
reject_result.add_argument("--superseded-by", required=True)
|
|
151
|
+
reject_result.add_argument("--reason", required=True)
|
|
152
|
+
reject_result.add_argument("--json", action="store_true")
|
|
153
|
+
|
|
154
|
+
abandon = commands.add_parser(
|
|
155
|
+
"abandon-attempt",
|
|
156
|
+
help="close a started source-readonly attempt whose worker died "
|
|
157
|
+
"without a result, so a retry can follow it",
|
|
158
|
+
)
|
|
159
|
+
_common_paths(abandon)
|
|
160
|
+
abandon.add_argument("--run-manifest", required=True)
|
|
161
|
+
abandon.add_argument("--invocation-ref", required=True)
|
|
162
|
+
abandon.add_argument("--reason", required=True)
|
|
163
|
+
abandon.add_argument("--json", action="store_true")
|
|
164
|
+
|
|
165
|
+
link_result = commands.add_parser("link-result")
|
|
166
|
+
_common_paths(link_result)
|
|
167
|
+
link_result.add_argument("--run-manifest", required=True)
|
|
168
|
+
link_result.add_argument("--dispatch-id", required=True)
|
|
169
|
+
link_result.add_argument("--result", required=True)
|
|
170
|
+
link_result.add_argument("--json", action="store_true")
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _common_paths(parser: argparse.ArgumentParser) -> None:
|
|
174
|
+
parser.add_argument("--project-root", required=True)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _standalone_completion_args(parser: argparse.ArgumentParser) -> None:
|
|
178
|
+
_common_paths(parser)
|
|
179
|
+
parser.add_argument("--purpose", required=True)
|
|
180
|
+
parser.add_argument("--metadata", required=True)
|
|
181
|
+
parser.add_argument("--json", action="store_true")
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def main(argv: list[str] | None = None) -> int:
|
|
185
|
+
try:
|
|
186
|
+
args = _parser().parse_args(argv)
|
|
187
|
+
if args.command == "materialize":
|
|
188
|
+
prepared = _materialize(args)
|
|
189
|
+
_emit(_prepared_payload(prepared, args.audience), args.json)
|
|
190
|
+
return 0
|
|
191
|
+
if args.command == "verify":
|
|
192
|
+
_verify(args)
|
|
193
|
+
_emit(
|
|
194
|
+
{"ok": True, "metadataPath": str(Path(args.metadata).resolve())},
|
|
195
|
+
args.json,
|
|
196
|
+
args.text,
|
|
197
|
+
)
|
|
198
|
+
return 0
|
|
199
|
+
if args.command == "materialize-result":
|
|
200
|
+
_materialize_result(args)
|
|
201
|
+
return 0
|
|
202
|
+
if args.command == "complete":
|
|
203
|
+
_complete(args)
|
|
204
|
+
return 0
|
|
205
|
+
if args.command == "verify-completion":
|
|
206
|
+
_verify_completion(args)
|
|
207
|
+
return 0
|
|
208
|
+
if args.command == "record-dispatch":
|
|
209
|
+
_record_dispatch(args)
|
|
210
|
+
return 0
|
|
211
|
+
if args.command == "reject-result":
|
|
212
|
+
_reject_result(args)
|
|
213
|
+
return 0
|
|
214
|
+
if args.command == "abandon-attempt":
|
|
215
|
+
_abandon_attempt(args)
|
|
216
|
+
return 0
|
|
217
|
+
_link_result(args)
|
|
218
|
+
return 0
|
|
219
|
+
except (
|
|
220
|
+
AgentPromptCliError,
|
|
221
|
+
AgentInvocationError,
|
|
222
|
+
DispatchError,
|
|
223
|
+
WorkerPromptHeaderError,
|
|
224
|
+
OSError,
|
|
225
|
+
ValueError,
|
|
226
|
+
) as exc:
|
|
227
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
228
|
+
return 2
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""동적 검증자 요청을 예약하고, 그 출처가 자격이 있는지 본다.
|
|
2
|
+
|
|
3
|
+
재검증 라운드에서 리드가 추가 검증자를 요청할 수 있고, 그 요청은 예약(슬롯
|
|
4
|
+
확보)과 자격 검사(요청한 role 이 이 run 에서 그럴 수 있는가)를 함께 통과해야
|
|
5
|
+
한다. 두 가지가 한 파일에 있는 이유는 예약이 자격 검사를 통과한 뒤에만
|
|
6
|
+
일어나야 하기 때문이다 — 순서가 곧 계약이다.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
from dataclasses import replace
|
|
12
|
+
import hashlib
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any, Mapping
|
|
15
|
+
|
|
16
|
+
from ..invocation import (
|
|
17
|
+
AgentInvocationRequest,
|
|
18
|
+
AgentModelAssignment,
|
|
19
|
+
compose_agent_prompt,
|
|
20
|
+
compose_unbound_run_prompt,
|
|
21
|
+
v2_role_assignment_authority_errors,
|
|
22
|
+
)
|
|
23
|
+
from ...convergence_store import (
|
|
24
|
+
DYNAMIC_VERIFIER_SOURCE_ROLES,
|
|
25
|
+
reserve_dynamic_verifier,
|
|
26
|
+
)
|
|
27
|
+
from .inputs import AgentPromptCliError
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _reserve_dynamic_verifier_request(
|
|
31
|
+
request: AgentInvocationRequest,
|
|
32
|
+
*,
|
|
33
|
+
args: argparse.Namespace,
|
|
34
|
+
manifest: Mapping[str, Any],
|
|
35
|
+
manifest_path: Path,
|
|
36
|
+
source_role_execution_ref: str,
|
|
37
|
+
) -> AgentInvocationRequest:
|
|
38
|
+
_validate_dynamic_source_assignment(
|
|
39
|
+
manifest,
|
|
40
|
+
source_role_execution_ref,
|
|
41
|
+
request.assignment,
|
|
42
|
+
)
|
|
43
|
+
prompt_bytes = compose_unbound_run_prompt(request)
|
|
44
|
+
verifier, invocation = reserve_dynamic_verifier(
|
|
45
|
+
manifest_path,
|
|
46
|
+
source_role_execution_ref=source_role_execution_ref,
|
|
47
|
+
duty_id=args.audience,
|
|
48
|
+
round_number=_reverify_round(args.dispatch_kind),
|
|
49
|
+
task_key=_required_manifest_string(manifest, "taskKey"),
|
|
50
|
+
input_digest="sha256:" + hashlib.sha256(prompt_bytes).hexdigest(),
|
|
51
|
+
invocation_ref=args.invocation_id,
|
|
52
|
+
)
|
|
53
|
+
bound = replace(
|
|
54
|
+
request,
|
|
55
|
+
worker_id=None,
|
|
56
|
+
participant_ref=verifier.participant_ref,
|
|
57
|
+
role_execution_ref=verifier.role_execution_ref,
|
|
58
|
+
duty_id=args.audience,
|
|
59
|
+
invocation_ref=invocation.invocation_ref,
|
|
60
|
+
)
|
|
61
|
+
if compose_agent_prompt(bound).encode("utf-8") != prompt_bytes:
|
|
62
|
+
raise AgentPromptCliError(
|
|
63
|
+
"dynamic verifier identity changed immutable prompt bytes"
|
|
64
|
+
)
|
|
65
|
+
return bound
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _dynamic_verifier_source(
|
|
69
|
+
args: argparse.Namespace,
|
|
70
|
+
manifest: Mapping[str, Any],
|
|
71
|
+
) -> str | None:
|
|
72
|
+
is_v2 = (
|
|
73
|
+
manifest.get("schemaVersion") == "2.0"
|
|
74
|
+
and manifest.get("executionIdentityVersion") == 2
|
|
75
|
+
)
|
|
76
|
+
is_reverify = (
|
|
77
|
+
args.assignment_ref.startswith("reverify/")
|
|
78
|
+
and args.audience == "reverification-worker"
|
|
79
|
+
)
|
|
80
|
+
source = args.source_role_execution_ref
|
|
81
|
+
if is_v2 and is_reverify:
|
|
82
|
+
if args.replace_undispatched:
|
|
83
|
+
raise AgentPromptCliError(
|
|
84
|
+
"v2 dynamic verifier prompts are append-only: this "
|
|
85
|
+
"invocation's reservation already recorded this prompt's input "
|
|
86
|
+
"digest in the run manifest, and a reservation cannot be "
|
|
87
|
+
"rewritten. Use a fresh invocation ID and prompt path."
|
|
88
|
+
)
|
|
89
|
+
if not source:
|
|
90
|
+
raise AgentPromptCliError(
|
|
91
|
+
"v2 reverify materialization requires "
|
|
92
|
+
"--source-role-execution-ref"
|
|
93
|
+
)
|
|
94
|
+
return source
|
|
95
|
+
if source:
|
|
96
|
+
raise AgentPromptCliError(
|
|
97
|
+
"--source-role-execution-ref is allowed only for v2 reverify"
|
|
98
|
+
)
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _reverify_round(dispatch_kind: str) -> int:
|
|
103
|
+
prefix = "reverify-r"
|
|
104
|
+
value = dispatch_kind.removeprefix(prefix)
|
|
105
|
+
if not dispatch_kind.startswith(prefix) or not value.isdigit() or int(value) < 1:
|
|
106
|
+
raise AgentPromptCliError(
|
|
107
|
+
"dynamic verifier dispatch kind must be reverify-r<N>"
|
|
108
|
+
)
|
|
109
|
+
return int(value)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _validate_dynamic_source_assignment(
|
|
113
|
+
manifest: Mapping[str, Any],
|
|
114
|
+
source_role_execution_ref: str,
|
|
115
|
+
assignment: AgentModelAssignment,
|
|
116
|
+
) -> None:
|
|
117
|
+
rows = manifest.get("roleExecutions")
|
|
118
|
+
source = next(
|
|
119
|
+
(
|
|
120
|
+
row
|
|
121
|
+
for row in rows
|
|
122
|
+
if isinstance(row, Mapping)
|
|
123
|
+
and row.get("roleExecutionRef") == source_role_execution_ref
|
|
124
|
+
),
|
|
125
|
+
None,
|
|
126
|
+
) if isinstance(rows, list) else None
|
|
127
|
+
if source is None:
|
|
128
|
+
raise AgentPromptCliError(
|
|
129
|
+
f"source role execution is unknown: {source_role_execution_ref}"
|
|
130
|
+
)
|
|
131
|
+
if source.get("role") not in DYNAMIC_VERIFIER_SOURCE_ROLES:
|
|
132
|
+
raise AgentPromptCliError(
|
|
133
|
+
"dynamic verifier source role is not eligible for re-verification"
|
|
134
|
+
)
|
|
135
|
+
errors = v2_role_assignment_authority_errors(
|
|
136
|
+
manifest,
|
|
137
|
+
role_execution_ref=source_role_execution_ref,
|
|
138
|
+
participant_ref=str(source.get("participantRef") or ""),
|
|
139
|
+
assignment=assignment,
|
|
140
|
+
)
|
|
141
|
+
if errors:
|
|
142
|
+
raise AgentPromptCliError(
|
|
143
|
+
"dynamic verifier source does not match the selected assignment: "
|
|
144
|
+
+ "; ".join(errors)
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _required_manifest_string(
|
|
149
|
+
manifest: Mapping[str, Any],
|
|
150
|
+
key: str,
|
|
151
|
+
) -> str:
|
|
152
|
+
value = manifest.get(key)
|
|
153
|
+
if not isinstance(value, str) or not value.strip():
|
|
154
|
+
raise AgentPromptCliError(f"run manifest has no {key}")
|
|
155
|
+
return value
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""명령의 결과를 표준 출력으로 내보낸다.
|
|
2
|
+
|
|
3
|
+
`--json` 이면 JSON, 아니면 고정 Markdown 줄이다. 두 형태를 한자리에 둬서
|
|
4
|
+
명령마다 출력 모양이 갈라지지 않게 한다. 파일을 읽지도 쓰지도 않는다.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
from typing import Mapping
|
|
10
|
+
|
|
11
|
+
from ..invocation import PreparedAgentInvocation
|
|
12
|
+
from ...fixed_text import line
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _prepared_payload(
|
|
17
|
+
prepared: PreparedAgentInvocation,
|
|
18
|
+
audience: str,
|
|
19
|
+
) -> dict[str, object]:
|
|
20
|
+
assignment = prepared.assignment
|
|
21
|
+
return {
|
|
22
|
+
"ok": True,
|
|
23
|
+
"invocationId": prepared.invocation_id,
|
|
24
|
+
"workerId": prepared.worker_id,
|
|
25
|
+
"assignmentRef": prepared.assignment_ref,
|
|
26
|
+
"audience": audience,
|
|
27
|
+
"promptPath": str(prepared.prompt_path),
|
|
28
|
+
"metadataPath": str(prepared.metadata_path),
|
|
29
|
+
"modelAssignment": {
|
|
30
|
+
"provider": assignment.provider,
|
|
31
|
+
"model": assignment.model,
|
|
32
|
+
"modelExecutionValue": assignment.model_execution_value,
|
|
33
|
+
"runner": assignment.runner,
|
|
34
|
+
"hostRuntime": assignment.host_runtime,
|
|
35
|
+
"hostModelValue": assignment.host_model_value,
|
|
36
|
+
},
|
|
37
|
+
"digests": {
|
|
38
|
+
"catalogDigest": prepared.catalog_digest,
|
|
39
|
+
"assignmentDigest": prepared.assignment_digest,
|
|
40
|
+
"dutyDigest": prepared.duty_digest,
|
|
41
|
+
"instructionDigest": prepared.instruction_digest,
|
|
42
|
+
"promptDigest": prepared.prompt_digest,
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _emit(
|
|
48
|
+
payload: Mapping[str, object], as_json: bool, as_text: bool = False
|
|
49
|
+
) -> None:
|
|
50
|
+
if as_json:
|
|
51
|
+
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
|
52
|
+
elif as_text:
|
|
53
|
+
print(render_agent_prompt_text(payload), end="")
|
|
54
|
+
else:
|
|
55
|
+
print(payload.get("promptPath") or payload.get("metadataPath") or "ok")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def render_agent_prompt_text(payload: Mapping[str, object]) -> str:
|
|
59
|
+
"""agent prompt 검증 결과의 승인된 경로만 투영한다."""
|
|
60
|
+
rows = ["Okstra agent prompt\n"]
|
|
61
|
+
rows.append(line("Status", "ready" if payload.get("ok", True) else "error"))
|
|
62
|
+
for label, key in (("Prompt path", "promptPath"), ("Metadata path", "metadataPath"),
|
|
63
|
+
("Assignment ID", "assignmentId"), ("Worker role", "workerRole")):
|
|
64
|
+
if key in payload:
|
|
65
|
+
rows.append(line(label, payload.get(key)))
|
|
66
|
+
return "".join(rows)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""명령이 받은 경로를 해석하고, 허용된 것만 돌려준다.
|
|
2
|
+
|
|
3
|
+
이 CLI 는 모델이 부르는 표면이라 경로 인자를 그대로 믿을 수 없다. 여기 있는
|
|
4
|
+
함수들은 전부 같은 모양이다 — 받은 문자열을 절대 경로로 만들고, 프로젝트
|
|
5
|
+
루트(또는 명시된 상위) 안에 있는지 확인하고, 벗어나면 거절한다. 어느 것도
|
|
6
|
+
okstra 의 phase 나 role 을 모른다.
|
|
7
|
+
|
|
8
|
+
`AgentPromptCliError` 도 여기 있다. 모든 층이 이 하나로 실패를 알린다.
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from pathlib import PurePosixPath
|
|
14
|
+
from typing import Any, Mapping
|
|
15
|
+
|
|
16
|
+
from ...json_boundary import JsonBoundaryError, load_owned_object
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AgentPromptCliError(RuntimeError):
|
|
21
|
+
"""Raised when CLI input cannot become a valid invocation request."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _authorized_path(
|
|
25
|
+
project_root: Path,
|
|
26
|
+
raw_path: str,
|
|
27
|
+
raw_roots: object,
|
|
28
|
+
label: str,
|
|
29
|
+
*,
|
|
30
|
+
must_exist: bool,
|
|
31
|
+
) -> Path:
|
|
32
|
+
if not isinstance(raw_roots, list) or not raw_roots:
|
|
33
|
+
raise AgentPromptCliError(f"run manifest has no authorized {label} roots")
|
|
34
|
+
path = _candidate(project_root, raw_path, must_exist=must_exist, label=label)
|
|
35
|
+
roots = [
|
|
36
|
+
_project_manifest_path(project_root, value, f"{label} root", must_exist=True)
|
|
37
|
+
for value in raw_roots
|
|
38
|
+
]
|
|
39
|
+
if not any(_is_relative_to(path, root) for root in roots):
|
|
40
|
+
raise AgentPromptCliError(f"{label} path is outside authorized roots: {path}")
|
|
41
|
+
return path
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _candidate(project_root: Path, raw: str, *, must_exist: bool, label: str) -> Path:
|
|
45
|
+
candidate = Path(raw)
|
|
46
|
+
if not candidate.is_absolute():
|
|
47
|
+
candidate = project_root / candidate
|
|
48
|
+
try:
|
|
49
|
+
if must_exist or candidate.exists() or candidate.is_symlink():
|
|
50
|
+
return candidate.resolve(strict=True)
|
|
51
|
+
return candidate.parent.resolve(strict=True) / candidate.name
|
|
52
|
+
except OSError as exc:
|
|
53
|
+
raise AgentPromptCliError(f"{label} path is invalid: {candidate}") from exc
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _project_input(project_root: Path, raw: str, label: str) -> Path:
|
|
57
|
+
path = _candidate(project_root, raw, must_exist=True, label=label)
|
|
58
|
+
if not _is_relative_to(path, project_root):
|
|
59
|
+
raise AgentPromptCliError(f"{label} path escapes project root: {path}")
|
|
60
|
+
return path
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _project_manifest_path(
|
|
64
|
+
project_root: Path,
|
|
65
|
+
value: object,
|
|
66
|
+
label: str,
|
|
67
|
+
*,
|
|
68
|
+
must_exist: bool,
|
|
69
|
+
) -> Path:
|
|
70
|
+
if not isinstance(value, str) or not value:
|
|
71
|
+
raise AgentPromptCliError(f"{label} path is invalid")
|
|
72
|
+
pure = PurePosixPath(value)
|
|
73
|
+
if pure.is_absolute() or any(part in {"", ".", ".."} for part in pure.parts):
|
|
74
|
+
raise AgentPromptCliError(f"{label} path is invalid")
|
|
75
|
+
path = _candidate(project_root, value, must_exist=must_exist, label=label)
|
|
76
|
+
if not _is_relative_to(path, project_root):
|
|
77
|
+
raise AgentPromptCliError(f"{label} path escapes project root: {path}")
|
|
78
|
+
return path
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _exact_path(raw: str, expected: Path, must_exist: bool, label: str) -> Path:
|
|
82
|
+
actual = (
|
|
83
|
+
Path(raw).resolve(strict=True)
|
|
84
|
+
if must_exist
|
|
85
|
+
else Path(raw).parent.resolve(strict=True) / Path(raw).name
|
|
86
|
+
)
|
|
87
|
+
expected_actual = (
|
|
88
|
+
expected.resolve(strict=True)
|
|
89
|
+
if must_exist
|
|
90
|
+
else expected.parent.resolve(strict=True) / expected.name
|
|
91
|
+
)
|
|
92
|
+
if actual != expected_actual:
|
|
93
|
+
raise AgentPromptCliError(f"{label} does not use canonical standalone path")
|
|
94
|
+
return actual
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _project_root(value: str) -> Path:
|
|
98
|
+
try:
|
|
99
|
+
return Path(value).resolve(strict=True)
|
|
100
|
+
except OSError as exc:
|
|
101
|
+
raise AgentPromptCliError(f"project root not found: {value}") from exc
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _relative(project_root: Path, path: Path) -> str:
|
|
105
|
+
try:
|
|
106
|
+
return path.relative_to(project_root).as_posix()
|
|
107
|
+
except ValueError as exc:
|
|
108
|
+
raise AgentPromptCliError(f"path escapes project root: {path}") from exc
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _read_json_object(path: Path, label: str) -> dict[str, Any]:
|
|
112
|
+
try:
|
|
113
|
+
value = load_owned_object(path, artifact="agent prompt metadata")
|
|
114
|
+
except JsonBoundaryError as exc:
|
|
115
|
+
raise AgentPromptCliError(f"{label} is invalid: {path}") from exc
|
|
116
|
+
if not isinstance(value, dict):
|
|
117
|
+
raise AgentPromptCliError(f"{label} must be a JSON object: {path}")
|
|
118
|
+
return value
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _mapping(value: object, label: str) -> Mapping[str, Any]:
|
|
122
|
+
if not isinstance(value, Mapping):
|
|
123
|
+
raise AgentPromptCliError(f"{label} is missing or invalid")
|
|
124
|
+
return value
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _is_relative_to(path: Path, root: Path) -> bool:
|
|
128
|
+
try:
|
|
129
|
+
path.relative_to(root)
|
|
130
|
+
except ValueError:
|
|
131
|
+
return False
|
|
132
|
+
return True
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _is_slug(value: str) -> bool:
|
|
136
|
+
if not value or value.startswith("-") or value.endswith("-"):
|
|
137
|
+
return False
|
|
138
|
+
return all(part.isalnum() and part.lower() == part for part in value.split("-"))
|