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
|
@@ -18,8 +18,7 @@ Read `.okstra/discovery/task-catalog.json`. The catalog is the authoritative sou
|
|
|
18
18
|
| `currentStatus` | task-level status |
|
|
19
19
|
| `currentPhase` | lifecycle current phase |
|
|
20
20
|
| `currentPhaseState` | lifecycle phase state |
|
|
21
|
-
| `nextRecommendedPhase` | next
|
|
22
|
-
| `routingStatus` | routing decision status |
|
|
21
|
+
| `nextRecommendedPhase` | next-phase pointer — an **object** `{phase, status, rationale}`, never a string. `status` is `ready` / `pending` / `blocked` / `terminal`. The lead writes `phase` only under `ready`, but that is an authoring rule, not a constraint the struct enforces — `prepare` lowers a `ready` pointer to `pending` and keeps its `phase`, so a non-`ready` pointer that still names a phase is a normal state to read. Decide launchability from `status` alone. Render `phase` (or `--` when it is empty) — never the object itself. |
|
|
23
22
|
| `awaitingApproval` | whether awaiting approval |
|
|
24
23
|
| `latestRunStatus` | latest run status |
|
|
25
24
|
| `latestReportPath` | latest report path |
|
|
@@ -29,9 +28,9 @@ Read `.okstra/discovery/task-catalog.json`. The catalog is the authoritative sou
|
|
|
29
28
|
|
|
30
29
|
Sort by `updatedAt` desc, then `taskKey`.
|
|
31
30
|
|
|
32
|
-
The overview table is intentionally narrow so it renders cleanly in a terminal. Only six columns are shown; for any task that needs a closer look (phase state,
|
|
31
|
+
The overview table is intentionally narrow so it renders cleanly in a terminal. Only six columns are shown; for any task that needs a closer look (phase state, the pointer's status and rationale, approval gate, last run status, resume path, etc.) tell the user to run `/okstra-inspect status <task-key>` for the detail view in `status.2`.
|
|
33
32
|
|
|
34
|
-
If `awaitingApproval` is true OR `
|
|
33
|
+
The `Next` cell is `nextRecommendedPhase.phase`, or `--` when that string is empty. If `awaitingApproval` is true OR `nextRecommendedPhase.status` is anything other than `ready`, append a `*` to the cell and explain the marker once below the table — an unset or non-`ready` pointer means no next run is launchable yet.
|
|
35
34
|
|
|
36
35
|
```markdown
|
|
37
36
|
## okstra Status — <project-id>
|
|
@@ -39,9 +38,9 @@ If `awaitingApproval` is true OR `routingStatus == "pending"`, append a `*` to t
|
|
|
39
38
|
| # | Task Key | Category | Phase | workStatus | Next |
|
|
40
39
|
|---|----------|----------|-------|------------|------|
|
|
41
40
|
| 1 | proj:group:id | bugfix | error-analysis | in-progress | implementation-planning |
|
|
42
|
-
| 2 | proj:group:id2 | feature | requirements-discovery | done |
|
|
41
|
+
| 2 | proj:group:id2 | feature | requirements-discovery | done | --* |
|
|
43
42
|
|
|
44
|
-
`*` = awaiting user approval or
|
|
43
|
+
`*` = awaiting user approval, or the next-phase pointer is not `ready`. Run `/okstra-inspect status <task-key>` for details.
|
|
45
44
|
```
|
|
46
45
|
|
|
47
46
|
### status.2 — Specific task status
|
|
@@ -52,7 +51,9 @@ Given a specific `task-key` or `task-group + task-id`:
|
|
|
52
51
|
2. If necessary, read `.okstra/tasks/<task-group>/<task-id>/task-manifest.json` directly.
|
|
53
52
|
3. If you need the latest run information, read `history/timeline.json` along with the latest run manifest.
|
|
54
53
|
|
|
55
|
-
Required fields: `taskKey`, `taskType`, `workCategory`, `currentStatus`, `latestRunStatus`, `workflow.{currentPhase, currentPhaseState, phaseStates, lastCompletedPhase, nextRecommendedPhase, awaitingApproval,
|
|
54
|
+
Required fields: `taskKey`, `taskType`, `workCategory`, `currentStatus`, `latestRunStatus`, `workflow.{currentPhase, currentPhaseState, phaseStates, lastCompletedPhase, nextRecommendedPhase, awaitingApproval, lastSafeCheckpoint}`, `workStatus`, `workStatusUpdatedAt`, `workStatusNote`, `latestReportPath`, `latestResumeCommandPath`, `historyTimelinePath`.
|
|
55
|
+
|
|
56
|
+
`workflow.nextRecommendedPhase` is the `{phase, status, rationale}` object described in `status.1` — read its three fields, do not print it whole. A `task-manifest.json` written before the object existed still holds a bare string there; `scripts/okstra_ctl/next_phase.py::promote` is what turns that string into the object, and every CLI-projected surface you can read instead (`task-catalog.json`, `okstra rollup`, `okstra recap`) has already applied it. Prefer those over a raw manifest rather than promoting a legacy string yourself.
|
|
56
57
|
|
|
57
58
|
```markdown
|
|
58
59
|
## okstra Task Status — <task-key>
|
|
@@ -61,9 +62,8 @@ Required fields: `taskKey`, `taskType`, `workCategory`, `currentStatus`, `latest
|
|
|
61
62
|
- Current phase: `<phase>`
|
|
62
63
|
- Current phase state: `<phase-state>`
|
|
63
64
|
- Last completed phase: `<phase-or-->`
|
|
64
|
-
- Next
|
|
65
|
+
- Next phase pointer: `<phase-or-->` (`<status>`) — `<rationale-or-->`
|
|
65
66
|
- Awaiting approval: `<yes|no>`
|
|
66
|
-
- Routing status: `<routing-status>`
|
|
67
67
|
- Task status: `<task-status>`
|
|
68
68
|
- Latest run status: `<run-status>`
|
|
69
69
|
- Latest report: `<relative-path-or-->`
|
|
@@ -95,9 +95,11 @@ The status response always includes one of:
|
|
|
95
95
|
|
|
96
96
|
1. **Resume current run** — if `latestResumeCommandPath` exists, display that path.
|
|
97
97
|
2. **Restart current phase** — task can be re-run with the same `task-key` and current `taskType`.
|
|
98
|
-
3
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
Branches 3–5 are decided by `workflow.nextRecommendedPhase.status` alone — one status, one branch, no other field consulted:
|
|
99
|
+
|
|
100
|
+
3. **Start next phase** — `status` is `ready`. Propose `nextRecommendedPhase.phase` as the next run's `--task-type` and quote its `rationale` as the reason. This is the only status under which a named phase may be launched, so it is the only branch that proposes a run. A `ready` pointer to `release-handoff` already implies an `accepted` final-verification verdict (the report validator refuses that routing target otherwise), so do not re-gate it here.
|
|
101
|
+
4. **Need more information** — `status` is `pending` (the last run did not settle where this task goes next) or `blocked` (it did settle, and the answer is that something outside the run has to change first). Neither proposes a run, and a leftover `phase` name does not change that — `prepare` keeps the name when it lowers a pointer to `pending`, so read `status`, not the emptiness of `phase`. Show the `rationale`, and for `blocked` state what it names as the obstacle. The way forward is a fresh brief, a clarification response, or a re-run of the current phase — not a next-phase launch.
|
|
102
|
+
5. **Task complete (terminal)** — `status` is `terminal`: the task lifecycle ends here. This is **not** a "next phase" — do not propose a new okstra run. Surface the latest report and ask the user whether any follow-up task should be opened separately.
|
|
101
103
|
|
|
102
104
|
### status.4 — Update workStatus (write)
|
|
103
105
|
|
|
@@ -135,7 +137,7 @@ Confirm in Korean (the block below shows the message shape only — render the a
|
|
|
135
137
|
|
|
136
138
|
| Manifest state | Inferred display |
|
|
137
139
|
|---|---|
|
|
138
|
-
| `currentStatus == "completed"` AND `workflow.nextRecommendedPhase == "
|
|
140
|
+
| `currentStatus == "completed"` AND `workflow.nextRecommendedPhase.status == "terminal"` | `done` (inferred) |
|
|
139
141
|
| `currentStatus == "completed"` AND `workflow.currentPhaseState == "completed"` | `phase-done` (inferred) |
|
|
140
142
|
| `currentStatus == "contract-violated"` OR `workflow.currentPhaseState == "blocked"` | `blocked` (inferred) |
|
|
141
143
|
| anything else | `in-progress` (default) |
|
|
@@ -42,6 +42,7 @@ Omit `--task-group` for the whole project. The JSON shape (all durations are **r
|
|
|
42
42
|
|
|
43
43
|
- `taskGroup` — the scope (`null` = whole project), `taskCount` — number of tasks.
|
|
44
44
|
- `tasks[]` — per task: `taskKey, taskGroup, taskId, taskType, workCategory, workStatus, currentPhase, currentPhaseState, nextRecommendedPhase, latestRunStatus, updatedAt, reportPath, runCount, cpuSumMs, wallClockMs, errorCount`, plus `criticRuns, criticGapsProposed, criticGapsMerged, criticGapsRejected, criticGapsUnverified`.
|
|
45
|
+
- `nextRecommendedPhase` is an **object** `{phase, status, rationale}`, not a phase-name string. Anywhere you surface it, print `nextRecommendedPhase.phase` — or `--` when that string is empty, which is what `status` `pending` / `blocked` / `terminal` all produce. Never interpolate the object into a table cell or a sentence: it renders as a raw dict.
|
|
45
46
|
- `totals` — `runs, cpuSumMs, wallClockMs, errors`, plus `byWorkStatus`, `byWorkCategory`, `byCurrentPhase`, `byTaskType` (each a `{value: count}` map), plus `critic` (`runsWithCritic, gapsProposed, gapsMerged, gapsRejected, gapsUnverified`).
|
|
46
47
|
- The coverage critic is opt-in, so `totals.critic.runsWithCritic == 0` means it was never used — report that as "not used", never as a zero-yield result. When it IS non-zero, the merge rate (`gapsMerged / gapsProposed`) is what tells the user whether the pass earns its tokens; state it only when at least one run used it.
|
|
47
48
|
|
|
@@ -32,7 +32,7 @@ Every wizard call returns JSON. The two shapes you'll see:
|
|
|
32
32
|
"progress": { "index": 5, "total": 11, "remaining": 6 } } }
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Every non-terminal `next` carries a `progress` object (`done` / `aborted` omit it). It holds `index` (1-based number of the **current screen**; pick_group counts as one screen), `total` (the wizard's forward estimate of the full screen count — may grow by a few when the user opens a branch, e.g.
|
|
35
|
+
Every non-terminal `next` carries a `progress` object (`done` / `aborted` omit it). It holds `index` (1-based number of the **current screen**; pick_group counts as one screen), `total` (the wizard's forward estimate of the full screen count — may grow by a few when the user opens a branch, e.g. role-add or extra role-model slots), `remaining` (`total − index`), and **`label`** — the ready-to-render marker the wizard already composed (e.g. `Step 10/11 · 1 step remaining`, or `Step 11/11 · final step` on the final screen). **Always suffix the rendered prompt with `progress.label` verbatim** — see Step 3. Do not recompute the marker or decide "final step" yourself; only the wizard knows whether more screens follow.
|
|
36
36
|
|
|
37
37
|
```json
|
|
38
38
|
{ "ok": false, "error": "approved plan has no APPROVED marker: ...",
|
|
@@ -179,14 +179,14 @@ Repeat until `next.kind == "done"` (or `"aborted"` — terminal cancel, see "How
|
|
|
179
179
|
That is the entire interactive flow. The wizard handles:
|
|
180
180
|
|
|
181
181
|
- new-vs-existing task split (remaining work — `workStatus != done` — top-3 newest recommendations + Enter directly), task-group / task-id slug validation (task-group offers the top-3 newest candidates combining recent task use + recent `.okstra/briefs/<group>/` creation activity + Enter directly; task-id offers the top-3 recent candidates from the same group + Enter directly),
|
|
182
|
-
- task-type pick (3
|
|
182
|
+
- task-type pick (3 options + Enter directly; Enter directly is validated against the full task-type whitelist in a follow-up `text` step). What fills those three depends on `workflow.nextRecommendedPhase` — an object `{phase, status, rationale}`, not a phase-name string. `status: ready` gives the classic trio: its `phase` marked recommended, re-run the current phase, the lifecycle's next step. Any other status contributes nothing at all, since both the recommended slot and the next-step slot derive from that phase — re-run the current phase becomes the first option and the remaining slots fill unlabelled from recently used task-types and then the whitelist. Never recover a phase name from a non-`ready` pointer and propose it yourself: prepare deliberately lowers the pointer to `pending` while its run is unfinished, and the missing recommendation is that signal,
|
|
183
183
|
- brief path — **asked only for entry task-types (requirements-discovery / error-analysis / improvement-discovery / project-analysis / feature-analysis / change-impact-analysis)** (same-group `.okstra/briefs/<task-group>/**/*.md` candidates first, sorted by the newer of file-created/modified time and latest task-catalog use; direct input last; `Keep / Change` for existing entry tasks). `project-analysis`, `feature-analysis`, and `change-impact-analysis` are brief entry task types. A downstream lifecycle task-type auto carries in the manifest's brief, and when no registered brief exists a `brief_carry` 3-option prompt appears (recommend switching to entry / Enter directly / Abort). `release-handoff` has no brief step at all — prepare generates the input document that cites the verification report,
|
|
184
184
|
- analysis-input sub-flow — `project-analysis` has no target or evidence step. `feature-analysis` runs `project_evidence_pick` / `project_evidence`, then `analysis_target_pick` / `analysis_target`; the target is required even when the user skips project evidence. `change-impact-analysis` runs `feature_evidence_pick` / `feature_evidence`, then `project_evidence_pick` / `project_evidence`. The evidence steps show accepted compatible reports first and retain direct-path entry; do not invent a different relation or reorder these steps,
|
|
185
185
|
- base-ref pick + git rev-parse validation (skipped when reusing an active worktree),
|
|
186
|
-
- `implementation`-only sub-flow: approved-plan path (frontmatter `approved: true` check) + stage pick (`auto` = the earliest incomplete stage whose dependencies are satisfied, or a specific stage number)
|
|
186
|
+
- `implementation`-only sub-flow: approved-plan path (frontmatter `approved: true` check) + stage pick (`auto` = the earliest incomplete stage whose dependencies are satisfied, or a specific stage number). Implementer slots use role-count / role-model like every other role (`executor` is only a compatibility alias for `implementer`). When an approved plan is selected and a `## PLAN DECISION` sidecar carrying `Status: approved`, exported from the report — matching the plan on source-report·seq — is detected in that run's sibling `user-responses/`, the approve-confirm step expands to 3 options (`yes_apply` recommended: approve + apply the option as exported / `yes` approve only / `no` abort) — `yes_apply` validates the option against the plan's `optionCandidates` before applying it via the existing approval·option path,
|
|
187
187
|
- `release-handoff`-only sub-flow: after the approved plan auto-resolves, a `handoff_stage_pick` multi-select — choose an eligible stage bundle (stage-group) or the whole task (when an accepted whole-task verification report exists); the result goes out as render-args' `stages` key (csv, empty when whole-task),
|
|
188
|
-
- `
|
|
189
|
-
- **resume-clarification (in-session equivalent)** — there is no separate mode or flag matching the shell's `okstra.sh --resume-clarification`; two steps of the standard flow carry out its substance. (1) `reuse_previous` (yes/no to reuse the previous run's settings — in `requirements-discovery` / `error-analysis` / `implementation-planning`, only when prior run-inputs exist): YES prefills
|
|
188
|
+
- launch selection after identity/worktree steps: leader session read-only (current-session) → role-count per static role (`min..max`, omit uses **recommended**, skip when `min == max`) → role-model `provider/model` per slot → min=0 roles only via role-add (default skip). The wizard does not fork on defaults-vs-customize, does not show a provider roster multi-pick, and does not offer a separate implementer-provider pick. Dynamic verifiers are not chosen at launch. `--workers` is compatibility-only, not a launch picker. Repeated `--role-count` / `--role-model` tokens on `renderArgv` are intentional,
|
|
189
|
+
- **resume-clarification (in-session equivalent)** — there is no separate mode or flag matching the shell's `okstra.sh --resume-clarification`; two steps of the standard flow carry out its substance. (1) `reuse_previous` (yes/no to reuse the previous run's settings — in `requirements-discovery` / `error-analysis` / `implementation-planning`, only when prior run-inputs exist): YES prefills role-count·role-model·directive·related-tasks at once. (2) `clarification_pick`: if the **task-type's own** previous `final-report` exists it is auto-recommended as the carry-in input (falling back to the newest by mtime across all phases when absent), and the same run's `user-responses/` sidecar (answers the user filled in) is attached alongside. The chosen path is passed to prepare as `--clarification-response` — the user makes the sidecar via the report's `Export user response`, places it in `runs/<task-type>/user-responses/`, and re-runs the same phase,
|
|
190
190
|
- **re-verification scope (`reverify_scope_pick`, `implementation-planning` clarification re-runs only)** — asked right before `confirm`, and **only when the re-run is narrowable** (every answered `C-NNN` traces back to a stage in the prior report). 3 options: `auto` (recommended — leave it to the lead's `okstra incremental-scope` decision) / `full` (re-verify every stage) / Enter directly (a stage-number CSV, validated against the prior report's Stage Map). The answer goes out as `--reverify-scope` and reaches the lead prompt as the `REVERIFY_SCOPE_MODE` / `REVERIFY_SCOPE_STAGES` tokens; it shapes that CLI's inputs rather than replacing the decision. When the re-run is not narrowable the step does not appear — full is already fixed, and the confirmation block's `reverify-scope` line says which answered id broke the link,
|
|
191
191
|
- `release-handoff` PR template override + persist scope,
|
|
192
192
|
- final `Proceed / Edit` confirmation; on `Edit` the wizard asks which step to rewind to and clears every later answer.
|
|
@@ -220,9 +220,9 @@ When `next.kind == "done"`, fetch the public wizard outcome:
|
|
|
220
220
|
okstra wizard outcome --state-file /var/folders/.../okstra-wizard.AbCd.json
|
|
221
221
|
```
|
|
222
222
|
|
|
223
|
-
Output: `{ok: true, outcome: {renderArgs: {...}, orchestration: {chainStages: "..."}, persistActions: [...], confirmationText: "..."}}`.
|
|
223
|
+
Output: `{ok: true, outcome: {renderArgv: ["--lead-runtime", "...", ...], renderArgs: {...}, orchestration: {chainStages: "..."}, persistActions: [...], confirmationText: "..."}}`.
|
|
224
224
|
|
|
225
|
-
`
|
|
225
|
+
`renderArgv` is the canonical ordered `okstra render-bundle` argument list. Pass its tokens verbatim and in order. Repeated `--role-count` and `--role-model` flags are intentional. `renderArgs` is a compatibility and inspection view only; do not reconstruct an invocation from it. `orchestration` holds signals this skill acts on itself — never pass its entries to `render-bundle`.
|
|
226
226
|
|
|
227
227
|
Run every `outcome.persistActions[]` entry BEFORE `render-bundle`. The only supported action is:
|
|
228
228
|
|
|
@@ -243,19 +243,19 @@ Before rendering the next phase's bundle — and between worker rounds within a
|
|
|
243
243
|
|
|
244
244
|
Before you ask the user for any approval, clarification, or decision after workers have been dispatched, run the same reclaim first: `$HOME/.okstra/bin/okstra-trace-cleanup.sh --list --run-dir "<RUN_DIR>" [--keep report-writer-worker]` to count the panes, then the same command without `--list` to close them, emit `PROGRESS: phase-gate-cleanup panes=<n>`, and `TaskStop` each completed worker. A `TaskStop` by itself idles the task but leaves the pane open — the `trace-cleanup` call is what actually closes it. This keeps a user gate from being shown while finished worker panes remain; in-flight workers and an in-flight report writer are preserved.
|
|
245
245
|
|
|
246
|
-
Build the `okstra render-bundle` invocation from `outcome.
|
|
246
|
+
Build the `okstra render-bundle` invocation from `outcome.renderArgv`, passing every token verbatim and in order (including empty strings — they are intentional `use phase default` markers).
|
|
247
247
|
|
|
248
|
-
Analysis sidetracks therefore forward wizard-owned
|
|
248
|
+
Analysis sidetracks therefore forward wizard-owned tokens such as `--analysis-target "<value>"` and `--evidence-inputs "<value>"` when they are present. These are examples of the verbatim token rule, not a separate hard-coded argument list.
|
|
249
249
|
|
|
250
|
-
Step 3's empty-answer and escaping rules apply verbatim: every flag whose value is the empty string MUST still be passed explicitly
|
|
250
|
+
Step 3's empty-answer and escaping rules apply verbatim: every flag in `renderArgv` whose following value is the empty string MUST still be passed explicitly (e.g. `--workers ""`, `--directive ""`) — `render-bundle` distinguishes "flag absent" from "flag present with empty value", and the wizard's intent is always the latter.
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
`renderArgv` already contains exactly one `--lead-runtime <host-runtime>` pair. Do not add or replace it. Do not enumerate a fixed provider list in this skill because the wizard and role model pool own the ordered tokens.
|
|
253
253
|
|
|
254
254
|
```bash
|
|
255
255
|
okstra render-bundle \
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
256
|
+
<outcome.renderArgv token 1> \
|
|
257
|
+
<outcome.renderArgv token 2> \
|
|
258
|
+
<each remaining outcome.renderArgv token in order>
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
`render-bundle` auto-supplies `--workspace-root` and forces `--render-only`. Stdout prints `okstra task root:`, `okstra instruction-set:`, `okstra run manifest:`, and the full rendered lead prompt. Parse the labelled lines for `TASK_ROOT`, `INSTRUCTION_SET_PATH`, and `RUN_MANIFEST_PATH`. Also watch for an optional `okstra concurrent-run stages:` label line — present only when a concurrent run is detected (see "Concurrent-run detection branch" below).
|
|
@@ -29,24 +29,9 @@ When `**Evidence ledger:** required-v1` is present, append one canonical row to
|
|
|
29
29
|
|
|
30
30
|
Every file citation in the result MUST use backticks, a line suffix, and the same project-relative path its ledger row carries — for example `src/config/env.ts:1-22`. A bare filename (`env.ts:1-22`) does not match its row and fails exactly like a file you never opened, however many times you cited the full path earlier. A cited path without a matching ledger row fails Phase 7 in `validators/validate-run.py` `validate_worker_results_audit()`. Do not add a row for a file you did not open.
|
|
31
31
|
|
|
32
|
-
##
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
1. `**Project Root:** <absolute-path>`
|
|
37
|
-
2. `**Prompt History Path:** <project-relative-path>`
|
|
38
|
-
3. `**Result Path:** <project-relative-path>`
|
|
39
|
-
4. `Assigned worker prompt history path: <absolute-path>`
|
|
40
|
-
5. `**Worker Preamble Path:** <absolute-path>`
|
|
41
|
-
6. `**Worker Error Contract Path:** <absolute-path>`
|
|
42
|
-
7. `**Coding preflight pack:** <absolute-path>`
|
|
43
|
-
8. `**Evidence ledger:** required-v1`
|
|
44
|
-
9. `**Evidence citations:** <rule>` — the ledger-row and citation-path rule of §"Evidence read ledger", restated inline so it is in front of you before your first citation.
|
|
45
|
-
10. `**Errors log path:** <absolute-path>`
|
|
46
|
-
11. `**Errors sidecar path:** <absolute-path>`
|
|
47
|
-
12. `**Read scope:** <allowlist>`
|
|
48
|
-
|
|
49
|
-
The implementation body additionally carries `**Worktree:**` and its role-sidecar inputs. Do not synthesize any missing path.
|
|
32
|
+
## Injected paths
|
|
33
|
+
|
|
34
|
+
Use the path headers in the dispatch prompt exactly as written, including `**Coding preflight pack:**` and `**Worktree:**` when present. Do not synthesize any missing path.
|
|
50
35
|
|
|
51
36
|
## Return message to the lead
|
|
52
37
|
|
|
@@ -36,7 +36,6 @@ taskType: "{{FM_TASK_TYPE}}"
|
|
|
36
36
|
- Last Completed Phase: `{{WORKFLOW_LAST_COMPLETED_PHASE}}`
|
|
37
37
|
- Next Recommended Phase: `{{WORKFLOW_NEXT_RECOMMENDED_PHASE}}`
|
|
38
38
|
- Awaiting Approval: `{{WORKFLOW_AWAITING_APPROVAL}}`
|
|
39
|
-
- Routing Status: `{{WORKFLOW_ROUTING_STATUS}}`
|
|
40
39
|
- Fix cycles: {{FIX_CYCLES_SUMMARY}}
|
|
41
40
|
|
|
42
41
|
## Phase States
|
|
@@ -22,6 +22,8 @@ Write `- PROGRESS: <stage> <ISO-8601-UTC>` there before reading and at least eve
|
|
|
22
22
|
|
|
23
23
|
The generated prompt selects this file through `**Worker Preamble Path:**` and includes `**Worker Error Contract Path:**`, `**Audit sidecar path:**`, error paths, and read scope. It never includes `**Coding preflight pack:**`.
|
|
24
24
|
|
|
25
|
+
The adjacent v2 prompt metadata supplies `participantRef`, `roleExecutionRef`, `executionLabel`, `invocationRef`, and `attempt`. Copy those values into report and audit identity fields without deriving them from the provider or model. Legacy v1 `workerId` is a read-only compatibility projection and is not written into v2 artifacts.
|
|
26
|
+
|
|
25
27
|
## Return message to the lead
|
|
26
28
|
|
|
27
29
|
Begin the inline return with the exact `**Model:** Report writer worker, <modelExecutionValue>` line from the prompt, followed by the artifact status. Never invent or abbreviate the model.
|
|
@@ -25,7 +25,7 @@ schema-version: {{ schemaVersion | yaml_scalar }}
|
|
|
25
25
|
is a non-authoritative index of `finalVerdict`, which §Final Verdict already
|
|
26
26
|
carries in full.
|
|
27
27
|
-#}
|
|
28
|
-
{{ md_claim("schemaVersion", "meta", "frontmatter", "header", "humanSummary", "verdictCard") }}
|
|
28
|
+
{{ md_claim("schemaVersion", "meta", "frontmatter", "header", "humanSummary", "verdictCard", "executionRoles", "executionIdentityVersion") }}
|
|
29
29
|
|
|
30
30
|
# {{ frontmatter.title }}
|
|
31
31
|
|
|
@@ -44,6 +44,12 @@ schema-version: {{ schemaVersion | yaml_scalar }}
|
|
|
44
44
|
- Rationale IDs: {{ finalVerdict.rationaleRowIds | join(", ") }}
|
|
45
45
|
- Blocking IDs: {{ aiBlockingIds | join(", ") if aiBlockingIds else "none" }}
|
|
46
46
|
- Next step: {{ finalVerdict.nextStep }}
|
|
47
|
+
{% if executionIdentityVersion == 2 %}
|
|
48
|
+
|
|
49
|
+
## Execution Roles
|
|
50
|
+
|
|
51
|
+
{{ executionRolesTable }}
|
|
52
|
+
{% endif %}
|
|
47
53
|
|
|
48
54
|
## Decision Context
|
|
49
55
|
|
|
@@ -21,6 +21,27 @@
|
|
|
21
21
|
</dl>
|
|
22
22
|
<p class="lede">{{ humanSummary.headline | inline_code }}</p>
|
|
23
23
|
<p>{{ humanSummary.outcome | inline_code }}</p>
|
|
24
|
+
{% if executionRoles %}
|
|
25
|
+
<section data-report-section="execution-roles">
|
|
26
|
+
<h2>{{ t('base.execution-roles') }}</h2>
|
|
27
|
+
<table>
|
|
28
|
+
<thead><tr>
|
|
29
|
+
<th scope="col">{{ t('base.role') }}</th>
|
|
30
|
+
<th scope="col">{{ t('base.execution-label') }}</th>
|
|
31
|
+
<th scope="col">{{ t('base.status') }}</th>
|
|
32
|
+
</tr></thead>
|
|
33
|
+
<tbody>
|
|
34
|
+
{% for row in executionRoles %}
|
|
35
|
+
<tr>
|
|
36
|
+
<td>{{ row.role }}</td>
|
|
37
|
+
<td><code>{{ row.executionLabel }}</code></td>
|
|
38
|
+
<td>{{ row.status }}</td>
|
|
39
|
+
</tr>
|
|
40
|
+
{% endfor %}
|
|
41
|
+
</tbody>
|
|
42
|
+
</table>
|
|
43
|
+
</section>
|
|
44
|
+
{% endif %}
|
|
24
45
|
</header>
|
|
25
46
|
<main id="main-content" data-report-role="human-main">
|
|
26
47
|
{% block human_content %}{% endblock %}
|
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
"skip-to-report-content": "Skip to report content",
|
|
97
97
|
"contents": "Contents",
|
|
98
98
|
"task": "Task",
|
|
99
|
+
"execution-roles": "Execution roles",
|
|
100
|
+
"role": "Role",
|
|
101
|
+
"execution-label": "Execution label",
|
|
102
|
+
"status": "Status",
|
|
99
103
|
"task-key": "Task key",
|
|
100
104
|
"written": "Written",
|
|
101
105
|
"elapsed": "Elapsed",
|
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
"skip-to-report-content": "리포트 본문으로 건너뛰기",
|
|
97
97
|
"contents": "목차",
|
|
98
98
|
"task": "태스크",
|
|
99
|
+
"execution-roles": "실행 역할",
|
|
100
|
+
"role": "역할",
|
|
101
|
+
"execution-label": "실행 표지",
|
|
102
|
+
"status": "상태",
|
|
99
103
|
"task-key": "태스크 키",
|
|
100
104
|
"written": "작성",
|
|
101
105
|
"elapsed": "소요 시간",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
{% for row in items %}
|
|
64
64
|
{% set is_closed = row.status in ['resolved', 'obsolete'] %}
|
|
65
65
|
{% set approval_context = row.approvalContext | default(None) %}
|
|
66
|
+
{% set options = row.options | default([]) %}
|
|
66
67
|
<article class="clarification-item" id="id-{{ row.id }}" data-response-id="{{ row.id }}" data-kind="{{ row.kind }}" data-status="{{ row.status }}">
|
|
67
68
|
<p class="eyebrow">{{ row.id }} · {{ row.kind }}</p>
|
|
68
69
|
{{ row.statement | paragraphs }}
|
|
@@ -76,9 +77,9 @@
|
|
|
76
77
|
</p>
|
|
77
78
|
</div>
|
|
78
79
|
{% endif %}
|
|
79
|
-
{% if
|
|
80
|
+
{% if options %}
|
|
80
81
|
<ol class="clarification-options">
|
|
81
|
-
{% for option in
|
|
82
|
+
{% for option in options %}
|
|
82
83
|
<li class="clarification-option{% if option.role == 'recommended' %} is-recommended{% endif %}">
|
|
83
84
|
<p class="clarification-option-answer">{{ option.answer }}{% if option.role == 'recommended' %} <span class="badge">{{ t('macros.forms.recommended') }}</span>{% endif %}</p>
|
|
84
85
|
{% if option.disposition | default(None) %}<p class="clarification-option-disposition"><code>{{ option.disposition }}</code></p>{% endif %}
|
|
@@ -93,10 +94,10 @@
|
|
|
93
94
|
</ol>
|
|
94
95
|
{% endif %}
|
|
95
96
|
<label for="response-{{ row.id }}">{{ t('macros.forms.your-answer-to-id') | replace('{id}', row.id) }}</label>
|
|
96
|
-
{% if row.kind == 'decision' and approval_context and
|
|
97
|
+
{% if row.kind == 'decision' and approval_context and options %}
|
|
97
98
|
<select id="response-{{ row.id }}" data-response-id="{{ row.id }}"{% if is_closed %} disabled{% endif %}>
|
|
98
99
|
<option value="">{{ t('macros.forms.choose-one') }}</option>
|
|
99
|
-
{% for option in
|
|
100
|
+
{% for option in options %}<option value="{{ option.answer }}" data-disposition="{{ option.disposition | default('') }}"{% if option.role == 'recommended' %} data-recommended="true"{% endif %}{% if row.userInput | default('') == option.answer %} selected{% endif %}>{{ option.answer }}</option>{% endfor %}
|
|
100
101
|
</select>
|
|
101
102
|
{% else %}
|
|
102
103
|
<textarea id="response-{{ row.id }}" data-response-id="{{ row.id }}" rows="4"{% if is_closed %} disabled{% endif %}>{{ row.userInput | default('') }}</textarea>
|
|
@@ -41,6 +41,6 @@
|
|
|
41
41
|
<section data-report-section="release-route">
|
|
42
42
|
<h2>{{ t('tasks.final-verification.release-path') }}</h2>
|
|
43
43
|
{{ render_narrative(narrative.releaseReadiness, "finalVerification.userNarrative.releaseReadiness") }}
|
|
44
|
-
{% if releaseAllowed %}<p>{{ final.routingRecommendation | inline_code }}</p>{% else %}<p>{{ t('tasks.final-verification.the-current-verdict-does-not-allow-release-h') }}</p>{% endif %}
|
|
44
|
+
{% if releaseAllowed %}<p><strong><code>{{ final.routingRecommendation.target }}</code></strong> — {{ final.routingRecommendation.rationale | inline_code }}</p>{% else %}<p>{{ t('tasks.final-verification.the-current-verdict-does-not-allow-release-h') }}</p>{% endif %}
|
|
45
45
|
</section>
|
|
46
46
|
{% endblock %}
|
|
@@ -53,6 +53,6 @@
|
|
|
53
53
|
|
|
54
54
|
<section data-report-section="next-step" data-report-field="implementation.routingRecommendation">
|
|
55
55
|
<h2>{{ t('tasks.implementation.next-step') }}</h2>
|
|
56
|
-
<p>{{ implementation.routingRecommendation | inline_code }}</p>
|
|
56
|
+
<p><strong><code>{{ implementation.routingRecommendation.target }}</code></strong> — {{ implementation.routingRecommendation.rationale | inline_code }}</p>
|
|
57
57
|
</section>
|
|
58
58
|
{% endblock %}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
This file is the audience-specific contract for initial `analysis` workers. Read it end-to-end from the path selected by the dispatch prompt. Before doing work, also read the shared file named by `**Worker Error Contract Path:**`; that file is the only source for error-sidecar rules.
|
|
4
4
|
|
|
5
|
+
Your identity is the stored role execution (`executionLabel`). Canonical roles are `leader`, `analyser`, `critic`, `designer`, `planner`, `implementer`, `verifier`, `report-writer`, and `translator`. `lead` and `executor` are compatibility aliases only.
|
|
6
|
+
|
|
5
7
|
## Required reading
|
|
6
8
|
|
|
7
9
|
Read `analysis-packet.md`, the primary compact input, end-to-end. Source files named as fallback/evidence paths are read only when a finding needs to verify a citation, fill a packet gap, or resolve ambiguity. Do not read `final-report-template.md` or `final-report-schema.json`; analysis workers produce findings, not the final report.
|
|
@@ -23,34 +25,15 @@ Every file citation in the result MUST use backticks, a line suffix, and the sam
|
|
|
23
25
|
|
|
24
26
|
## Evidence command ledger
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- Evidence command: {"command":"npm run check","cwd":"<project-root>","exitCode":0,"outputSummary":"all checks passed"}
|
|
29
|
-
|
|
30
|
-
Do not record commands used only to explore, including `rg`, `ls`, and file-opening commands. Do not record environment variable values, tokens, credentials, or authorization headers. `okstra worker-audit-check` rejects malformed command rows and rows containing potential sensitive material through `okstra_ctl.worker_audit_ledger`.
|
|
28
|
+
Follow the `**Evidence commands:**` header in the dispatch prompt. That header is the worker-facing rule.
|
|
31
29
|
|
|
32
|
-
##
|
|
30
|
+
## Injected paths
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
1. `**Project Root:** <absolute-path>`
|
|
37
|
-
2. `**Prompt History Path:** <project-relative-path>`
|
|
38
|
-
3. `**Result Path:** <project-relative-path>`
|
|
39
|
-
4. `**Audit sidecar path:** <absolute-path>` — the generated audit destination; write the sidecar here and never synthesize a `runs/<task-type>/...` path.
|
|
40
|
-
5. `Assigned worker prompt history path: <absolute-path>`
|
|
41
|
-
6. `**Worker Preamble Path:** <absolute-path>` — selects this analysis preamble.
|
|
42
|
-
7. `**Worker Error Contract Path:** <absolute-path>` — shared by every initial audience.
|
|
43
|
-
8. `**Evidence ledger:** required-v1`
|
|
44
|
-
9. `**Evidence citations:** <rule>` — the ledger-row and citation-path rule of §"Evidence read ledger", restated inline so it is in front of you before your first citation.
|
|
45
|
-
10. `**Errors log path:** <absolute-path>`
|
|
46
|
-
11. `**Errors sidecar path:** <absolute-path>`
|
|
47
|
-
12. `**Read scope:** <allowlist>`
|
|
48
|
-
|
|
49
|
-
`final-verification` additionally carries its six verification-target anchors. `improvement-discovery` carries `**Phase 1.5 Grilling Log:**`. Reverify prompts are lightweight and do not use this preamble.
|
|
32
|
+
Use the path headers in the dispatch prompt exactly as written. Do not synthesize a missing path from a run-directory pattern. `final-verification` may carry verification-target headers. `improvement-discovery` may carry `**Phase 1.5 Grilling Log:**`. Treat extra generated headers the same way. Reverify prompts are lightweight and do not use this preamble.
|
|
50
33
|
|
|
51
34
|
## Worker output sections
|
|
52
35
|
|
|
53
|
-
Every analysis result starts with YAML frontmatter containing the task identity and `
|
|
36
|
+
Every analysis result starts with YAML frontmatter containing the task identity, `participantRef`, `roleExecutionRef`, `executionLabel`, `invocationRef`, and `attempt`, followed by a header with the actual `**Model:**` value. Copy these execution fields from the generated prompt metadata; do not derive them from the provider or model name. Legacy v1 prompts may expose only `workerId`, which is a read-only compatibility projection and must not be written into a v2 result. Then emit these sections in exact order:
|
|
54
37
|
|
|
55
38
|
1. Findings
|
|
56
39
|
2. Missing Information or Assumptions
|
|
@@ -61,18 +44,6 @@ Every analysis result starts with YAML frontmatter containing the task identity
|
|
|
61
44
|
|
|
62
45
|
Every item has a worker-local ID and file:line evidence where code evidence exists. Sections 1–5 are the common core: feasibility, requirement interpretation, hidden assumptions, alternatives, and execution risk. Section 6 is the only legal home for specialization and is not consensus input.
|
|
63
46
|
|
|
64
|
-
### Selected-direction planning ownership
|
|
65
|
-
|
|
66
|
-
For `implementation-planning` with `selected-direction.json`, sections 1–5 read that snapshot and the original requirements, then assess only its realization into files, interfaces, stages, validation, rollback, bidirectional requirement links, and `direction-invalidated` evidence. Direction selection remains upstream of this prompt.
|
|
67
|
-
|
|
68
|
-
### Legacy candidate-comparison ownership
|
|
69
|
-
|
|
70
|
-
For an implementation-planning compatibility rerun without the snapshot, sections 1–5 retain candidate comparison, trade-off, recommendation, and `P-Opt-*` evidence.
|
|
71
|
-
|
|
72
|
-
### Ticket Tagging
|
|
73
|
-
|
|
74
|
-
For `requirements-discovery`, `error-analysis`, and `implementation-planning`, tag every section 1–5 item with its related ticket. Use `Issue / Ticket`, fall back to Task ID, then `unknown`; comma-separate multiple tickets.
|
|
75
|
-
|
|
76
47
|
## Return message to the lead
|
|
77
48
|
|
|
78
49
|
Begin the inline return with the model identity copied verbatim from the `**Model:** <Role>, <modelExecutionValue>` line in the prompt, followed by the status summary. Never invent or abbreviate the model.
|
|
@@ -138,6 +138,7 @@ prompt_path.write_text(
|
|
|
138
138
|
f"{target_worker_id}-errors.json",
|
|
139
139
|
f"Assigned worker prompt history path: {prompt_relative}",
|
|
140
140
|
"**Prompt Delivery Mode:** eager-include",
|
|
141
|
+
f"**Model:** Fixture worker, {target_worker.get('modelExecutionValue', '')}",
|
|
141
142
|
f"- Primary analysis packet: `{analysis_packet_path}`",
|
|
142
143
|
"",
|
|
143
144
|
"# Initial Analysis Prompt",
|
|
@@ -222,7 +223,7 @@ for worker in team_state.get("workers", []):
|
|
|
222
223
|
worker["reason"] = reason_by_worker_id.get(worker_id, "Validation fixture not used")
|
|
223
224
|
|
|
224
225
|
prompt_relative = str(worker.get("promptPath", "")).strip()
|
|
225
|
-
if prompt_relative
|
|
226
|
+
if prompt_relative:
|
|
226
227
|
prompt_path = project_root / prompt_relative
|
|
227
228
|
prompt_path.parent.mkdir(parents=True, exist_ok=True)
|
|
228
229
|
prompt_lines = [
|
|
@@ -232,6 +233,7 @@ for worker in team_state.get("workers", []):
|
|
|
232
233
|
f"{worker_id}-errors.json",
|
|
233
234
|
f"Assigned worker prompt history path: {prompt_relative}",
|
|
234
235
|
"**Prompt Delivery Mode:** eager-include",
|
|
236
|
+
f"**Model:** Fixture worker, {worker.get('modelExecutionValue', '')}",
|
|
235
237
|
]
|
|
236
238
|
if worker_id != "report-writer":
|
|
237
239
|
prompt_lines.append(
|
|
@@ -570,6 +572,7 @@ if WORKSPACE_ROOT:
|
|
|
570
572
|
AgentInstructionSource,
|
|
571
573
|
AgentInvocationRequest,
|
|
572
574
|
agent_model_assignment_from_payload,
|
|
575
|
+
invocation_execution_identity_from_manifest,
|
|
573
576
|
prepare_agent_invocation,
|
|
574
577
|
)
|
|
575
578
|
from okstra_ctl.dispatch_state import (
|
|
@@ -602,7 +605,7 @@ if WORKSPACE_ROOT:
|
|
|
602
605
|
contract = run_manifest["agentContract"]
|
|
603
606
|
reservation_root = project_root / contract["invocationReservationRootPath"]
|
|
604
607
|
for worker in team_state.get("workers", []):
|
|
605
|
-
if not isinstance(worker, dict)
|
|
608
|
+
if not isinstance(worker, dict):
|
|
606
609
|
continue
|
|
607
610
|
worker_id = str(worker.get("workerId") or "").strip()
|
|
608
611
|
prompt_relative = str(worker.get("promptPath") or "").strip()
|
|
@@ -615,18 +618,37 @@ if WORKSPACE_ROOT:
|
|
|
615
618
|
assignment_ref = f"initial/{worker_id}"
|
|
616
619
|
invocation_id = f"validation-fixture-{worker_id}"
|
|
617
620
|
invocation_prompt = reservation_root / f"{invocation_id}.prompt.md"
|
|
621
|
+
audience = (
|
|
622
|
+
"report-writer" if worker_id == "report-writer"
|
|
623
|
+
else analysis_audience
|
|
624
|
+
)
|
|
625
|
+
assignment = agent_model_assignment_from_payload(
|
|
626
|
+
assignments[assignment_ref]
|
|
627
|
+
)
|
|
628
|
+
identity = invocation_execution_identity_from_manifest(
|
|
629
|
+
run_manifest,
|
|
630
|
+
assignment=assignment,
|
|
631
|
+
assignment_ref=assignment_ref,
|
|
632
|
+
duty_id=audience,
|
|
633
|
+
)
|
|
634
|
+
identity_args = {
|
|
635
|
+
"participant_ref": (
|
|
636
|
+
identity.participant_ref if identity is not None else None
|
|
637
|
+
),
|
|
638
|
+
"role_execution_ref": (
|
|
639
|
+
identity.role_execution_ref if identity is not None else None
|
|
640
|
+
),
|
|
641
|
+
"duty_id": identity.duty_id if identity is not None else None,
|
|
642
|
+
"invocation_ref": invocation_id if identity is not None else None,
|
|
643
|
+
"attempt": 1,
|
|
644
|
+
}
|
|
618
645
|
prepared = prepare_agent_invocation(AgentInvocationRequest(
|
|
619
646
|
invocation_id=invocation_id,
|
|
620
|
-
worker_id=worker_id,
|
|
621
|
-
audience=
|
|
622
|
-
"report-writer" if worker_id == "report-writer"
|
|
623
|
-
else analysis_audience
|
|
624
|
-
),
|
|
647
|
+
worker_id=worker_id if identity is None else None,
|
|
648
|
+
audience=audience,
|
|
625
649
|
assignment_ref=assignment_ref,
|
|
626
650
|
purpose=None,
|
|
627
|
-
assignment=
|
|
628
|
-
assignments[assignment_ref]
|
|
629
|
-
),
|
|
651
|
+
assignment=assignment,
|
|
630
652
|
instruction=AgentInstruction(
|
|
631
653
|
anchor_lines=(),
|
|
632
654
|
body=source_prompt.read_text(encoding="utf-8"),
|
|
@@ -642,6 +664,7 @@ if WORKSPACE_ROOT:
|
|
|
642
664
|
invocation_prompt.name + ".meta.json"
|
|
643
665
|
),
|
|
644
666
|
dispatch_kind="validation-fixture",
|
|
667
|
+
**identity_args,
|
|
645
668
|
))
|
|
646
669
|
dispatch = record_verified_agent_dispatch(
|
|
647
670
|
project_root=project_root,
|
|
@@ -653,11 +676,21 @@ if WORKSPACE_ROOT:
|
|
|
653
676
|
else "core-pre-dispatch"
|
|
654
677
|
),
|
|
655
678
|
)
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
679
|
+
if worker.get("status") == "completed":
|
|
680
|
+
link_agent_dispatch_result(
|
|
681
|
+
project_root=project_root,
|
|
682
|
+
run_manifest_path=run_manifest_path,
|
|
683
|
+
dispatch_id=dispatch["dispatchId"],
|
|
684
|
+
result_path=project_root / result_relative,
|
|
685
|
+
)
|
|
686
|
+
|
|
687
|
+
# Preserve the workflow's historical missing-prompt negative after the v2
|
|
688
|
+
# invocation record has captured the prompt bytes that were actually sent.
|
|
689
|
+
for worker in team_state.get("workers", []):
|
|
690
|
+
if isinstance(worker, dict) and worker.get("workerId") == omitted_worker_id:
|
|
691
|
+
omitted_prompt = str(worker.get("promptPath") or "").strip()
|
|
692
|
+
if omitted_prompt:
|
|
693
|
+
(project_root / omitted_prompt).unlink(missing_ok=True)
|
|
694
|
+
break
|
|
662
695
|
PY
|
|
663
696
|
}
|