okstra 0.174.0 → 0.176.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 +18 -9
- package/bin/okstra +8 -4
- package/dist/cli-registry.d.mts +16 -0
- package/dist/cli-registry.mjs +560 -0
- package/dist/cli-registry.mjs.map +1 -0
- package/dist/commands/execute/agent-prompt.d.mts +1 -0
- package/{src → dist}/commands/execute/agent-prompt.mjs +10 -11
- package/dist/commands/execute/agent-prompt.mjs.map +1 -0
- package/dist/commands/execute/codex-dispatch.d.mts +3 -0
- package/dist/commands/execute/codex-dispatch.mjs +6 -0
- package/dist/commands/execute/codex-dispatch.mjs.map +1 -0
- package/dist/commands/execute/codex-run.d.mts +3 -0
- package/{src → dist}/commands/execute/codex-run.mjs +30 -37
- package/dist/commands/execute/codex-run.mjs.map +1 -0
- package/dist/commands/execute/convergence.d.mts +1 -0
- package/{src → dist}/commands/execute/convergence.mjs +15 -16
- package/dist/commands/execute/convergence.mjs.map +1 -0
- package/dist/commands/execute/error-log.d.mts +1 -0
- package/{src → dist}/commands/execute/error-log.mjs +2 -3
- package/dist/commands/execute/error-log.mjs.map +1 -0
- package/dist/commands/execute/git-reconcile.d.mts +1 -0
- package/{src → dist}/commands/execute/git-reconcile.mjs +10 -11
- package/dist/commands/execute/git-reconcile.mjs.map +1 -0
- package/dist/commands/execute/handoff.d.mts +1 -0
- package/{src → dist}/commands/execute/handoff.mjs +10 -11
- package/dist/commands/execute/handoff.mjs.map +1 -0
- package/dist/commands/execute/incremental-carry.d.mts +1 -0
- package/{src → dist}/commands/execute/incremental-carry.mjs +2 -3
- package/dist/commands/execute/incremental-carry.mjs.map +1 -0
- package/dist/commands/execute/incremental-scope.d.mts +1 -0
- package/{src → dist}/commands/execute/incremental-scope.mjs +2 -3
- package/dist/commands/execute/incremental-scope.mjs.map +1 -0
- package/dist/commands/execute/integrate-stages.d.mts +1 -0
- package/{src → dist}/commands/execute/integrate-stages.mjs +10 -11
- package/dist/commands/execute/integrate-stages.mjs.map +1 -0
- package/dist/commands/execute/pane-title.d.mts +1 -0
- package/dist/commands/execute/pane-title.mjs +20 -0
- package/dist/commands/execute/pane-title.mjs.map +1 -0
- package/dist/commands/execute/plan-items.d.mts +1 -0
- package/dist/commands/execute/plan-items.mjs +9 -0
- package/dist/commands/execute/plan-items.mjs.map +1 -0
- package/dist/commands/execute/plan-validate.d.mts +1 -0
- package/dist/commands/execute/plan-validate.mjs +68 -0
- package/dist/commands/execute/plan-validate.mjs.map +1 -0
- package/dist/commands/execute/plan-verify.d.mts +1 -0
- package/{src → dist}/commands/execute/plan-verify.mjs +13 -16
- package/dist/commands/execute/plan-verify.mjs.map +1 -0
- package/dist/commands/execute/render-bundle.d.mts +3 -0
- package/{src → dist}/commands/execute/render-bundle.mjs +65 -61
- package/dist/commands/execute/render-bundle.mjs.map +1 -0
- package/dist/commands/execute/run.d.mts +24 -0
- package/dist/commands/execute/run.mjs +196 -0
- package/dist/commands/execute/run.mjs.map +1 -0
- package/dist/commands/execute/spawn-followups.d.mts +1 -0
- package/{src → dist}/commands/execute/spawn-followups.mjs +6 -7
- package/dist/commands/execute/spawn-followups.mjs.map +1 -0
- package/dist/commands/execute/team.d.mts +3 -0
- package/{src → dist}/commands/execute/team.mjs +29 -36
- package/dist/commands/execute/team.mjs.map +1 -0
- package/dist/commands/execute/token-usage.d.mts +1 -0
- package/{src → dist}/commands/execute/token-usage.mjs +2 -3
- package/dist/commands/execute/token-usage.mjs.map +1 -0
- package/dist/commands/execute/wizard.d.mts +8 -0
- package/dist/commands/execute/wizard.mjs +191 -0
- package/dist/commands/execute/wizard.mjs.map +1 -0
- package/dist/commands/execute/worker-audit-check.d.mts +1 -0
- package/{src → dist}/commands/execute/worker-audit-check.mjs +11 -12
- package/dist/commands/execute/worker-audit-check.mjs.map +1 -0
- package/dist/commands/execute/worker-dispatch.d.mts +7 -0
- package/{src → dist}/commands/execute/worker-dispatch.mjs +34 -46
- package/dist/commands/execute/worker-dispatch.mjs.map +1 -0
- package/dist/commands/execute/worker-state.d.mts +1 -0
- package/{src → dist}/commands/execute/worker-state.mjs +15 -16
- package/dist/commands/execute/worker-state.mjs.map +1 -0
- package/dist/commands/execute/worktree-lookup.d.mts +1 -0
- package/{src → dist}/commands/execute/worktree-lookup.mjs +38 -37
- package/dist/commands/execute/worktree-lookup.mjs.map +1 -0
- package/dist/commands/execute/worktree-status.d.mts +1 -0
- package/{src → dist}/commands/execute/worktree-status.mjs +52 -46
- package/dist/commands/execute/worktree-status.mjs.map +1 -0
- package/dist/commands/inspect/code-review.d.mts +1 -0
- package/{src → dist}/commands/inspect/code-review.mjs +16 -19
- package/dist/commands/inspect/code-review.mjs.map +1 -0
- package/dist/commands/inspect/container.d.mts +1 -0
- package/{src → dist}/commands/inspect/container.mjs +11 -13
- package/dist/commands/inspect/container.mjs.map +1 -0
- package/dist/commands/inspect/context-cost.d.mts +1 -0
- package/{src → dist}/commands/inspect/context-cost.mjs +11 -13
- package/dist/commands/inspect/context-cost.mjs.map +1 -0
- package/dist/commands/inspect/design-prep.d.mts +1 -0
- package/{src → dist}/commands/inspect/design-prep.mjs +10 -11
- package/dist/commands/inspect/design-prep.mjs.map +1 -0
- package/dist/commands/inspect/error-report.d.mts +1 -0
- package/{src → dist}/commands/inspect/error-report.mjs +11 -13
- package/dist/commands/inspect/error-report.mjs.map +1 -0
- package/dist/commands/inspect/error-zip.d.mts +1 -0
- package/{src → dist}/commands/inspect/error-zip.mjs +11 -12
- package/dist/commands/inspect/error-zip.mjs.map +1 -0
- package/dist/commands/inspect/log-report.d.mts +1 -0
- package/{src → dist}/commands/inspect/log-report.mjs +11 -13
- package/dist/commands/inspect/log-report.mjs.map +1 -0
- package/dist/commands/inspect/profile-show.d.mts +1 -0
- package/{src → dist}/commands/inspect/profile-show.mjs +10 -11
- package/dist/commands/inspect/profile-show.mjs.map +1 -0
- package/dist/commands/inspect/recap.d.mts +1 -0
- package/{src → dist}/commands/inspect/recap.mjs +11 -13
- package/dist/commands/inspect/recap.mjs.map +1 -0
- package/dist/commands/inspect/resolve-task-key.d.mts +1 -0
- package/{src → dist}/commands/inspect/resolve-task-key.mjs +11 -13
- package/dist/commands/inspect/resolve-task-key.mjs.map +1 -0
- package/dist/commands/inspect/rollup.d.mts +1 -0
- package/{src → dist}/commands/inspect/rollup.mjs +11 -13
- package/dist/commands/inspect/rollup.mjs.map +1 -0
- package/dist/commands/inspect/run-audit.d.mts +1 -0
- package/{src → dist}/commands/inspect/run-audit.mjs +11 -12
- package/dist/commands/inspect/run-audit.mjs.map +1 -0
- package/dist/commands/inspect/set-work-status.d.mts +1 -0
- package/{src → dist}/commands/inspect/set-work-status.mjs +11 -13
- package/dist/commands/inspect/set-work-status.mjs.map +1 -0
- package/dist/commands/inspect/stage-map.d.mts +1 -0
- package/dist/commands/inspect/stage-map.mjs +110 -0
- package/dist/commands/inspect/stage-map.mjs.map +1 -0
- package/dist/commands/inspect/task-list.d.mts +1 -0
- package/dist/commands/inspect/task-list.mjs +103 -0
- package/dist/commands/inspect/task-list.mjs.map +1 -0
- package/dist/commands/inspect/task-show.d.mts +1 -0
- package/dist/commands/inspect/task-show.mjs +108 -0
- package/dist/commands/inspect/task-show.mjs.map +1 -0
- package/dist/commands/inspect/time-report.d.mts +1 -0
- package/{src → dist}/commands/inspect/time-report.mjs +11 -13
- package/dist/commands/inspect/time-report.mjs.map +1 -0
- package/dist/commands/inspect/usage-report.d.mts +1 -0
- package/{src → dist}/commands/inspect/usage-report.mjs +11 -13
- package/dist/commands/inspect/usage-report.mjs.map +1 -0
- package/dist/commands/inspect/user-response.d.mts +1 -0
- package/{src → dist}/commands/inspect/user-response.mjs +10 -11
- package/dist/commands/inspect/user-response.mjs.map +1 -0
- package/dist/commands/inspect/worker-liveness.d.mts +1 -0
- package/{src → dist}/commands/inspect/worker-liveness.mjs +11 -13
- package/dist/commands/inspect/worker-liveness.mjs.map +1 -0
- package/dist/commands/lifecycle/check-project.d.mts +21 -0
- package/dist/commands/lifecycle/check-project.mjs +175 -0
- package/dist/commands/lifecycle/check-project.mjs.map +1 -0
- package/dist/commands/lifecycle/config.d.mts +1 -0
- package/dist/commands/lifecycle/config.mjs +369 -0
- package/dist/commands/lifecycle/config.mjs.map +1 -0
- package/dist/commands/lifecycle/doctor.d.mts +10 -0
- package/dist/commands/lifecycle/doctor.mjs +317 -0
- package/dist/commands/lifecycle/doctor.mjs.map +1 -0
- package/dist/commands/lifecycle/install.d.mts +17 -0
- package/dist/commands/lifecycle/install.mjs +1077 -0
- package/dist/commands/lifecycle/install.mjs.map +1 -0
- package/dist/commands/lifecycle/migrate.d.mts +1 -0
- package/{src → dist}/commands/lifecycle/migrate.mjs +10 -11
- package/dist/commands/lifecycle/migrate.mjs.map +1 -0
- package/dist/commands/lifecycle/model.d.mts +1 -0
- package/dist/commands/lifecycle/model.mjs +22 -0
- package/dist/commands/lifecycle/model.mjs.map +1 -0
- package/dist/commands/lifecycle/paths.d.mts +1 -0
- package/dist/commands/lifecycle/paths.mjs +102 -0
- package/dist/commands/lifecycle/paths.mjs.map +1 -0
- package/dist/commands/lifecycle/preflight.d.mts +1 -0
- package/dist/commands/lifecycle/preflight.mjs +124 -0
- package/dist/commands/lifecycle/preflight.mjs.map +1 -0
- package/dist/commands/lifecycle/setup.d.mts +1 -0
- package/dist/commands/lifecycle/setup.mjs +297 -0
- package/dist/commands/lifecycle/setup.mjs.map +1 -0
- package/dist/commands/lifecycle/uninstall.d.mts +4 -0
- package/dist/commands/lifecycle/uninstall.mjs +262 -0
- package/dist/commands/lifecycle/uninstall.mjs.map +1 -0
- package/dist/commands/manager.d.mts +3 -0
- package/{src → dist}/commands/manager.mjs +25 -32
- package/dist/commands/manager.mjs.map +1 -0
- package/dist/commands/memory/memory.d.mts +1 -0
- package/dist/commands/memory/memory.mjs +569 -0
- package/dist/commands/memory/memory.mjs.map +1 -0
- package/dist/commands/pr/pr.d.mts +33 -0
- package/dist/commands/pr/pr.mjs +296 -0
- package/dist/commands/pr/pr.mjs.map +1 -0
- package/dist/commands/report/agent-activity.d.mts +1 -0
- package/{src → dist}/commands/report/agent-activity.mjs +11 -12
- package/dist/commands/report/agent-activity.mjs.map +1 -0
- package/dist/commands/report/finalize.d.mts +4 -0
- package/{src → dist}/commands/report/finalize.mjs +25 -32
- package/dist/commands/report/finalize.mjs.map +1 -0
- package/dist/commands/report/inject-report-index.d.mts +1 -0
- package/{src → dist}/commands/report/inject-report-index.mjs +6 -7
- package/dist/commands/report/inject-report-index.mjs.map +1 -0
- package/dist/commands/report/render-final-report.d.mts +1 -0
- package/{src → dist}/commands/report/render-final-report.mjs +6 -7
- package/dist/commands/report/render-final-report.mjs.map +1 -0
- package/dist/commands/report/render-views.d.mts +1 -0
- package/{src → dist}/commands/report/render-views.mjs +6 -7
- package/dist/commands/report/render-views.mjs.map +1 -0
- package/dist/commands/report/translate.d.mts +1 -0
- package/{src → dist}/commands/report/translate.mjs +6 -7
- package/dist/commands/report/translate.mjs.map +1 -0
- package/dist/lib/helper-scripts.d.mts +3 -0
- package/{src → dist}/lib/helper-scripts.mjs +11 -14
- package/dist/lib/helper-scripts.mjs.map +1 -0
- package/dist/lib/host-registry-client.d.mts +25 -0
- package/dist/lib/host-registry-client.mjs +152 -0
- package/dist/lib/host-registry-client.mjs.map +1 -0
- package/dist/lib/install-assets.d.mts +8 -0
- package/{src → dist}/lib/install-assets.mjs +17 -20
- package/dist/lib/install-assets.mjs.map +1 -0
- package/dist/lib/okstra-dirs.d.mts +4 -0
- package/{src → dist}/lib/okstra-dirs.mjs +3 -6
- package/dist/lib/okstra-dirs.mjs.map +1 -0
- package/dist/lib/paths.d.mts +4 -0
- package/dist/lib/paths.mjs +78 -0
- package/dist/lib/paths.mjs.map +1 -0
- package/dist/lib/proc.d.mts +3 -0
- package/dist/lib/proc.mjs +31 -0
- package/dist/lib/proc.mjs.map +1 -0
- package/dist/lib/python-helper.d.mts +8 -0
- package/dist/lib/python-helper.mjs +123 -0
- package/dist/lib/python-helper.mjs.map +1 -0
- package/dist/lib/runtime-manifest.d.mts +7 -0
- package/dist/lib/runtime-manifest.mjs +73 -0
- package/dist/lib/runtime-manifest.mjs.map +1 -0
- package/dist/lib/skill-catalog.d.mts +4 -0
- package/dist/lib/skill-catalog.mjs +50 -0
- package/dist/lib/skill-catalog.mjs.map +1 -0
- package/dist/lib/types.d.mts +129 -0
- package/dist/lib/types.mjs +2 -0
- package/dist/lib/types.mjs.map +1 -0
- package/dist/lib/version.d.mts +2 -0
- package/dist/lib/version.mjs +27 -0
- package/dist/lib/version.mjs.map +1 -0
- package/docs/architecture/storage-model.md +6 -2
- package/docs/architecture.md +29 -20
- package/docs/cli.md +40 -16
- package/docs/contributor-change-matrix.md +2 -2
- package/docs/for-ai/skills/okstra-inspect.md +2 -3
- package/docs/for-ai/skills/okstra-rollup.md +1 -0
- package/docs/project-structure-overview.md +72 -62
- package/docs/task-process/README.md +12 -8
- package/docs/task-process/common-flow.md +13 -16
- package/docs/task-process/error-analysis.md +9 -10
- package/docs/task-process/final-verification.md +7 -7
- package/docs/task-process/implementation-planning.md +9 -9
- package/docs/task-process/implementation.md +6 -6
- package/docs/task-process/release-handoff.md +8 -7
- package/docs/task-process/requirements-discovery.md +8 -8
- package/package.json +11 -5
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/claude-worker.md +2 -1
- package/runtime/agents/workers/report-writer-worker.md +3 -1
- package/runtime/agents/workers/translator-worker.md +3 -1
- package/runtime/bin/lib/okstra/cli.sh +12 -0
- package/runtime/bin/lib/okstra/globals.sh +3 -0
- package/runtime/bin/lib/okstra/interactive.sh +12 -6
- package/runtime/bin/lib/okstra/usage.sh +7 -6
- package/runtime/bin/okstra-error-log.py +27 -0
- package/runtime/bin/okstra-provider-exec.py +217 -5
- package/runtime/bin/okstra-spawn-followups.py +4 -2
- package/runtime/bin/okstra.sh +10 -0
- package/runtime/prompts/launch.template.md +2 -2
- package/runtime/prompts/lead/context-loader.md +1 -2
- package/runtime/prompts/lead/convergence.md +27 -18
- package/runtime/prompts/lead/okstra-lead-contract.md +6 -5
- package/runtime/prompts/lead/plan-body-verification.md +10 -3
- package/runtime/prompts/lead/report-writer.md +15 -1
- package/runtime/prompts/lead/team-contract.md +17 -13
- package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
- package/runtime/prompts/profiles/_implementation-executor.md +0 -3
- package/runtime/prompts/profiles/_implementation-verifier.md +3 -7
- package/runtime/prompts/profiles/change-impact-analysis.md +20 -0
- package/runtime/prompts/profiles/error-analysis.md +27 -1
- package/runtime/prompts/profiles/feature-analysis.md +20 -0
- package/runtime/prompts/profiles/final-verification.md +20 -1
- package/runtime/prompts/profiles/implementation-option-selection.md +20 -0
- package/runtime/prompts/profiles/implementation-planning.md +26 -0
- package/runtime/prompts/profiles/implementation.md +19 -0
- package/runtime/prompts/profiles/improvement-discovery.md +21 -1
- package/runtime/prompts/profiles/project-analysis.md +20 -0
- package/runtime/prompts/profiles/release-handoff.md +4 -0
- package/runtime/prompts/profiles/requirements-discovery.md +27 -1
- package/runtime/prompts/wizard/prompts.ko.json +35 -0
- package/runtime/python/okstra_ctl/adapters/dispatch/cli_wrapper.py +8 -0
- package/runtime/python/okstra_ctl/adapters/dispatch/cmux.py +8 -0
- package/runtime/python/okstra_ctl/adapters/dispatch/native_team.py +13 -0
- package/runtime/python/okstra_ctl/adapters/hosts/antigravity/adapter.py +2 -2
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +25 -5
- package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +2 -2
- package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +4 -1
- package/runtime/python/okstra_ctl/adapters/hosts/grok/adapter.py +2 -2
- package/runtime/python/okstra_ctl/adapters/hosts/kimi/adapter.py +2 -2
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +79 -11
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +95 -25
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +59 -14
- package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +55 -9
- package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +51 -12
- package/runtime/python/okstra_ctl/adapters/runtime/__init__.py +1 -0
- package/runtime/python/okstra_ctl/adapters/runtime/assembly.py +27 -0
- package/runtime/python/okstra_ctl/adapters/runtime/cli_wrapper.py +49 -0
- package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +74 -0
- package/runtime/python/okstra_ctl/agent_activity.py +5 -1
- package/runtime/python/okstra_ctl/agent_invocation.py +608 -14
- package/runtime/python/okstra_ctl/agent_prompt_cli.py +249 -50
- package/runtime/python/okstra_ctl/application/open_worker.py +29 -0
- package/runtime/python/okstra_ctl/application/resolve_assignment.py +53 -12
- package/runtime/python/okstra_ctl/assignment_environment.py +102 -0
- package/runtime/python/okstra_ctl/assignment_resolver.py +790 -0
- package/runtime/python/okstra_ctl/attempt_evidence.py +342 -0
- package/runtime/python/okstra_ctl/convergence.py +409 -3
- package/runtime/python/okstra_ctl/convergence_engine.py +248 -15
- package/runtime/python/okstra_ctl/convergence_store.py +170 -1
- package/runtime/python/okstra_ctl/dispatch_core.py +1204 -155
- package/runtime/python/okstra_ctl/dispatch_state.py +696 -11
- package/runtime/python/okstra_ctl/doctor.py +14 -0
- package/runtime/python/okstra_ctl/domain/host.py +34 -1
- package/runtime/python/okstra_ctl/domain/provider.py +212 -6
- package/runtime/python/okstra_ctl/domain/role.py +125 -0
- package/runtime/python/okstra_ctl/domain/wizard/interaction.py +18 -0
- package/runtime/python/okstra_ctl/domain/worker_exec.py +34 -1
- package/runtime/python/okstra_ctl/domain/worker_role.py +13 -3
- package/runtime/python/okstra_ctl/domain/worker_runtime.py +44 -0
- package/runtime/python/okstra_ctl/domain/worker_stream.py +24 -0
- package/runtime/python/okstra_ctl/error_log_write.py +9 -0
- package/runtime/python/okstra_ctl/error_report.py +21 -1
- package/runtime/python/okstra_ctl/execution_identity.py +529 -0
- package/runtime/python/okstra_ctl/execution_manifest.py +1281 -0
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +619 -0
- package/runtime/python/okstra_ctl/implementation_outcome.py +21 -5
- package/runtime/python/okstra_ctl/index.py +6 -2
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +43 -3
- package/runtime/python/okstra_ctl/legacy_model_selection.py +578 -0
- package/runtime/python/okstra_ctl/manager_sync.py +4 -1
- package/runtime/python/okstra_ctl/model_cli.py +278 -0
- package/runtime/python/okstra_ctl/model_defaults.py +46 -0
- package/runtime/python/okstra_ctl/model_discovery.py +26 -7
- package/runtime/python/okstra_ctl/model_pool.py +501 -0
- package/runtime/python/okstra_ctl/models.py +47 -27
- package/runtime/python/okstra_ctl/mutation_recovery.py +293 -0
- package/runtime/python/okstra_ctl/next_phase.py +236 -0
- package/runtime/python/okstra_ctl/pane_title.py +151 -0
- package/runtime/python/okstra_ctl/ports/host_model.py +48 -17
- package/runtime/python/okstra_ctl/ports/worker_dispatch.py +4 -0
- package/runtime/python/okstra_ctl/ports/worker_runtime.py +26 -0
- package/runtime/python/okstra_ctl/recap.py +4 -1
- package/runtime/python/okstra_ctl/registry/provider_registry.py +8 -4
- package/runtime/python/okstra_ctl/render.py +124 -57
- package/runtime/python/okstra_ctl/render_final_report.py +19 -0
- package/runtime/python/okstra_ctl/report_contract.py +39 -0
- package/runtime/python/okstra_ctl/report_finalize.py +16 -0
- package/runtime/python/okstra_ctl/report_html/render.py +1 -0
- package/runtime/python/okstra_ctl/role_requirements.py +210 -0
- package/runtime/python/okstra_ctl/rollup.py +4 -1
- package/runtime/python/okstra_ctl/run.py +1210 -258
- package/runtime/python/okstra_ctl/run_index_row.py +7 -1
- package/runtime/python/okstra_ctl/stage_fix_carry.py +17 -1
- package/runtime/python/okstra_ctl/team.py +14 -18
- package/runtime/python/okstra_ctl/time_report.py +38 -4
- package/runtime/python/okstra_ctl/usage_identity.py +86 -0
- package/runtime/python/okstra_ctl/usage_report.py +15 -3
- package/runtime/python/okstra_ctl/wizard.py +1449 -66
- package/runtime/python/okstra_ctl/worker_audit_ledger.py +68 -65
- package/runtime/python/okstra_ctl/worker_prompt_body.py +18 -2
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +40 -9
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +16 -1
- package/runtime/python/okstra_ctl/worker_request.py +7 -1
- package/runtime/python/okstra_ctl/worker_runner.py +130 -5
- package/runtime/python/okstra_ctl/workers.py +7 -5
- package/runtime/python/okstra_ctl/workflow.py +18 -32
- package/runtime/python/okstra_ctl/worktree.py +3 -3
- package/runtime/python/okstra_ctl/worktree_registry.py +5 -4
- package/runtime/python/okstra_ctl/write_policy.py +571 -0
- package/runtime/python/okstra_project/state.py +54 -6
- package/runtime/schemas/convergence-groups-v2.0.schema.json +128 -0
- package/runtime/schemas/execution-manifest-v2.schema.json +340 -0
- package/runtime/schemas/final-report-v2.0.schema.json +68 -5
- package/runtime/skills/okstra-inspect/facets/recap.md +2 -0
- package/runtime/skills/okstra-inspect/facets/report.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +15 -13
- package/runtime/skills/okstra-rollup/SKILL.md +1 -0
- package/runtime/skills/okstra-run/SKILL.md +14 -14
- package/runtime/templates/implementation-worker-preamble.md +3 -18
- package/runtime/templates/project-docs/task-index.template.md +0 -1
- package/runtime/templates/report-writer-prompt-preamble.md +2 -0
- package/runtime/templates/reports/final-report-v2.template.md +7 -1
- package/runtime/templates/reports/html/base.template.html +21 -0
- package/runtime/templates/reports/html/i18n/en.json +4 -0
- package/runtime/templates/reports/html/i18n/ko.json +4 -0
- package/runtime/templates/reports/html/macros/forms.html +5 -4
- package/runtime/templates/reports/html/tasks/final-verification.template.html +1 -1
- package/runtime/templates/reports/html/tasks/implementation.template.html +1 -1
- package/runtime/templates/worker-prompt-preamble.md +6 -35
- package/runtime/validators/lib/fixtures.sh +49 -16
- package/runtime/validators/validate-run.py +486 -134
- package/runtime/validators/validate_session_conformance.py +25 -7
- package/src/cli-registry.mjs +0 -539
- package/src/commands/execute/codex-dispatch.mjs +0 -10
- package/src/commands/execute/plan-items.mjs +0 -9
- package/src/commands/execute/plan-validate.mjs +0 -68
- package/src/commands/execute/run.mjs +0 -208
- package/src/commands/execute/wizard.mjs +0 -167
- package/src/commands/inspect/stage-map.mjs +0 -98
- package/src/commands/inspect/task-list.mjs +0 -97
- package/src/commands/inspect/task-show.mjs +0 -100
- package/src/commands/lifecycle/check-project.mjs +0 -187
- package/src/commands/lifecycle/config.mjs +0 -385
- package/src/commands/lifecycle/doctor.mjs +0 -308
- package/src/commands/lifecycle/install.mjs +0 -1170
- package/src/commands/lifecycle/paths.mjs +0 -104
- package/src/commands/lifecycle/preflight.mjs +0 -125
- package/src/commands/lifecycle/setup.mjs +0 -333
- package/src/commands/lifecycle/uninstall.mjs +0 -279
- package/src/commands/memory/memory.mjs +0 -524
- package/src/commands/pr/pr.mjs +0 -261
- package/src/lib/host-registry-client.mjs +0 -176
- package/src/lib/paths.mjs +0 -86
- package/src/lib/proc.mjs +0 -31
- package/src/lib/python-helper.mjs +0 -142
- package/src/lib/runtime-manifest.mjs +0 -70
- package/src/lib/skill-catalog.mjs +0 -53
- package/src/lib/version.mjs +0 -20
- /package/{src → dist}/commands/pr/default.md +0 -0
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
import argparse
|
|
5
|
+
from collections.abc import Mapping
|
|
5
6
|
import json
|
|
6
|
-
from pathlib import Path
|
|
7
|
+
from pathlib import Path, PurePosixPath
|
|
7
8
|
import sys
|
|
8
9
|
from typing import Any
|
|
9
10
|
|
|
@@ -32,6 +33,9 @@ from .convergence_store import (
|
|
|
32
33
|
write_final_state_atomic,
|
|
33
34
|
write_json_atomic,
|
|
34
35
|
)
|
|
36
|
+
from .execution_identity import ExecutionManifest
|
|
37
|
+
from .execution_manifest import read_execution_manifest_view
|
|
38
|
+
from .paths import RunRef
|
|
35
39
|
from .verdict_blocks import FindingVote, VerdictBlockError, parse_finding_votes
|
|
36
40
|
|
|
37
41
|
|
|
@@ -154,7 +158,7 @@ def _parser() -> argparse.ArgumentParser:
|
|
|
154
158
|
prog="okstra convergence",
|
|
155
159
|
description="Advance and validate deterministic re-verification state.",
|
|
156
160
|
epilog=(
|
|
157
|
-
"Working lifecycle: groups v1.0 → work v1.0 → "
|
|
161
|
+
"Working lifecycle: groups v1.0/v2.0 → work v1.0/v2.0 → "
|
|
158
162
|
"round-plan/results v1.0 → final v1.3\n"
|
|
159
163
|
"historical final readers: v1.0, v1.1, v1.2"
|
|
160
164
|
),
|
|
@@ -188,6 +192,7 @@ def _parser() -> argparse.ArgumentParser:
|
|
|
188
192
|
|
|
189
193
|
seed = subparsers.add_parser("seed", help="create, resume, or recover working state")
|
|
190
194
|
seed.add_argument("--groups", type=Path, required=True)
|
|
195
|
+
seed.add_argument("--run-manifest", type=Path)
|
|
191
196
|
seed.add_argument("--work-state", type=Path, required=True)
|
|
192
197
|
seed.add_argument("--final-state", type=Path, required=True)
|
|
193
198
|
seed.add_argument("--migration-dir", type=Path, required=True)
|
|
@@ -314,13 +319,402 @@ def _seeded_groups_provenance_errors(groups_path: Path, document: dict) -> list[
|
|
|
314
319
|
)
|
|
315
320
|
|
|
316
321
|
|
|
322
|
+
def _seed_execution_manifest(
|
|
323
|
+
groups_path: Path,
|
|
324
|
+
grouped_input: dict[str, Any],
|
|
325
|
+
manifest_path: Path | None,
|
|
326
|
+
work_state_path: Path,
|
|
327
|
+
final_state_path: Path,
|
|
328
|
+
) -> ExecutionManifest | None:
|
|
329
|
+
if manifest_path is None:
|
|
330
|
+
return None
|
|
331
|
+
manifest, authority = read_execution_manifest_view(manifest_path)
|
|
332
|
+
if grouped_input.get("schemaVersion") == "2.0":
|
|
333
|
+
_validate_v2_seed_authority(
|
|
334
|
+
groups_path,
|
|
335
|
+
grouped_input,
|
|
336
|
+
manifest_path,
|
|
337
|
+
authority,
|
|
338
|
+
work_state_path,
|
|
339
|
+
final_state_path,
|
|
340
|
+
execution_manifest=manifest,
|
|
341
|
+
)
|
|
342
|
+
return manifest
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def _validate_v2_seed_authority(
|
|
346
|
+
groups_path: Path,
|
|
347
|
+
grouped_input: dict[str, Any],
|
|
348
|
+
manifest_path: Path,
|
|
349
|
+
authority: Mapping[str, Any],
|
|
350
|
+
work_state_path: Path,
|
|
351
|
+
final_state_path: Path,
|
|
352
|
+
*,
|
|
353
|
+
execution_manifest: ExecutionManifest,
|
|
354
|
+
) -> None:
|
|
355
|
+
validated = _validated_v2_work_authority(
|
|
356
|
+
work_state_path,
|
|
357
|
+
grouped_input,
|
|
358
|
+
manifest_snapshot=(manifest_path, execution_manifest, authority),
|
|
359
|
+
path_label="state output",
|
|
360
|
+
)
|
|
361
|
+
if validated is None:
|
|
362
|
+
raise ConvergenceContractError("v2 convergence groups require v2 work authority")
|
|
363
|
+
_manifest, run_dir, task_type, state_sequence = validated
|
|
364
|
+
expected_groups_name = _canonical_run_artifact_name(
|
|
365
|
+
"convergence-groups",
|
|
366
|
+
task_type,
|
|
367
|
+
state_sequence,
|
|
368
|
+
)
|
|
369
|
+
if groups_path.name != expected_groups_name:
|
|
370
|
+
raise ConvergenceContractError(
|
|
371
|
+
"convergence groups filename does not match run authority"
|
|
372
|
+
)
|
|
373
|
+
expected_state_dir = run_dir / "state"
|
|
374
|
+
if groups_path.absolute() != groups_path.resolve():
|
|
375
|
+
raise ConvergenceContractError("groups artifact path must be canonical")
|
|
376
|
+
if groups_path.resolve().parent != expected_state_dir:
|
|
377
|
+
raise ConvergenceContractError(
|
|
378
|
+
"groups artifact is outside the current run state directory"
|
|
379
|
+
)
|
|
380
|
+
_validate_v2_state_artifact_path(
|
|
381
|
+
final_state_path,
|
|
382
|
+
state_dir=expected_state_dir,
|
|
383
|
+
task_type=task_type,
|
|
384
|
+
state_sequence=state_sequence,
|
|
385
|
+
prefix="convergence",
|
|
386
|
+
label="state output",
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def _validated_v2_work_authority(
|
|
391
|
+
work_state_path: Path,
|
|
392
|
+
state: Mapping[str, Any],
|
|
393
|
+
*,
|
|
394
|
+
manifest_snapshot: tuple[
|
|
395
|
+
Path,
|
|
396
|
+
ExecutionManifest,
|
|
397
|
+
Mapping[str, Any],
|
|
398
|
+
] | None = None,
|
|
399
|
+
path_label: str = "working state",
|
|
400
|
+
) -> tuple[ExecutionManifest, Path, str, str] | None:
|
|
401
|
+
if state.get("schemaVersion") != "2.0":
|
|
402
|
+
return None
|
|
403
|
+
if state.get("executionIdentityVersion") != 2:
|
|
404
|
+
raise ConvergenceContractError(
|
|
405
|
+
"v2 working state requires executionIdentityVersion 2"
|
|
406
|
+
)
|
|
407
|
+
task_key = _manifest_authority_string(state, "taskKey")
|
|
408
|
+
run_ref = _manifest_authority_string(state, "runManifestPath")
|
|
409
|
+
project_root = _project_root_for_v2_work_state(work_state_path, path_label)
|
|
410
|
+
expected_manifest_path = _canonical_project_artifact_path(
|
|
411
|
+
project_root,
|
|
412
|
+
run_ref,
|
|
413
|
+
"working runManifestPath",
|
|
414
|
+
)
|
|
415
|
+
if manifest_snapshot is None:
|
|
416
|
+
execution_manifest, authority = read_execution_manifest_view(
|
|
417
|
+
expected_manifest_path
|
|
418
|
+
)
|
|
419
|
+
manifest_path = expected_manifest_path
|
|
420
|
+
else:
|
|
421
|
+
supplied_manifest_path, execution_manifest, authority = manifest_snapshot
|
|
422
|
+
manifest_path = supplied_manifest_path.resolve()
|
|
423
|
+
if (
|
|
424
|
+
supplied_manifest_path.absolute() != manifest_path
|
|
425
|
+
or manifest_path != expected_manifest_path
|
|
426
|
+
):
|
|
427
|
+
raise ConvergenceContractError(
|
|
428
|
+
"--run-manifest must use the canonical run manifest path; "
|
|
429
|
+
"runManifestPath does not match supplied path"
|
|
430
|
+
)
|
|
431
|
+
manifest_project_root = _manifest_project_root(authority)
|
|
432
|
+
if project_root != manifest_project_root:
|
|
433
|
+
raise ConvergenceContractError(
|
|
434
|
+
"working state path does not match run manifest projectRoot"
|
|
435
|
+
)
|
|
436
|
+
canonical_run_ref = _manifest_run_ref(
|
|
437
|
+
authority,
|
|
438
|
+
project_root,
|
|
439
|
+
manifest_path,
|
|
440
|
+
)
|
|
441
|
+
if task_key != authority.get("taskKey"):
|
|
442
|
+
raise ConvergenceContractError(
|
|
443
|
+
"working state taskKey does not match run manifest"
|
|
444
|
+
)
|
|
445
|
+
if run_ref != canonical_run_ref:
|
|
446
|
+
raise ConvergenceContractError(
|
|
447
|
+
"working state runManifestPath does not match run manifest"
|
|
448
|
+
)
|
|
449
|
+
run_dir, task_type, state_sequence = _validated_run_artifact_authority(
|
|
450
|
+
authority,
|
|
451
|
+
project_root,
|
|
452
|
+
manifest_path,
|
|
453
|
+
canonical_run_ref,
|
|
454
|
+
)
|
|
455
|
+
_validate_v2_state_artifact_path(
|
|
456
|
+
work_state_path,
|
|
457
|
+
state_dir=run_dir / "state",
|
|
458
|
+
task_type=task_type,
|
|
459
|
+
state_sequence=state_sequence,
|
|
460
|
+
prefix="convergence-work",
|
|
461
|
+
label=path_label,
|
|
462
|
+
)
|
|
463
|
+
return execution_manifest, run_dir, task_type, state_sequence
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def _project_root_for_v2_work_state(
|
|
467
|
+
work_state_path: Path,
|
|
468
|
+
path_label: str,
|
|
469
|
+
) -> Path:
|
|
470
|
+
supplied_path = work_state_path.absolute()
|
|
471
|
+
resolved_path = work_state_path.resolve()
|
|
472
|
+
if supplied_path != resolved_path:
|
|
473
|
+
raise ConvergenceContractError(
|
|
474
|
+
f"{path_label} path does not match run authority"
|
|
475
|
+
)
|
|
476
|
+
for parent in supplied_path.parents:
|
|
477
|
+
if parent.name == ".okstra":
|
|
478
|
+
return parent.parent
|
|
479
|
+
raise ConvergenceContractError(
|
|
480
|
+
f"{path_label} path does not match run authority"
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
def _validated_run_artifact_authority(
|
|
485
|
+
authority: Mapping[str, Any],
|
|
486
|
+
project_root: Path,
|
|
487
|
+
manifest_path: Path,
|
|
488
|
+
run_ref: str,
|
|
489
|
+
) -> tuple[Path, str, str]:
|
|
490
|
+
run_dir = _manifest_run_directory(authority, project_root, manifest_path)
|
|
491
|
+
task_type = _manifest_authority_string(authority, "taskType")
|
|
492
|
+
manifest_sequence = _manifest_sequence(authority, "manifests")
|
|
493
|
+
expected_name = _canonical_run_artifact_name(
|
|
494
|
+
"run-manifest",
|
|
495
|
+
task_type,
|
|
496
|
+
manifest_sequence,
|
|
497
|
+
)
|
|
498
|
+
try:
|
|
499
|
+
recovered = RunRef.from_run_dir(
|
|
500
|
+
run_dir,
|
|
501
|
+
seq=int(manifest_sequence),
|
|
502
|
+
)
|
|
503
|
+
except ValueError as exc:
|
|
504
|
+
raise ConvergenceContractError(
|
|
505
|
+
"run manifest runDirectoryPath is not a canonical run directory"
|
|
506
|
+
) from exc
|
|
507
|
+
if recovered.project_root != project_root:
|
|
508
|
+
raise ConvergenceContractError(
|
|
509
|
+
"run manifest projectRoot does not match recovered run directory"
|
|
510
|
+
)
|
|
511
|
+
if recovered.task_type != task_type:
|
|
512
|
+
raise ConvergenceContractError(
|
|
513
|
+
"run manifest taskType does not match run directory"
|
|
514
|
+
)
|
|
515
|
+
stage = recovered.stage
|
|
516
|
+
invalid_stage = (
|
|
517
|
+
(task_type == "implementation" and (stage is None or stage < 1))
|
|
518
|
+
or (task_type == "final-verification" and stage is not None and stage < 1)
|
|
519
|
+
or (
|
|
520
|
+
task_type not in ("implementation", "final-verification")
|
|
521
|
+
and stage is not None
|
|
522
|
+
)
|
|
523
|
+
)
|
|
524
|
+
if invalid_stage:
|
|
525
|
+
raise ConvergenceContractError(
|
|
526
|
+
"run manifest stage semantics do not match taskType"
|
|
527
|
+
)
|
|
528
|
+
if recovered.run_dir != run_dir:
|
|
529
|
+
raise ConvergenceContractError(
|
|
530
|
+
"run manifest stage does not match runDirectoryPath"
|
|
531
|
+
)
|
|
532
|
+
if manifest_path.name != expected_name:
|
|
533
|
+
raise ConvergenceContractError(
|
|
534
|
+
"run manifest filename does not match run authority"
|
|
535
|
+
)
|
|
536
|
+
if manifest_path != recovered.manifest:
|
|
537
|
+
raise ConvergenceContractError(
|
|
538
|
+
"run manifest path does not match runDirectoryPath authority"
|
|
539
|
+
)
|
|
540
|
+
expected_ref = recovered.manifest.relative_to(project_root).as_posix()
|
|
541
|
+
if run_ref != expected_ref:
|
|
542
|
+
raise ConvergenceContractError(
|
|
543
|
+
"runManifestPath does not match canonical run authority"
|
|
544
|
+
)
|
|
545
|
+
return run_dir, task_type, _manifest_sequence(authority, "state")
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
def _manifest_authority_string(
|
|
549
|
+
authority: Mapping[str, Any],
|
|
550
|
+
key: str,
|
|
551
|
+
) -> str:
|
|
552
|
+
value = authority.get(key)
|
|
553
|
+
if not isinstance(value, str) or not value.strip():
|
|
554
|
+
raise ConvergenceContractError(f"run manifest has no {key}")
|
|
555
|
+
return value
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def _manifest_sequence(authority: Mapping[str, Any], category: str) -> str:
|
|
559
|
+
sequences = authority.get("runSequencesByCategory")
|
|
560
|
+
if not isinstance(sequences, Mapping):
|
|
561
|
+
raise ConvergenceContractError(
|
|
562
|
+
"run manifest has no runSequencesByCategory object"
|
|
563
|
+
)
|
|
564
|
+
return _manifest_authority_string(sequences, category)
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def _canonical_run_artifact_name(
|
|
568
|
+
prefix: str,
|
|
569
|
+
task_type: str,
|
|
570
|
+
sequence: str,
|
|
571
|
+
) -> str:
|
|
572
|
+
try:
|
|
573
|
+
sequence_number = int(sequence)
|
|
574
|
+
except ValueError as exc:
|
|
575
|
+
raise ConvergenceContractError(
|
|
576
|
+
"run manifest sequence is not canonical"
|
|
577
|
+
) from exc
|
|
578
|
+
if sequence_number < 1:
|
|
579
|
+
raise ConvergenceContractError(
|
|
580
|
+
"run manifest sequence is not canonical"
|
|
581
|
+
)
|
|
582
|
+
probe = RunRef(
|
|
583
|
+
project_root=Path("/"),
|
|
584
|
+
task_group="group",
|
|
585
|
+
task_id="task",
|
|
586
|
+
task_type=task_type,
|
|
587
|
+
seq=sequence_number,
|
|
588
|
+
).manifest.name
|
|
589
|
+
if not probe.endswith(f"-{sequence}.json"):
|
|
590
|
+
raise ConvergenceContractError(
|
|
591
|
+
"run manifest sequence is not canonical"
|
|
592
|
+
)
|
|
593
|
+
suffix = probe.removeprefix("run-manifest").removesuffix(".json")
|
|
594
|
+
return f"{prefix}{suffix}.json"
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
def _manifest_run_directory(
|
|
598
|
+
authority: Mapping[str, Any],
|
|
599
|
+
project_root: Path,
|
|
600
|
+
manifest_path: Path,
|
|
601
|
+
) -> Path:
|
|
602
|
+
value = _manifest_authority_string(authority, "runDirectoryPath")
|
|
603
|
+
posix = PurePosixPath(value)
|
|
604
|
+
if (
|
|
605
|
+
posix.is_absolute()
|
|
606
|
+
or posix.as_posix() != value
|
|
607
|
+
or not posix.parts
|
|
608
|
+
or posix.parts[0] != ".okstra"
|
|
609
|
+
or ".." in posix.parts
|
|
610
|
+
):
|
|
611
|
+
raise ConvergenceContractError(
|
|
612
|
+
"run manifest runDirectoryPath is not canonical"
|
|
613
|
+
)
|
|
614
|
+
resolved = (project_root / value).resolve()
|
|
615
|
+
if not resolved.is_relative_to(project_root):
|
|
616
|
+
raise ConvergenceContractError(
|
|
617
|
+
"run manifest runDirectoryPath escapes projectRoot"
|
|
618
|
+
)
|
|
619
|
+
if resolved != manifest_path.parent.parent:
|
|
620
|
+
raise ConvergenceContractError(
|
|
621
|
+
"run manifest runDirectoryPath does not identify the supplied run"
|
|
622
|
+
)
|
|
623
|
+
return resolved
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
def _validate_v2_state_artifact_path(
|
|
627
|
+
supplied_path: Path,
|
|
628
|
+
*,
|
|
629
|
+
state_dir: Path,
|
|
630
|
+
task_type: str,
|
|
631
|
+
state_sequence: str,
|
|
632
|
+
prefix: str,
|
|
633
|
+
label: str,
|
|
634
|
+
) -> None:
|
|
635
|
+
expected_path = state_dir / _canonical_run_artifact_name(
|
|
636
|
+
prefix,
|
|
637
|
+
task_type,
|
|
638
|
+
state_sequence,
|
|
639
|
+
)
|
|
640
|
+
if (
|
|
641
|
+
supplied_path.absolute() != supplied_path.resolve()
|
|
642
|
+
or supplied_path.resolve() != expected_path
|
|
643
|
+
):
|
|
644
|
+
raise ConvergenceContractError(
|
|
645
|
+
f"{label} path does not match run authority"
|
|
646
|
+
)
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
def _manifest_project_root(authority: dict[str, Any]) -> Path:
|
|
650
|
+
value = authority.get("projectRoot")
|
|
651
|
+
if not isinstance(value, str) or not value.strip():
|
|
652
|
+
raise ConvergenceContractError("run manifest has no projectRoot")
|
|
653
|
+
project_root = Path(value)
|
|
654
|
+
if not project_root.is_absolute() or project_root.absolute() != project_root.resolve():
|
|
655
|
+
raise ConvergenceContractError("run manifest projectRoot must be canonical")
|
|
656
|
+
return project_root
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
def _manifest_run_ref(
|
|
660
|
+
authority: dict[str, Any],
|
|
661
|
+
project_root: Path,
|
|
662
|
+
manifest_path: Path,
|
|
663
|
+
) -> str:
|
|
664
|
+
value = _manifest_authority_string(authority, "runManifestPath")
|
|
665
|
+
resolved = _canonical_project_artifact_path(
|
|
666
|
+
project_root,
|
|
667
|
+
value,
|
|
668
|
+
"run manifest runManifestPath",
|
|
669
|
+
)
|
|
670
|
+
if resolved != manifest_path:
|
|
671
|
+
raise ConvergenceContractError(
|
|
672
|
+
"run manifest runManifestPath does not identify the supplied manifest"
|
|
673
|
+
)
|
|
674
|
+
return value
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
def _canonical_project_artifact_path(
|
|
678
|
+
project_root: Path,
|
|
679
|
+
value: str,
|
|
680
|
+
label: str,
|
|
681
|
+
) -> Path:
|
|
682
|
+
posix = PurePosixPath(value)
|
|
683
|
+
supplied = project_root.joinpath(*posix.parts)
|
|
684
|
+
resolved = supplied.resolve()
|
|
685
|
+
if not resolved.is_relative_to(project_root):
|
|
686
|
+
raise ConvergenceContractError(f"{label} escapes projectRoot")
|
|
687
|
+
if (
|
|
688
|
+
posix.is_absolute()
|
|
689
|
+
or posix.as_posix() != value
|
|
690
|
+
or not posix.parts
|
|
691
|
+
or posix.parts[0] != ".okstra"
|
|
692
|
+
or ".." in posix.parts
|
|
693
|
+
):
|
|
694
|
+
raise ConvergenceContractError(f"{label} is not canonical")
|
|
695
|
+
if supplied.absolute() != resolved:
|
|
696
|
+
raise ConvergenceContractError(f"{label} escapes projectRoot")
|
|
697
|
+
return resolved
|
|
698
|
+
|
|
699
|
+
|
|
317
700
|
def _seed(args: argparse.Namespace) -> tuple[str, Path]:
|
|
318
701
|
grouped_input = load_json_object(args.groups)
|
|
702
|
+
execution_manifest = _seed_execution_manifest(
|
|
703
|
+
args.groups,
|
|
704
|
+
grouped_input,
|
|
705
|
+
args.run_manifest,
|
|
706
|
+
args.work_state,
|
|
707
|
+
args.final_state,
|
|
708
|
+
)
|
|
319
709
|
provenance = _seeded_groups_provenance_errors(args.groups, grouped_input)
|
|
320
710
|
if provenance:
|
|
321
711
|
raise ConvergenceContractError(
|
|
322
712
|
"grouping cites source items no worker reported: " + "; ".join(provenance)
|
|
323
713
|
)
|
|
714
|
+
state = seed_working_state(
|
|
715
|
+
grouped_input,
|
|
716
|
+
execution_manifest=execution_manifest,
|
|
717
|
+
)
|
|
324
718
|
decision = decide_seed_action(
|
|
325
719
|
grouped_input=grouped_input,
|
|
326
720
|
work_state_path=args.work_state,
|
|
@@ -338,7 +732,6 @@ def _seed(args: argparse.Namespace) -> tuple[str, Path]:
|
|
|
338
732
|
)
|
|
339
733
|
return decision.action, args.work_state
|
|
340
734
|
|
|
341
|
-
state = seed_working_state(grouped_input)
|
|
342
735
|
if decision.action == "restart-round0":
|
|
343
736
|
migration = _archive_existing_states(
|
|
344
737
|
work_state_path=args.work_state,
|
|
@@ -364,6 +757,7 @@ def _plan_round(args: argparse.Namespace) -> tuple[str, Path]:
|
|
|
364
757
|
|
|
365
758
|
def _apply_round(args: argparse.Namespace) -> tuple[str, Path]:
|
|
366
759
|
state = load_json_object(args.work_state)
|
|
760
|
+
_validated_v2_work_authority(args.work_state, state)
|
|
367
761
|
plan = load_json_object(args.plan)
|
|
368
762
|
results = load_json_object(args.results)
|
|
369
763
|
updated = apply_round_results(state, plan, results)
|
|
@@ -376,6 +770,7 @@ def _apply_round(args: argparse.Namespace) -> tuple[str, Path]:
|
|
|
376
770
|
|
|
377
771
|
def _apply_critic_gaps(args: argparse.Namespace) -> tuple[str, Path]:
|
|
378
772
|
state = load_json_object(args.work_state)
|
|
773
|
+
_validated_v2_work_authority(args.work_state, state)
|
|
379
774
|
results = load_json_object(args.results)
|
|
380
775
|
updated = apply_critic_gap_results(state, results)
|
|
381
776
|
write_json_atomic(args.work_state, updated)
|
|
@@ -384,6 +779,17 @@ def _apply_critic_gaps(args: argparse.Namespace) -> tuple[str, Path]:
|
|
|
384
779
|
|
|
385
780
|
def _finalize(args: argparse.Namespace) -> tuple[str, Path]:
|
|
386
781
|
state = load_json_object(args.work_state)
|
|
782
|
+
authority = _validated_v2_work_authority(args.work_state, state)
|
|
783
|
+
if authority is not None:
|
|
784
|
+
_manifest, run_dir, task_type, state_sequence = authority
|
|
785
|
+
_validate_v2_state_artifact_path(
|
|
786
|
+
args.output,
|
|
787
|
+
state_dir=run_dir / "state",
|
|
788
|
+
task_type=task_type,
|
|
789
|
+
state_sequence=state_sequence,
|
|
790
|
+
prefix="convergence",
|
|
791
|
+
label="final state",
|
|
792
|
+
)
|
|
387
793
|
final = finalize_working_state(state)
|
|
388
794
|
migration = state.get("migration")
|
|
389
795
|
write_final_state_atomic(args.output, final, migration=migration)
|