okstra 0.186.7 → 0.187.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli-registry.d.mts +88 -1
- package/dist/cli-registry.mjs +68 -111
- package/dist/cli-registry.mjs.map +1 -1
- package/dist/commands/execute/render-bundle.mjs +0 -1
- package/dist/commands/execute/render-bundle.mjs.map +1 -1
- package/dist/commands/execute/run.mjs +8 -3
- package/dist/commands/execute/run.mjs.map +1 -1
- package/dist/commands/lifecycle/check-project.mjs +1 -14
- package/dist/commands/lifecycle/check-project.mjs.map +1 -1
- package/dist/commands/lifecycle/config.mjs +38 -40
- package/dist/commands/lifecycle/config.mjs.map +1 -1
- package/dist/commands/lifecycle/doctor.d.mts +22 -7
- package/dist/commands/lifecycle/doctor.mjs +77 -49
- package/dist/commands/lifecycle/doctor.mjs.map +1 -1
- package/dist/commands/lifecycle/install.d.mts +12 -10
- package/dist/commands/lifecycle/install.mjs +104 -39
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/dist/commands/lifecycle/paths.mjs +8 -3
- package/dist/commands/lifecycle/paths.mjs.map +1 -1
- package/dist/commands/lifecycle/preflight.mjs +2 -1
- package/dist/commands/lifecycle/preflight.mjs.map +1 -1
- package/dist/commands/lifecycle/setup.mjs +22 -36
- package/dist/commands/lifecycle/setup.mjs.map +1 -1
- package/dist/commands/lifecycle/uninstall.d.mts +4 -2
- package/dist/commands/lifecycle/uninstall.mjs +59 -15
- package/dist/commands/lifecycle/uninstall.mjs.map +1 -1
- package/dist/commands/memory/memory.mjs +7 -1
- package/dist/commands/memory/memory.mjs.map +1 -1
- package/dist/lib/helper-scripts.d.mts +1 -1
- package/dist/lib/helper-scripts.mjs +10 -18
- package/dist/lib/helper-scripts.mjs.map +1 -1
- package/dist/lib/host-config.d.mts +72 -0
- package/dist/lib/host-config.mjs +404 -0
- package/dist/lib/host-config.mjs.map +1 -0
- package/dist/lib/host-registry-client.d.mts +2 -2
- package/dist/lib/host-registry-client.mjs +0 -3
- package/dist/lib/host-registry-client.mjs.map +1 -1
- package/dist/lib/install-assets.d.mts +1 -0
- package/dist/lib/install-assets.mjs +4 -0
- package/dist/lib/install-assets.mjs.map +1 -1
- package/dist/lib/proc.d.mts +2 -0
- package/dist/lib/proc.mjs +12 -0
- package/dist/lib/proc.mjs.map +1 -1
- package/dist/lib/python-command.d.mts +2 -0
- package/dist/lib/python-command.mjs +52 -0
- package/dist/lib/python-command.mjs.map +1 -0
- package/dist/lib/python-helper.d.mts +2 -5
- package/dist/lib/python-helper.mjs +3 -52
- package/dist/lib/python-helper.mjs.map +1 -1
- package/dist/lib/runtime-payload.d.mts +23 -0
- package/dist/lib/runtime-payload.mjs +57 -0
- package/dist/lib/runtime-payload.mjs.map +1 -0
- package/dist/lib/types.d.mts +24 -13
- package/docs/architecture/storage-model.md +21 -5
- package/docs/architecture.md +37 -36
- package/docs/cli.md +55 -76
- package/docs/coding-rules.md +295 -0
- package/docs/container.md +10 -36
- package/docs/contributor-change-matrix.md +1 -1
- package/docs/for-ai/skills/okstra-code-review.md +0 -1
- package/docs/for-ai/skills/okstra-container-build.md +8 -41
- package/docs/for-ai/skills/okstra-inspect.md +4 -4
- package/docs/for-ai/skills/okstra-manager.md +2 -2
- package/docs/for-ai/skills/okstra-rollup.md +0 -1
- package/docs/for-ai/skills/okstra-run.md +3 -3
- package/docs/for-ai/skills/okstra-user-response.md +0 -1
- package/docs/performance-improvement-plan-v2.md +1 -1
- package/docs/project-structure-overview.md +62 -62
- package/docs/task-process/README.md +3 -3
- package/docs/task-process/common-flow.md +1 -1
- package/docs/task-process/error-analysis.md +3 -3
- package/docs/task-process/implementation-planning.md +3 -1
- package/docs/task-process/release-handoff.md +1 -1
- package/package.json +3 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/claude-worker.md +6 -11
- package/runtime/agents/workers/report-writer-worker.md +1 -1
- package/runtime/bin/lib/okstra/cli.sh +4 -0
- package/runtime/bin/lib/okstra/globals.sh +2 -0
- package/runtime/bin/lib/okstra/interactive.sh +26 -173
- package/runtime/bin/lib/okstra/project-resolver.sh +23 -61
- package/runtime/bin/lib/okstra/usage.sh +3 -3
- package/runtime/bin/okstra-compact-reminder.sh +1 -5
- package/runtime/bin/okstra-error-log.py +19 -2
- package/runtime/bin/okstra-import-check.py +26 -0
- package/runtime/bin/okstra-inject-report-index.py +5 -4
- package/runtime/bin/okstra-provider-exec.py +22 -17
- package/runtime/bin/okstra-render-final-report.py +16 -6
- package/runtime/bin/okstra-render-report-views.py +25 -18
- package/runtime/bin/okstra-report-translate.py +30 -18
- package/runtime/bin/okstra-spawn-followups.py +4 -0
- package/runtime/bin/okstra-token-usage.py +3 -0
- package/runtime/bin/okstra.sh +4 -2
- package/runtime/bin/okstra_bootstrap.py +58 -0
- package/runtime/prompts/coding-preflight/overview.md +1 -1
- package/runtime/prompts/duties/planning-worker.md +1 -1
- package/runtime/prompts/launch.template.md +35 -9
- package/runtime/prompts/lead/convergence.md +96 -87
- package/runtime/prompts/lead/okstra-lead-contract.md +63 -12
- package/runtime/prompts/lead/plan-body-verification.md +65 -46
- package/runtime/prompts/lead/report-writer.md +34 -4
- package/runtime/prompts/lead/team-contract.md +4 -1
- package/runtime/prompts/profiles/_clarification-recommendation.md +2 -1
- package/runtime/prompts/profiles/_coding-conventions-preflight.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +3 -3
- package/runtime/prompts/profiles/_coverage-critic.md +1 -1
- package/runtime/prompts/profiles/_implementation-deliverable.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +3 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +16 -2
- package/runtime/prompts/profiles/error-analysis.md +4 -3
- package/runtime/prompts/profiles/final-verification.md +2 -2
- package/runtime/prompts/profiles/implementation-planning.md +22 -17
- package/runtime/prompts/profiles/implementation.md +3 -2
- package/runtime/prompts/profiles/requirements-discovery.md +2 -1
- package/runtime/prompts/wizard/prompts.ko.json +29 -8
- package/runtime/python/okstra_ctl/__init__.py +6 -27
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -5
- package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +21 -2
- package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +3 -12
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +40 -22
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +14 -21
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +37 -20
- package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +86 -14
- package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +12 -12
- package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +4 -7
- package/runtime/python/okstra_ctl/agent/__init__.py +1 -0
- package/runtime/python/okstra_ctl/{agent_activity.py → agent/activity.py} +12 -1
- package/runtime/python/okstra_ctl/{agent_invocation.py → agent/invocation.py} +34 -5
- package/runtime/python/okstra_ctl/agent/prompt_cli/__init__.py +19 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/__main__.py +11 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +215 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/dynamic_verifier.py +155 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/emit.py +66 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/inputs.py +138 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +408 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/results.py +197 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +107 -0
- package/runtime/python/okstra_ctl/analysis_packet.py +47 -4
- package/runtime/python/okstra_ctl/approval_decisions.py +260 -8
- package/runtime/python/okstra_ctl/assignment_resolver.py +0 -12
- package/runtime/python/okstra_ctl/attempt_evidence.py +12 -24
- package/runtime/python/okstra_ctl/blocking_checks.py +251 -0
- package/runtime/python/okstra_ctl/brief_frontmatter.py +0 -7
- package/runtime/python/okstra_ctl/clarification_items/__init__.py +102 -0
- package/runtime/python/okstra_ctl/clarification_items/carry.py +224 -0
- package/runtime/python/okstra_ctl/clarification_items/dispositions.py +135 -0
- package/runtime/python/okstra_ctl/clarification_items/parsing.py +253 -0
- package/runtime/python/okstra_ctl/clarification_items/rows.py +115 -0
- package/runtime/python/okstra_ctl/clarification_items/scan.py +215 -0
- package/runtime/python/okstra_ctl/clarification_items/sidecars.py +211 -0
- package/runtime/python/okstra_ctl/cmux.py +38 -31
- package/runtime/python/okstra_ctl/code_review_target.py +163 -1
- package/runtime/python/okstra_ctl/conformance.py +23 -0
- package/runtime/python/okstra_ctl/container.py +38 -421
- package/runtime/python/okstra_ctl/context_cost.py +16 -2
- package/runtime/python/okstra_ctl/contract_graph_cli.py +7 -0
- package/runtime/python/okstra_ctl/convergence.py +101 -15
- package/runtime/python/okstra_ctl/convergence_critic_prompt.py +345 -0
- package/runtime/python/okstra_ctl/convergence_engine.py +382 -70
- package/runtime/python/okstra_ctl/convergence_store.py +5 -29
- package/runtime/python/okstra_ctl/design_prep.py +108 -12
- package/runtime/python/okstra_ctl/design_snapshot.py +11 -1
- package/runtime/python/okstra_ctl/design_surfaces.py +29 -2
- package/runtime/python/okstra_ctl/dispatch_core.py +102 -25
- package/runtime/python/okstra_ctl/dispatch_state.py +268 -39
- package/runtime/python/okstra_ctl/doctor_cli.py +48 -0
- package/runtime/python/okstra_ctl/domain/worker_exec.py +10 -5
- package/runtime/python/okstra_ctl/domain/worker_presentation.py +21 -1
- package/runtime/python/okstra_ctl/domain/worker_stream.py +52 -21
- package/runtime/python/okstra_ctl/domain/write_policy.py +219 -0
- package/runtime/python/okstra_ctl/entrypoints/hosts.py +9 -2
- package/runtime/python/okstra_ctl/error_log_core.py +1 -1
- package/runtime/python/okstra_ctl/error_report.py +14 -0
- package/runtime/python/okstra_ctl/error_zip.py +18 -2
- package/runtime/python/okstra_ctl/execution_identity.py +100 -7
- package/runtime/python/okstra_ctl/execution_manifest.py +67 -20
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +90 -8
- package/runtime/python/okstra_ctl/final_report_paths.py +17 -0
- package/runtime/python/okstra_ctl/final_report_schema.py +90 -16
- package/runtime/python/okstra_ctl/git_reconcile.py +22 -2
- package/runtime/python/okstra_ctl/handoff.py +24 -1
- package/runtime/python/okstra_ctl/ids.py +6 -16
- package/runtime/python/okstra_ctl/implementation_direction.py +142 -33
- package/runtime/python/okstra_ctl/implementation_options.py +25 -11
- package/runtime/python/okstra_ctl/implementation_outcome.py +5 -2
- package/runtime/python/okstra_ctl/improvement_lenses.py +0 -14
- package/runtime/python/okstra_ctl/incremental_carry.py +69 -8
- package/runtime/python/okstra_ctl/incremental_scope.py +173 -12
- package/runtime/python/okstra_ctl/index.py +2 -2
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +48 -8
- package/runtime/python/okstra_ctl/interactive_cli.py +223 -0
- package/runtime/python/okstra_ctl/json_boundary.py +10 -0
- package/runtime/python/okstra_ctl/listing.py +0 -91
- package/runtime/python/okstra_ctl/locks.py +5 -19
- package/runtime/python/okstra_ctl/log_report.py +14 -0
- package/runtime/python/okstra_ctl/manager_cli.py +22 -3
- package/runtime/python/okstra_ctl/manager_launch.py +4 -8
- package/runtime/python/okstra_ctl/material.py +2 -2
- package/runtime/python/okstra_ctl/migrate.py +23 -1
- package/runtime/python/okstra_ctl/model_cli.py +19 -5
- package/runtime/python/okstra_ctl/model_discovery.py +46 -47
- package/runtime/python/okstra_ctl/model_io/__init__.py +1 -0
- package/runtime/python/okstra_ctl/model_io/lines.py +163 -0
- package/runtime/python/okstra_ctl/model_io/references.py +370 -0
- package/runtime/python/okstra_ctl/model_io/renderers.py +498 -0
- package/runtime/python/okstra_ctl/model_io_cli.py +30 -945
- package/runtime/python/okstra_ctl/model_pool.py +10 -6
- package/runtime/python/okstra_ctl/models.py +8 -8
- package/runtime/python/okstra_ctl/mutation_recovery.py +5 -63
- package/runtime/python/okstra_ctl/next_phase.py +121 -69
- package/runtime/python/okstra_ctl/pane_reclaim.py +23 -0
- package/runtime/python/okstra_ctl/pane_title.py +11 -8
- package/runtime/python/okstra_ctl/path_hints.py +36 -11
- package/runtime/python/okstra_ctl/paths.py +76 -8
- package/runtime/python/okstra_ctl/plan_items.py +132 -16
- package/runtime/python/okstra_ctl/plan_items_cli.py +486 -36
- package/runtime/python/okstra_ctl/plan_run_root.py +1 -1
- package/runtime/python/okstra_ctl/plan_validate_cli.py +51 -0
- package/runtime/python/okstra_ctl/plan_verify_cli.py +80 -0
- package/runtime/python/okstra_ctl/prepare_error.py +20 -0
- package/runtime/python/okstra_ctl/prior_planning.py +157 -0
- package/runtime/python/okstra_ctl/profile_show.py +18 -1
- package/runtime/python/okstra_ctl/project_setup_cli.py +140 -0
- package/runtime/python/okstra_ctl/recap.py +22 -1
- package/runtime/python/okstra_ctl/reconcile.py +84 -0
- package/runtime/python/okstra_ctl/registry/host_registry.py +18 -1
- package/runtime/python/okstra_ctl/render.py +98 -32
- package/runtime/python/okstra_ctl/render_final_report.py +3 -7
- package/runtime/python/okstra_ctl/report_assembly.py +297 -7
- package/runtime/python/okstra_ctl/report_contract.py +30 -7
- package/runtime/python/okstra_ctl/report_finalize.py +206 -15
- package/runtime/python/okstra_ctl/report_html/common.py +2 -2
- package/runtime/python/okstra_ctl/report_html/render.py +8 -12
- package/runtime/python/okstra_ctl/report_language.py +8 -4
- package/runtime/python/okstra_ctl/report_narrative.py +90 -3
- package/runtime/python/okstra_ctl/report_projections.py +8 -2
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +258 -1
- package/runtime/python/okstra_ctl/report_translation.py +2 -35
- package/runtime/python/okstra_ctl/report_views.py +4 -22
- package/runtime/python/okstra_ctl/resolve_task_key.py +13 -0
- package/runtime/python/okstra_ctl/rollup.py +13 -0
- package/runtime/python/okstra_ctl/run.py +639 -138
- package/runtime/python/okstra_ctl/run_audit.py +13 -0
- package/runtime/python/okstra_ctl/run_index_row.py +0 -12
- package/runtime/python/okstra_ctl/seeding.py +21 -11
- package/runtime/python/okstra_ctl/sequence.py +1 -1
- package/runtime/python/okstra_ctl/session.py +64 -14
- package/runtime/python/okstra_ctl/set_work_status.py +18 -0
- package/runtime/python/okstra_ctl/stage_integrate.py +15 -1
- package/runtime/python/okstra_ctl/stage_ledger.py +1 -1
- package/runtime/python/okstra_ctl/stage_map.py +57 -11
- package/runtime/python/okstra_ctl/stage_map_cli.py +83 -0
- package/runtime/python/okstra_ctl/stage_map_view.py +65 -0
- package/runtime/python/okstra_ctl/stage_targets.py +3 -12
- package/runtime/python/okstra_ctl/task_list_cli.py +138 -0
- package/runtime/python/okstra_ctl/task_show_cli.py +66 -0
- package/runtime/python/okstra_ctl/task_target.py +4 -16
- package/runtime/python/okstra_ctl/team.py +49 -2
- package/runtime/python/okstra_ctl/time_report.py +17 -2
- package/runtime/python/okstra_ctl/usage_report.py +11 -0
- package/runtime/python/okstra_ctl/user_response.py +55 -218
- package/runtime/python/okstra_ctl/user_response_values.py +242 -0
- package/runtime/python/okstra_ctl/validation_contract.py +3 -0
- package/runtime/python/okstra_ctl/verification_target.py +68 -0
- package/runtime/python/okstra_ctl/wizard.py +457 -92
- package/runtime/python/okstra_ctl/worker_artifacts.py +75 -16
- package/runtime/python/okstra_ctl/worker_audit_check.py +22 -0
- package/runtime/python/okstra_ctl/worker_dispatch.py +21 -0
- package/runtime/python/okstra_ctl/worker_liveness.py +33 -0
- package/runtime/python/okstra_ctl/worker_prompt_body.py +15 -2
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +98 -7
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +24 -2
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +18 -3
- package/runtime/python/okstra_ctl/worker_request.py +2 -1
- package/runtime/python/okstra_ctl/worker_runner.py +16 -9
- package/runtime/python/okstra_ctl/worker_state.py +16 -1
- package/runtime/python/okstra_ctl/workflow.py +18 -1
- package/runtime/python/okstra_ctl/worktree/__init__.py +92 -0
- package/runtime/python/okstra_ctl/worktree/cleanliness.py +89 -0
- package/runtime/python/okstra_ctl/worktree/decisions.py +127 -0
- package/runtime/python/okstra_ctl/worktree/git_ops.py +165 -0
- package/runtime/python/okstra_ctl/worktree/linking.py +249 -0
- package/runtime/python/okstra_ctl/worktree/naming.py +91 -0
- package/runtime/python/okstra_ctl/worktree/provision.py +385 -0
- package/runtime/python/okstra_ctl/worktree/sync_config.py +181 -0
- package/runtime/python/okstra_ctl/worktree_cli.py +75 -0
- package/runtime/python/okstra_ctl/worktree_lookup_cli.py +39 -0
- package/runtime/python/okstra_ctl/worktree_registry.py +7 -0
- package/runtime/python/okstra_ctl/worktree_status_cli.py +53 -0
- package/runtime/python/okstra_ctl/write_policy.py +90 -213
- package/runtime/python/okstra_project/__init__.py +0 -4
- package/runtime/python/okstra_project/dirs.py +2 -2
- package/runtime/python/okstra_project/phase_pointer.py +84 -0
- package/runtime/python/okstra_project/slug.py +24 -0
- package/runtime/python/okstra_project/state.py +22 -230
- package/runtime/python/okstra_token_usage/claude.py +9 -1
- package/runtime/python/okstra_token_usage/cli.py +3 -1
- package/runtime/python/okstra_token_usage/collect.py +71 -10
- package/runtime/python/okstra_token_usage/cursor.py +2 -0
- package/runtime/python/okstra_token_usage/grok.py +1 -5
- package/runtime/python/okstra_token_usage/paths.py +26 -0
- package/runtime/python/okstra_token_usage/pricing.py +19 -7
- package/runtime/schemas/convergence-critic-results-v1.0.schema.json +5 -0
- package/runtime/schemas/execution-manifest-v2.schema.json +10 -10
- package/runtime/schemas/final-report-v2.0.schema.json +9 -26
- package/runtime/schemas/final-report-v3.0.schema.json +173 -41
- package/runtime/schemas/report-narrative-v3.0.schema.json +3 -2
- package/runtime/skills/okstra-brief-gen/SKILL.md +35 -2
- package/runtime/skills/okstra-container-build/SKILL.md +16 -47
- package/runtime/skills/okstra-inspect/facets/history.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +7 -6
- package/runtime/skills/okstra-pr-gen/SKILL.md +1 -1
- package/runtime/skills/okstra-run/SKILL.md +7 -5
- package/runtime/templates/report-writer-prompt-preamble.md +1 -1
- package/runtime/templates/reports/brief.template.md +6 -2
- package/runtime/templates/reports/error-analysis-input.template.md +2 -0
- package/runtime/templates/reports/final-verification-input.template.md +2 -0
- package/runtime/templates/reports/implementation-input.template.md +7 -1
- package/runtime/templates/reports/implementation-planning-input.template.md +4 -0
- package/runtime/templates/reports/quick-input.template.md +2 -0
- package/runtime/templates/reports/release-handoff-input.template.md +6 -1
- package/runtime/templates/reports/report.js +20 -3
- package/runtime/templates/reports/schedule.template.md +2 -0
- package/runtime/templates/reports/settings.template.json +0 -10
- package/runtime/templates/reports/task-brief.template.md +3 -0
- package/runtime/templates/reports/user-response.template.md +7 -3
- package/runtime/validators/checks/fixtures-01.py +57 -0
- package/runtime/validators/checks/fixtures-02.py +565 -0
- package/runtime/validators/checks/runners-01.py +108 -0
- package/runtime/validators/checks/validate-assets-01.py +60 -0
- package/runtime/validators/checks/validate-prompt-metadata-01.py +261 -0
- package/runtime/validators/checks/validate-tasks-01.py +46 -0
- package/runtime/validators/checks/validate-tasks-02.py +85 -0
- package/runtime/validators/checks/validate-tasks-03.py +61 -0
- package/runtime/validators/checks/validate-tasks-04.py +118 -0
- package/runtime/validators/forbidden_actions.py +73 -3
- package/runtime/validators/lib/common.sh +5 -0
- package/runtime/validators/lib/fixtures.sh +7 -591
- package/runtime/validators/lib/paths.sh +13 -0
- package/runtime/validators/lib/runners.sh +6 -104
- package/runtime/validators/lib/summary.sh +1 -1
- package/runtime/validators/lib/validate-assets.sh +6 -56
- package/runtime/validators/lib/validate-prompt-metadata.sh +6 -257
- package/runtime/validators/lib/validate-tasks.sh +9 -294
- package/runtime/validators/validate-implementation-plan-stages.py +4 -4
- package/runtime/validators/validate-run.py +1369 -2654
- package/runtime/validators/validate-workflow.sh +56 -16
- package/runtime/validators/validate_improvement_report.py +2 -1
- package/runtime/validators/validate_session_conformance.py +295 -49
- package/dist/commands/execute/agent-prompt.d.mts +0 -1
- package/dist/commands/execute/agent-prompt.mjs +0 -24
- package/dist/commands/execute/agent-prompt.mjs.map +0 -1
- package/dist/commands/execute/codex-dispatch.d.mts +0 -3
- package/dist/commands/execute/codex-dispatch.mjs +0 -6
- package/dist/commands/execute/codex-dispatch.mjs.map +0 -1
- package/dist/commands/execute/codex-run.d.mts +0 -3
- package/dist/commands/execute/codex-run.mjs +0 -62
- package/dist/commands/execute/codex-run.mjs.map +0 -1
- package/dist/commands/execute/convergence.d.mts +0 -1
- package/dist/commands/execute/convergence.mjs +0 -38
- package/dist/commands/execute/convergence.mjs.map +0 -1
- package/dist/commands/execute/error-log.d.mts +0 -1
- package/dist/commands/execute/error-log.mjs +0 -18
- package/dist/commands/execute/error-log.mjs.map +0 -1
- package/dist/commands/execute/git-reconcile.d.mts +0 -1
- package/dist/commands/execute/git-reconcile.mjs +0 -30
- package/dist/commands/execute/git-reconcile.mjs.map +0 -1
- package/dist/commands/execute/handoff.d.mts +0 -1
- package/dist/commands/execute/handoff.mjs +0 -31
- package/dist/commands/execute/handoff.mjs.map +0 -1
- package/dist/commands/execute/incremental-carry.d.mts +0 -1
- package/dist/commands/execute/incremental-carry.mjs +0 -20
- package/dist/commands/execute/incremental-carry.mjs.map +0 -1
- package/dist/commands/execute/incremental-scope.d.mts +0 -1
- package/dist/commands/execute/incremental-scope.mjs +0 -29
- package/dist/commands/execute/incremental-scope.mjs.map +0 -1
- package/dist/commands/execute/integrate-stages.d.mts +0 -1
- package/dist/commands/execute/integrate-stages.mjs +0 -24
- package/dist/commands/execute/integrate-stages.mjs.map +0 -1
- package/dist/commands/execute/pane-title.d.mts +0 -1
- package/dist/commands/execute/pane-title.mjs +0 -20
- package/dist/commands/execute/pane-title.mjs.map +0 -1
- package/dist/commands/execute/plan-items.d.mts +0 -1
- package/dist/commands/execute/plan-items.mjs +0 -9
- package/dist/commands/execute/plan-items.mjs.map +0 -1
- package/dist/commands/execute/plan-validate.d.mts +0 -1
- package/dist/commands/execute/plan-validate.mjs +0 -68
- package/dist/commands/execute/plan-validate.mjs.map +0 -1
- package/dist/commands/execute/plan-verify.d.mts +0 -1
- package/dist/commands/execute/plan-verify.mjs +0 -43
- package/dist/commands/execute/plan-verify.mjs.map +0 -1
- package/dist/commands/execute/spawn-followups.d.mts +0 -1
- package/dist/commands/execute/spawn-followups.mjs +0 -22
- package/dist/commands/execute/spawn-followups.mjs.map +0 -1
- package/dist/commands/execute/team.d.mts +0 -3
- package/dist/commands/execute/team.mjs +0 -66
- package/dist/commands/execute/team.mjs.map +0 -1
- package/dist/commands/execute/token-usage.d.mts +0 -1
- package/dist/commands/execute/token-usage.mjs +0 -19
- package/dist/commands/execute/token-usage.mjs.map +0 -1
- package/dist/commands/execute/worker-audit-check.d.mts +0 -1
- package/dist/commands/execute/worker-audit-check.mjs +0 -34
- package/dist/commands/execute/worker-audit-check.mjs.map +0 -1
- package/dist/commands/execute/worker-dispatch.d.mts +0 -7
- package/dist/commands/execute/worker-dispatch.mjs +0 -64
- package/dist/commands/execute/worker-dispatch.mjs.map +0 -1
- package/dist/commands/execute/worker-state.d.mts +0 -1
- package/dist/commands/execute/worker-state.mjs +0 -28
- package/dist/commands/execute/worker-state.mjs.map +0 -1
- package/dist/commands/execute/worktree-lookup.d.mts +0 -1
- package/dist/commands/execute/worktree-lookup.mjs +0 -92
- package/dist/commands/execute/worktree-lookup.mjs.map +0 -1
- package/dist/commands/execute/worktree-status.d.mts +0 -1
- package/dist/commands/execute/worktree-status.mjs +0 -121
- package/dist/commands/execute/worktree-status.mjs.map +0 -1
- package/dist/commands/inspect/code-review.d.mts +0 -1
- package/dist/commands/inspect/code-review.mjs +0 -32
- package/dist/commands/inspect/code-review.mjs.map +0 -1
- package/dist/commands/inspect/container.d.mts +0 -1
- package/dist/commands/inspect/container.mjs +0 -25
- package/dist/commands/inspect/container.mjs.map +0 -1
- package/dist/commands/inspect/context-cost.d.mts +0 -1
- package/dist/commands/inspect/context-cost.mjs +0 -25
- package/dist/commands/inspect/context-cost.mjs.map +0 -1
- package/dist/commands/inspect/design-prep.d.mts +0 -1
- package/dist/commands/inspect/design-prep.mjs +0 -22
- package/dist/commands/inspect/design-prep.mjs.map +0 -1
- package/dist/commands/inspect/error-report.d.mts +0 -1
- package/dist/commands/inspect/error-report.mjs +0 -25
- package/dist/commands/inspect/error-report.mjs.map +0 -1
- package/dist/commands/inspect/error-zip.d.mts +0 -1
- package/dist/commands/inspect/error-zip.mjs +0 -24
- package/dist/commands/inspect/error-zip.mjs.map +0 -1
- package/dist/commands/inspect/log-report.d.mts +0 -1
- package/dist/commands/inspect/log-report.mjs +0 -26
- package/dist/commands/inspect/log-report.mjs.map +0 -1
- package/dist/commands/inspect/model-io.d.mts +0 -1
- package/dist/commands/inspect/model-io.mjs +0 -25
- package/dist/commands/inspect/model-io.mjs.map +0 -1
- package/dist/commands/inspect/profile-show.d.mts +0 -1
- package/dist/commands/inspect/profile-show.mjs +0 -28
- package/dist/commands/inspect/profile-show.mjs.map +0 -1
- package/dist/commands/inspect/recap.d.mts +0 -1
- package/dist/commands/inspect/recap.mjs +0 -30
- package/dist/commands/inspect/recap.mjs.map +0 -1
- package/dist/commands/inspect/resolve-task-key.d.mts +0 -1
- package/dist/commands/inspect/resolve-task-key.mjs +0 -24
- package/dist/commands/inspect/resolve-task-key.mjs.map +0 -1
- package/dist/commands/inspect/rollup.d.mts +0 -1
- package/dist/commands/inspect/rollup.mjs +0 -25
- package/dist/commands/inspect/rollup.mjs.map +0 -1
- package/dist/commands/inspect/run-audit.d.mts +0 -1
- package/dist/commands/inspect/run-audit.mjs +0 -25
- package/dist/commands/inspect/run-audit.mjs.map +0 -1
- package/dist/commands/inspect/set-work-status.d.mts +0 -1
- package/dist/commands/inspect/set-work-status.mjs +0 -29
- package/dist/commands/inspect/set-work-status.mjs.map +0 -1
- package/dist/commands/inspect/stage-map.d.mts +0 -1
- package/dist/commands/inspect/stage-map.mjs +0 -131
- package/dist/commands/inspect/stage-map.mjs.map +0 -1
- package/dist/commands/inspect/task-list.d.mts +0 -1
- package/dist/commands/inspect/task-list.mjs +0 -149
- package/dist/commands/inspect/task-list.mjs.map +0 -1
- package/dist/commands/inspect/task-show.d.mts +0 -1
- package/dist/commands/inspect/task-show.mjs +0 -108
- package/dist/commands/inspect/task-show.mjs.map +0 -1
- package/dist/commands/inspect/time-report.d.mts +0 -1
- package/dist/commands/inspect/time-report.mjs +0 -24
- package/dist/commands/inspect/time-report.mjs.map +0 -1
- package/dist/commands/inspect/usage-report.d.mts +0 -1
- package/dist/commands/inspect/usage-report.mjs +0 -23
- package/dist/commands/inspect/usage-report.mjs.map +0 -1
- package/dist/commands/inspect/user-response.d.mts +0 -1
- package/dist/commands/inspect/user-response.mjs +0 -35
- package/dist/commands/inspect/user-response.mjs.map +0 -1
- package/dist/commands/inspect/worker-liveness.d.mts +0 -1
- package/dist/commands/inspect/worker-liveness.mjs +0 -45
- package/dist/commands/inspect/worker-liveness.mjs.map +0 -1
- package/dist/commands/lifecycle/contract-check.d.mts +0 -1
- package/dist/commands/lifecycle/contract-check.mjs +0 -18
- package/dist/commands/lifecycle/contract-check.mjs.map +0 -1
- package/dist/commands/lifecycle/migrate.d.mts +0 -1
- package/dist/commands/lifecycle/migrate.mjs +0 -30
- package/dist/commands/lifecycle/migrate.mjs.map +0 -1
- package/dist/commands/lifecycle/model.d.mts +0 -1
- package/dist/commands/lifecycle/model.mjs +0 -22
- package/dist/commands/lifecycle/model.mjs.map +0 -1
- package/dist/commands/manager.d.mts +0 -3
- package/dist/commands/manager.mjs +0 -50
- package/dist/commands/manager.mjs.map +0 -1
- package/dist/commands/report/agent-activity.d.mts +0 -1
- package/dist/commands/report/agent-activity.mjs +0 -20
- package/dist/commands/report/agent-activity.mjs.map +0 -1
- package/dist/commands/report/approval-decision.d.mts +0 -1
- package/dist/commands/report/approval-decision.mjs +0 -21
- package/dist/commands/report/approval-decision.mjs.map +0 -1
- package/dist/commands/report/design-snapshot.d.mts +0 -1
- package/dist/commands/report/design-snapshot.mjs +0 -19
- package/dist/commands/report/design-snapshot.mjs.map +0 -1
- package/dist/commands/report/finalize.d.mts +0 -4
- package/dist/commands/report/finalize.mjs +0 -64
- package/dist/commands/report/finalize.mjs.map +0 -1
- package/dist/commands/report/inject-report-index.d.mts +0 -1
- package/dist/commands/report/inject-report-index.mjs +0 -21
- package/dist/commands/report/inject-report-index.mjs.map +0 -1
- package/dist/commands/report/render-final-report.d.mts +0 -1
- package/dist/commands/report/render-final-report.mjs +0 -23
- package/dist/commands/report/render-final-report.mjs.map +0 -1
- package/dist/commands/report/render-views.d.mts +0 -1
- package/dist/commands/report/render-views.mjs +0 -27
- package/dist/commands/report/render-views.mjs.map +0 -1
- package/dist/commands/report/translate.d.mts +0 -1
- package/dist/commands/report/translate.mjs +0 -33
- package/dist/commands/report/translate.mjs.map +0 -1
- package/runtime/bin/lib/okstra/tmux-pane.sh +0 -40
- package/runtime/bin/lib/okstra-ctl/cmd-batch.sh +0 -59
- package/runtime/bin/lib/okstra-ctl/cmd-list.sh +0 -35
- package/runtime/bin/lib/okstra-ctl/cmd-open.sh +0 -36
- package/runtime/bin/lib/okstra-ctl/cmd-projects.sh +0 -26
- package/runtime/bin/lib/okstra-ctl/cmd-reconcile.sh +0 -29
- package/runtime/bin/lib/okstra-ctl/cmd-reindex.sh +0 -38
- package/runtime/bin/lib/okstra-ctl/cmd-rerun.sh +0 -345
- package/runtime/bin/lib/okstra-ctl/cmd-show.sh +0 -27
- package/runtime/bin/lib/okstra-ctl/cmd-tail.sh +0 -92
- package/runtime/bin/lib/okstra-ctl/main.sh +0 -41
- package/runtime/bin/lib/okstra-ctl/prepare.sh +0 -31
- package/runtime/bin/lib/okstra-ctl/usage.sh +0 -23
- package/runtime/bin/okstra-central.sh +0 -152
- package/runtime/bin/okstra-incremental-carry.py +0 -10
- package/runtime/bin/okstra-incremental-scope.py +0 -10
- package/runtime/bin/okstra-team-reconcile.sh +0 -36
- package/runtime/python/okstra_ctl/agent_prompt_cli.py +0 -1156
- package/runtime/python/okstra_ctl/batch.py +0 -60
- package/runtime/python/okstra_ctl/clarification_items.py +0 -1050
- package/runtime/python/okstra_ctl/container_registry.py +0 -72
- package/runtime/python/okstra_ctl/improvement_assignment.py +0 -61
- package/runtime/python/okstra_ctl/resolver.py +0 -54
- package/runtime/python/okstra_ctl/team_reconcile.py +0 -275
- package/runtime/python/okstra_ctl/tmux.py +0 -134
- package/runtime/python/okstra_ctl/worktree.py +0 -1099
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# shellcheck shell=bash
|
|
2
2
|
|
|
3
|
+
# 이 lib 은 단독으로 source 될 수 있다(계약 테스트가 그렇게 부른다). checks
|
|
4
|
+
# 경로 계산은 common.sh 한 곳에만 두고, 없으면 여기서 채운다.
|
|
5
|
+
# shellcheck source=common.sh
|
|
6
|
+
[ -n "${OKSTRA_VALIDATOR_CHECKS:-}" ] || . "$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
|
|
7
|
+
|
|
3
8
|
write_validation_brief() {
|
|
4
9
|
local brief_path="$1"
|
|
5
10
|
local brief_title="$2"
|
|
@@ -96,59 +101,7 @@ write_worker_prompt_history_fixture() {
|
|
|
96
101
|
|
|
97
102
|
expected_task_manifest_relative_path="$(task_manifest_relative_path "$task_group" "$task_id")"
|
|
98
103
|
|
|
99
|
-
python3 - "$PROJECT_ROOT" "$expected_task_manifest_relative_path" "$worker_id"
|
|
100
|
-
from pathlib import Path
|
|
101
|
-
import json
|
|
102
|
-
import sys
|
|
103
|
-
|
|
104
|
-
project_root = Path(sys.argv[1])
|
|
105
|
-
task_manifest_path = project_root / sys.argv[2]
|
|
106
|
-
target_worker_id = sys.argv[3]
|
|
107
|
-
task_manifest = json.loads(task_manifest_path.read_text())
|
|
108
|
-
team_state_path = project_root / task_manifest["teamStatePath"]
|
|
109
|
-
team_state = json.loads(team_state_path.read_text())
|
|
110
|
-
|
|
111
|
-
target_worker = None
|
|
112
|
-
for worker in team_state.get("workers", []):
|
|
113
|
-
if isinstance(worker, dict) and worker.get("workerId") == target_worker_id:
|
|
114
|
-
target_worker = worker
|
|
115
|
-
break
|
|
116
|
-
|
|
117
|
-
if target_worker is None:
|
|
118
|
-
raise SystemExit(f"worker not found in team-state: {target_worker_id}")
|
|
119
|
-
|
|
120
|
-
prompt_relative = str(target_worker.get("promptPath", "")).strip()
|
|
121
|
-
if not prompt_relative:
|
|
122
|
-
raise SystemExit(f"worker promptPath is missing: {target_worker_id}")
|
|
123
|
-
|
|
124
|
-
prompt_path = project_root / prompt_relative
|
|
125
|
-
prompt_path.parent.mkdir(parents=True, exist_ok=True)
|
|
126
|
-
artifacts = task_manifest.get("artifacts", {})
|
|
127
|
-
analysis_packet_path = (
|
|
128
|
-
str(artifacts.get("analysisPacketPath", "")).strip()
|
|
129
|
-
if isinstance(artifacts, dict)
|
|
130
|
-
else ""
|
|
131
|
-
)
|
|
132
|
-
prompt_path.write_text(
|
|
133
|
-
"\n".join(
|
|
134
|
-
[
|
|
135
|
-
"**Worker Error Contract Path:** /okstra/templates/worker-error-contract.md",
|
|
136
|
-
f"**Errors log path:** {project_root}/run/logs/errors.jsonl",
|
|
137
|
-
f"**Errors sidecar path:** {project_root}/run/worker-results/"
|
|
138
|
-
f"{target_worker_id}-errors.json",
|
|
139
|
-
f"Assigned worker prompt history path: {prompt_relative}",
|
|
140
|
-
"**Prompt Delivery Mode:** eager-include",
|
|
141
|
-
f"**Model:** Fixture worker, {target_worker.get('modelExecutionValue', '')}",
|
|
142
|
-
f"- Primary analysis packet: `{analysis_packet_path}`",
|
|
143
|
-
"",
|
|
144
|
-
"# Initial Analysis Prompt",
|
|
145
|
-
f"Task Key: {task_manifest.get('taskKey', '')}",
|
|
146
|
-
"Validation fixture prompt body.",
|
|
147
|
-
]
|
|
148
|
-
)
|
|
149
|
-
+ "\n"
|
|
150
|
-
)
|
|
151
|
-
PY
|
|
104
|
+
python3 "$OKSTRA_VALIDATOR_CHECKS/fixtures-01.py" "$PROJECT_ROOT" "$expected_task_manifest_relative_path" "$worker_id"
|
|
152
105
|
}
|
|
153
106
|
|
|
154
107
|
prepare_run_validator_fixture() {
|
|
@@ -159,542 +112,5 @@ prepare_run_validator_fixture() {
|
|
|
159
112
|
|
|
160
113
|
expected_task_manifest_relative_path="$(task_manifest_relative_path "$task_group" "$task_id")"
|
|
161
114
|
|
|
162
|
-
python3 - "$PROJECT_ROOT" "$expected_task_manifest_relative_path" "$omitted_worker_id"
|
|
163
|
-
from datetime import datetime, timezone
|
|
164
|
-
from pathlib import Path
|
|
165
|
-
import json
|
|
166
|
-
import sys
|
|
167
|
-
|
|
168
|
-
project_root = Path(sys.argv[1])
|
|
169
|
-
task_manifest_path = project_root / sys.argv[2]
|
|
170
|
-
omitted_worker_id = sys.argv[3]
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
def load_json(path: Path) -> dict:
|
|
174
|
-
return json.loads(path.read_text())
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def write_json(path: Path, payload: dict) -> None:
|
|
178
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
179
|
-
path.write_text(json.dumps(payload, indent=2, ensure_ascii=False) + "\n")
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
task_manifest = load_json(task_manifest_path)
|
|
183
|
-
timeline_path = project_root / task_manifest["historyTimelinePath"]
|
|
184
|
-
timeline = load_json(timeline_path)
|
|
185
|
-
runs = timeline.get("runs", [])
|
|
186
|
-
latest_run = None
|
|
187
|
-
if isinstance(runs, list):
|
|
188
|
-
for item in reversed(runs):
|
|
189
|
-
if isinstance(item, dict):
|
|
190
|
-
latest_run = item
|
|
191
|
-
break
|
|
192
|
-
|
|
193
|
-
if latest_run is None:
|
|
194
|
-
raise SystemExit("timeline does not contain a latest run entry")
|
|
195
|
-
|
|
196
|
-
run_manifest_path = project_root / latest_run["runManifestPath"]
|
|
197
|
-
run_manifest = load_json(run_manifest_path)
|
|
198
|
-
team_state_path = project_root / run_manifest["teamStatePath"]
|
|
199
|
-
team_state = load_json(team_state_path)
|
|
200
|
-
report_path = project_root / run_manifest["expectedReportRecordPath"]
|
|
201
|
-
final_status_path = project_root / run_manifest["expectedStatusPath"]
|
|
202
|
-
|
|
203
|
-
status_by_worker_id = {
|
|
204
|
-
"claude": "completed",
|
|
205
|
-
"codex": "timeout",
|
|
206
|
-
"antigravity": "error",
|
|
207
|
-
"report-writer": "completed",
|
|
208
|
-
}
|
|
209
|
-
reason_by_worker_id = {
|
|
210
|
-
"claude": "",
|
|
211
|
-
"codex": "Validation fixture timeout",
|
|
212
|
-
"antigravity": "Validation fixture execution error",
|
|
213
|
-
"report-writer": "",
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
for worker in team_state.get("workers", []):
|
|
217
|
-
if not isinstance(worker, dict):
|
|
218
|
-
continue
|
|
219
|
-
worker_id = str(worker.get("workerId", "")).strip()
|
|
220
|
-
if not worker_id:
|
|
221
|
-
continue
|
|
222
|
-
worker["status"] = status_by_worker_id.get(worker_id, "not-run")
|
|
223
|
-
worker["reason"] = reason_by_worker_id.get(worker_id, "Validation fixture not used")
|
|
224
|
-
|
|
225
|
-
prompt_relative = str(worker.get("promptPath", "")).strip()
|
|
226
|
-
if prompt_relative:
|
|
227
|
-
prompt_path = project_root / prompt_relative
|
|
228
|
-
prompt_path.parent.mkdir(parents=True, exist_ok=True)
|
|
229
|
-
prompt_lines = [
|
|
230
|
-
"**Worker Error Contract Path:** /okstra/templates/worker-error-contract.md",
|
|
231
|
-
f"**Errors log path:** {project_root}/run/logs/errors.jsonl",
|
|
232
|
-
f"**Errors sidecar path:** {project_root}/run/worker-results/"
|
|
233
|
-
f"{worker_id}-errors.json",
|
|
234
|
-
f"Assigned worker prompt history path: {prompt_relative}",
|
|
235
|
-
"**Prompt Delivery Mode:** eager-include",
|
|
236
|
-
f"**Model:** Fixture worker, {worker.get('modelExecutionValue', '')}",
|
|
237
|
-
]
|
|
238
|
-
if worker_id != "report-writer":
|
|
239
|
-
prompt_lines.append(
|
|
240
|
-
f"- Primary analysis packet: `{run_manifest.get('analysisPacketPath', '')}`"
|
|
241
|
-
)
|
|
242
|
-
prompt_lines.extend([
|
|
243
|
-
"",
|
|
244
|
-
"# Initial Analysis Prompt",
|
|
245
|
-
f"Task Key: {task_manifest.get('taskKey', '')}",
|
|
246
|
-
"Validation fixture prompt body.",
|
|
247
|
-
])
|
|
248
|
-
else:
|
|
249
|
-
prompt_lines.extend(["", "# Report Writer Prompt"])
|
|
250
|
-
prompt_path.write_text(
|
|
251
|
-
"\n".join(prompt_lines) + "\n"
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
result_relative = str(worker.get("resultPath", "")).strip()
|
|
255
|
-
if worker["status"] == "completed" and result_relative:
|
|
256
|
-
result_path = project_root / result_relative
|
|
257
|
-
result_path.parent.mkdir(parents=True, exist_ok=True)
|
|
258
|
-
result_path.write_text(
|
|
259
|
-
"\n".join(
|
|
260
|
-
[
|
|
261
|
-
"# Findings",
|
|
262
|
-
"- Validation fixture finding.",
|
|
263
|
-
"",
|
|
264
|
-
"# Missing Information or Assumptions",
|
|
265
|
-
"- None.",
|
|
266
|
-
"",
|
|
267
|
-
"# Safe or Reasonable Areas",
|
|
268
|
-
"- Fixture output format is valid.",
|
|
269
|
-
"",
|
|
270
|
-
"# Uncertain Points",
|
|
271
|
-
"- None.",
|
|
272
|
-
"",
|
|
273
|
-
"# Recommended Next Actions",
|
|
274
|
-
"- Continue validator coverage.",
|
|
275
|
-
]
|
|
276
|
-
)
|
|
277
|
-
+ "\n"
|
|
278
|
-
)
|
|
279
|
-
# Mirror the audit sidecar contract — every completed worker-results
|
|
280
|
-
# file ships alongside `<worker>-audit-<task-type>-<seq>.md` carrying
|
|
281
|
-
# the Reading Confirmation block. Derive the sidecar path by
|
|
282
|
-
# inserting `-audit` after the worker-role segment of the
|
|
283
|
-
# result-file stem.
|
|
284
|
-
result_stem = result_path.stem # e.g. claude-worker-error-analysis-001
|
|
285
|
-
audit_stem = result_stem.replace("-worker-", "-worker-audit-", 1)
|
|
286
|
-
audit_path = result_path.with_name(f"{audit_stem}{result_path.suffix}")
|
|
287
|
-
audit_lines = [
|
|
288
|
-
f"# {worker.get('role', worker_id)} Audit",
|
|
289
|
-
"",
|
|
290
|
-
"- Read task-brief.md end-to-end (validation fixture).",
|
|
291
|
-
]
|
|
292
|
-
if worker_id == "claude":
|
|
293
|
-
# Heartbeat 계약 (agents/workers/claude-worker.md "Heartbeat") —
|
|
294
|
-
# validate_session_conformance 가 claude-worker audit 사이드카의
|
|
295
|
-
# `- PROGRESS:` cadence 를 검사하므로 fixture 도 계약을 준수한다.
|
|
296
|
-
hb_ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
297
|
-
audit_lines += [
|
|
298
|
-
"",
|
|
299
|
-
f"- PROGRESS: started {hb_ts}",
|
|
300
|
-
f"- PROGRESS: read-task-brief.md {hb_ts}",
|
|
301
|
-
f"- PROGRESS: analysis-start {hb_ts}",
|
|
302
|
-
f"- PROGRESS: findings-draft-complete {hb_ts}",
|
|
303
|
-
f"- PROGRESS: write-result-start {hb_ts}",
|
|
304
|
-
]
|
|
305
|
-
audit_path.write_text("\n".join(audit_lines) + "\n")
|
|
306
|
-
|
|
307
|
-
lead = team_state.get("lead")
|
|
308
|
-
if isinstance(lead, dict):
|
|
309
|
-
lead["status"] = "completed"
|
|
310
|
-
# render-only fixture 에는 실 Claude 세션이 없어 sessionId 가 비어 있을 수
|
|
311
|
-
# 있다 — session-conformance fixture jsonl 의 파일명과 맞춘 고정 id 를 부여.
|
|
312
|
-
if not str(lead.get("sessionId") or "").strip():
|
|
313
|
-
lead["sessionId"] = "fixture-lead-session-0001"
|
|
314
|
-
team_state["workflowState"] = "worker-results-collected"
|
|
315
|
-
|
|
316
|
-
# validate-run.py requires team-state.teamCreate.status == "implicit" once any
|
|
317
|
-
# worker has been dispatched (CC v2.1.178 removed TeamCreate; every session has
|
|
318
|
-
# an implicit team). Mirror that here so the fixture is a valid post-Phase-3 state.
|
|
319
|
-
team_state["teamCreate"] = {
|
|
320
|
-
"attempted": False,
|
|
321
|
-
"status": "implicit",
|
|
322
|
-
"splitPane": False,
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
# Phase 7 token-usage collection is normally produced by okstra-token-usage.py.
|
|
326
|
-
# The validator (`team-state.usageSummary is empty`) treats absence as a contract
|
|
327
|
-
# violation, so the fixture must mirror that step with a synthetic-but-valid object.
|
|
328
|
-
team_state["usageSummary"] = {
|
|
329
|
-
"leadTotalTokens": 0,
|
|
330
|
-
"workerTotalTokens": 0,
|
|
331
|
-
"grandTotalTokens": 0,
|
|
332
|
-
"leadBillableEquivalentTokens": 0,
|
|
333
|
-
"workerBillableEquivalentTokens": 0,
|
|
334
|
-
"grandBillableEquivalentTokens": 0,
|
|
335
|
-
"estimatedCostUsd": {
|
|
336
|
-
"lead": 0.0,
|
|
337
|
-
"claudeWorkers": 0.0,
|
|
338
|
-
"cliWorkers": 0.0,
|
|
339
|
-
"grandTotal": 0.0,
|
|
340
|
-
},
|
|
341
|
-
"collectedAt": "1970-01-01T00:00:00Z",
|
|
342
|
-
"teamName": team_state.get("teamName", "validation-fixture"),
|
|
343
|
-
"sessionsFound": 0,
|
|
344
|
-
"definitions": {
|
|
345
|
-
"totalTokens": "Validation fixture placeholder.",
|
|
346
|
-
"billableEquivalentTokens": "Validation fixture placeholder.",
|
|
347
|
-
"estimatedCostUsd": "Validation fixture placeholder.",
|
|
348
|
-
},
|
|
349
|
-
"intake": {
|
|
350
|
-
"totalTokens": 0,
|
|
351
|
-
"billableEquivalentTokens": 0,
|
|
352
|
-
"estimatedCostUsd": 0,
|
|
353
|
-
},
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
required_status_entries = run_manifest.get("teamContract", {}).get(
|
|
357
|
-
"requiredAgentStatusEntries", []
|
|
358
|
-
)
|
|
359
|
-
if not isinstance(required_status_entries, list):
|
|
360
|
-
required_status_entries = []
|
|
361
|
-
|
|
362
|
-
report_lines = [
|
|
363
|
-
"# Validation Fixture Report",
|
|
364
|
-
"",
|
|
365
|
-
# Top-of-report Index — the renderer injects this on real runs; the
|
|
366
|
-
# hand-crafted fixture mirrors it so validate_report's index/anchor
|
|
367
|
-
# contract (introduced with the clickable-ID pass) is satisfied.
|
|
368
|
-
'## Index <a id="report-index"></a>',
|
|
369
|
-
"",
|
|
370
|
-
"### Sections",
|
|
371
|
-
"",
|
|
372
|
-
"- [Verdict Card](#verdict-card)",
|
|
373
|
-
"",
|
|
374
|
-
"## Verdict Card",
|
|
375
|
-
"",
|
|
376
|
-
"| 항목 | 값 |",
|
|
377
|
-
"|------|----|",
|
|
378
|
-
"| Final Conclusion | validation fixture |",
|
|
379
|
-
"| Verdict Token | `accepted` |",
|
|
380
|
-
"| Direction | `continue-investigation` |",
|
|
381
|
-
"| Approval Required? | `no` |",
|
|
382
|
-
"| Next Step | fixture |",
|
|
383
|
-
"",
|
|
384
|
-
"## Agent Execution Status",
|
|
385
|
-
]
|
|
386
|
-
for label in required_status_entries:
|
|
387
|
-
if isinstance(label, str) and label.strip():
|
|
388
|
-
report_lines.append(f"- {label}: fixture status recorded")
|
|
389
|
-
report_lines.extend(
|
|
390
|
-
[
|
|
391
|
-
"",
|
|
392
|
-
"## Token Usage Summary",
|
|
393
|
-
"",
|
|
394
|
-
"| 항목 | 처리 토큰 | 환산 토큰 | 비용 (USD) |",
|
|
395
|
-
"|------|-----------|-----------|------------|",
|
|
396
|
-
"| Lead | `1` | `1` | `$0.01` |",
|
|
397
|
-
"| Worker 합계 | `1` | `1` | `$0.01` |",
|
|
398
|
-
"| **전체 합계** | **`2`** | **`2`** | **`$0.02`** |",
|
|
399
|
-
"| Codex/Antigravity CLI 추가 비용 | | | `$0.00` |",
|
|
400
|
-
"",
|
|
401
|
-
"## 7. Final Verdict",
|
|
402
|
-
"",
|
|
403
|
-
"| 항목 | 값 |",
|
|
404
|
-
"|------|----|",
|
|
405
|
-
"| Verdict Token | `accepted` |",
|
|
406
|
-
"",
|
|
407
|
-
"## 5.8 Final Verification Deliverables",
|
|
408
|
-
"",
|
|
409
|
-
"Source Implementation Report / Acceptance Blockers / Residual Risk / "
|
|
410
|
-
"Validation Evidence / Read-only Command Log / Conditional Acceptance "
|
|
411
|
-
"Conditions / Routing Recommendation: fixture stub.",
|
|
412
|
-
]
|
|
413
|
-
)
|
|
414
|
-
report_path.parent.mkdir(parents=True, exist_ok=True)
|
|
415
|
-
_report_name = report_path.name
|
|
416
|
-
if _report_name.endswith(".data.json"):
|
|
417
|
-
data_path = report_path
|
|
418
|
-
md_path = report_path.with_name(_report_name[: -len(".data.json")] + ".md")
|
|
419
|
-
elif _report_name.endswith(".md"):
|
|
420
|
-
md_path = report_path
|
|
421
|
-
data_path = report_path.with_name(_report_name[: -len(".md")] + ".data.json")
|
|
422
|
-
else:
|
|
423
|
-
md_path = report_path
|
|
424
|
-
data_path = report_path.with_suffix(".data.json")
|
|
425
|
-
md_path.write_text("\n".join(report_lines) + "\n")
|
|
426
|
-
|
|
427
|
-
# Phase 7 step 1.5 (BLOCKING) — render the html sibling artifact next
|
|
428
|
-
# to the final-report so validate-run.py's report-views hook passes.
|
|
429
|
-
# The workflow validator's fixture predates that step; we materialise
|
|
430
|
-
# the html file in-place using the same single-reference-point helper
|
|
431
|
-
# the CLI uses.
|
|
432
|
-
import os
|
|
433
|
-
WORKSPACE_ROOT = os.environ.get("OKSTRA_WORKSPACE_ROOT_FOR_FIXTURE", "")
|
|
434
|
-
if WORKSPACE_ROOT:
|
|
435
|
-
# Write final-report .data.json SSOT next to the markdown. The validator's
|
|
436
|
-
# validate_final_report_data() reads this via _data_path_for(report_path)
|
|
437
|
-
# and the renderer treats it as the canonical source — the markdown alone
|
|
438
|
-
# is no longer a valid run artifact (dual-format final-report rollout).
|
|
439
|
-
# Sample bundled in tests/fixtures is patched with this run's task identity.
|
|
440
|
-
task_type = str(task_manifest.get("taskType", ""))
|
|
441
|
-
sample_path = (
|
|
442
|
-
Path(WORKSPACE_ROOT)
|
|
443
|
-
/ "tests" / "fixtures" / "final-report-data-v2"
|
|
444
|
-
/ f"{task_type}-001.data.json"
|
|
445
|
-
)
|
|
446
|
-
if sample_path.is_file():
|
|
447
|
-
sample = json.loads(sample_path.read_text(encoding="utf-8"))
|
|
448
|
-
sample["frontmatter"]["taskGroup"] = str(task_manifest.get("taskGroup", ""))
|
|
449
|
-
sample["frontmatter"]["taskId"] = str(task_manifest.get("taskId", ""))
|
|
450
|
-
sample["frontmatter"]["taskType"] = task_type
|
|
451
|
-
sample["frontmatter"]["projectId"] = str(task_manifest.get("projectId", ""))
|
|
452
|
-
sample["header"]["taskKey"] = str(task_manifest.get("taskKey", ""))
|
|
453
|
-
sample["header"]["taskType"] = task_type
|
|
454
|
-
# The shipped fixture carries its own roster; this run's contract names
|
|
455
|
-
# a different one, and the validator compares the report's agent rows
|
|
456
|
-
# against that contract. Restate the rows under the contract's names so
|
|
457
|
-
# the fixture exercises the check instead of tripping over it.
|
|
458
|
-
_required = (
|
|
459
|
-
(run_manifest.get("teamContract") or {}).get("requiredAgentStatusEntries")
|
|
460
|
-
or (task_manifest.get("resultContract") or {}).get(
|
|
461
|
-
"requiredAgentStatusEntries"
|
|
462
|
-
)
|
|
463
|
-
or []
|
|
464
|
-
)
|
|
465
|
-
_rows = sample.get("executionStatus") or []
|
|
466
|
-
if _required and _rows:
|
|
467
|
-
# `agent` is the runtime (a schema enum); `role` carries the label the
|
|
468
|
-
# validator looks for in the rendered markdown.
|
|
469
|
-
sample["executionStatus"] = [
|
|
470
|
-
{**_rows[min(i, len(_rows) - 1)], "role": role}
|
|
471
|
-
for i, role in enumerate(_required)
|
|
472
|
-
]
|
|
473
|
-
data_path.write_text(
|
|
474
|
-
json.dumps(sample, indent=2, ensure_ascii=False) + "\n",
|
|
475
|
-
encoding="utf-8",
|
|
476
|
-
)
|
|
477
|
-
|
|
478
|
-
import sys as _sys
|
|
479
|
-
_sys.path.insert(0, str(Path(WORKSPACE_ROOT) / "scripts"))
|
|
480
|
-
# The markdown seeded above this block predates the data.json contract, so
|
|
481
|
-
# re-render it from the data.json the fixture just wrote. Otherwise the pair
|
|
482
|
-
# disagrees and the validator's AI-handoff heading scan fails on a fixture
|
|
483
|
-
# that never claimed to be hand-authored.
|
|
484
|
-
if sample_path.is_file():
|
|
485
|
-
try:
|
|
486
|
-
from okstra_ctl.render_final_report import render_to_file
|
|
487
|
-
|
|
488
|
-
render_to_file(data_path, md_path)
|
|
489
|
-
except Exception as exc: # pragma: no cover — fixture path only
|
|
490
|
-
raise SystemExit(f"failed to render final report in fixture: {exc}")
|
|
491
|
-
# Go through the same CLI the run uses, so the fixture picks the schema's
|
|
492
|
-
# own view (v2 task template) rather than a second copy of that choice.
|
|
493
|
-
import subprocess as _subprocess
|
|
494
|
-
_views = _subprocess.run(
|
|
495
|
-
[
|
|
496
|
-
_sys.executable,
|
|
497
|
-
str(Path(WORKSPACE_ROOT) / "scripts" / "okstra-render-report-views.py"),
|
|
498
|
-
str(data_path),
|
|
499
|
-
"--task-key", str(task_manifest.get("taskKey", "validation/fixture")),
|
|
500
|
-
"--task-type", str(task_manifest.get("taskType", "validation")),
|
|
501
|
-
"--seq", "001",
|
|
502
|
-
],
|
|
503
|
-
capture_output=True,
|
|
504
|
-
text=True,
|
|
505
|
-
)
|
|
506
|
-
if _views.returncode != 0:
|
|
507
|
-
raise SystemExit(
|
|
508
|
-
f"failed to render report views in fixture: {_views.stderr or _views.stdout}"
|
|
509
|
-
)
|
|
510
|
-
|
|
511
|
-
if final_status_path.exists():
|
|
512
|
-
final_status_path.unlink()
|
|
513
|
-
|
|
514
|
-
# session-conformance fixture — validate_session_conformance 는 lead 세션
|
|
515
|
-
# jsonl 에서 run 윈도우 내 PROGRESS 체크포인트를 스캔한다. 계약을 준수한
|
|
516
|
-
# 합성 jsonl 을 주입 시드 디렉터리(.claude-projects-fixture)에 만들어 두고,
|
|
517
|
-
# 러너(run_validator_expectation)가 --claude-projects-dir 로 넘긴다.
|
|
518
|
-
lead_sid = str((team_state.get("lead") or {}).get("sessionId") or "").strip()
|
|
519
|
-
if lead_sid:
|
|
520
|
-
now_iso = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
|
|
521
|
-
progress_lines = [
|
|
522
|
-
"PROGRESS: phase-1-intake reading task bundle",
|
|
523
|
-
"PROGRESS: phase-1-intake complete",
|
|
524
|
-
f"PROGRESS: phase-2-prompts preparing {len(team_state.get('workers') or [])} worker prompts",
|
|
525
|
-
"PROGRESS: phase-3-team-create using implicit team (split-pane=off)",
|
|
526
|
-
]
|
|
527
|
-
for worker in team_state.get("workers", []):
|
|
528
|
-
if not isinstance(worker, dict):
|
|
529
|
-
continue
|
|
530
|
-
worker_id = str(worker.get("workerId", "")).strip()
|
|
531
|
-
status = str(worker.get("status", "")).strip()
|
|
532
|
-
if not worker_id or worker_id == "report-writer":
|
|
533
|
-
continue
|
|
534
|
-
if status in ("completed", "timeout", "error"):
|
|
535
|
-
progress_lines.append(
|
|
536
|
-
f"PROGRESS: phase-4-dispatch worker={worker_id}-worker model=fixture"
|
|
537
|
-
)
|
|
538
|
-
if status == "completed":
|
|
539
|
-
progress_lines.append(
|
|
540
|
-
f"PROGRESS: phase-5-collect worker={worker_id}-worker status=completed"
|
|
541
|
-
)
|
|
542
|
-
progress_lines.append("PROGRESS: phase-batch-cleanup panes=1")
|
|
543
|
-
progress_lines.append("PROGRESS: phase-6-synthesis dispatching report-writer-worker")
|
|
544
|
-
progress_lines.append("PROGRESS: phase-7-persist updating manifests")
|
|
545
|
-
records = [
|
|
546
|
-
{
|
|
547
|
-
"type": "assistant",
|
|
548
|
-
"timestamp": now_iso,
|
|
549
|
-
"message": {"content": [{"type": "text", "text": line}]},
|
|
550
|
-
}
|
|
551
|
-
for line in progress_lines
|
|
552
|
-
]
|
|
553
|
-
# 인코딩 기준은 validator 가 쓰는 task-manifest.projectRoot — macOS 의
|
|
554
|
-
# /tmp 심링크 때문에 셸의 $PROJECT_ROOT(/tmp/...)와 manifest 의
|
|
555
|
-
# projectRoot(/private/tmp/...)가 다른 문자열일 수 있다.
|
|
556
|
-
manifest_project_root = str(task_manifest.get("projectRoot") or project_root)
|
|
557
|
-
encoded_cwd = "-" + manifest_project_root.strip("/").replace("/", "-")
|
|
558
|
-
session_dir = project_root / ".claude-projects-fixture" / encoded_cwd
|
|
559
|
-
session_dir.mkdir(parents=True, exist_ok=True)
|
|
560
|
-
(session_dir / f"{lead_sid}.jsonl").write_text(
|
|
561
|
-
"".join(json.dumps(r, ensure_ascii=False) + "\n" for r in records)
|
|
562
|
-
)
|
|
563
|
-
|
|
564
|
-
write_json(team_state_path, team_state)
|
|
565
|
-
write_json(run_manifest_path, run_manifest)
|
|
566
|
-
write_json(task_manifest_path, task_manifest)
|
|
567
|
-
|
|
568
|
-
# The synthetic fixture accepts lead and completed-worker results, so it must
|
|
569
|
-
# create the same verified invocation records and result links as a real run.
|
|
570
|
-
# Keep the deliberately omitted worker prompt absent: the first validator pass
|
|
571
|
-
# still exercises the historical prompt-history failure before the helper
|
|
572
|
-
# restores that file.
|
|
573
|
-
if WORKSPACE_ROOT:
|
|
574
|
-
from okstra_ctl.agent_invocation import (
|
|
575
|
-
AgentInstruction,
|
|
576
|
-
AgentInstructionSource,
|
|
577
|
-
AgentInvocationRequest,
|
|
578
|
-
agent_model_assignment_from_payload,
|
|
579
|
-
invocation_execution_identity_from_manifest,
|
|
580
|
-
prepare_agent_invocation,
|
|
581
|
-
)
|
|
582
|
-
from okstra_ctl.dispatch_state import (
|
|
583
|
-
link_agent_dispatch_result,
|
|
584
|
-
record_verified_agent_dispatch,
|
|
585
|
-
)
|
|
586
|
-
# The analysis duty depends on the task type, exactly as it does in a real
|
|
587
|
-
# run — a fixture that assumed one audience for every phase would be
|
|
588
|
-
# rejected by the manifest's own allowlist.
|
|
589
|
-
from okstra_ctl.worker_prompt_policy import ANALYSIS_DUTY_BY_TASK_TYPE
|
|
590
|
-
|
|
591
|
-
analysis_audience = ANALYSIS_DUTY_BY_TASK_TYPE.get(
|
|
592
|
-
str(run_manifest.get("taskType") or ""), "analysis-worker"
|
|
593
|
-
)
|
|
594
|
-
|
|
595
|
-
lead_record = record_verified_agent_dispatch(
|
|
596
|
-
project_root=project_root,
|
|
597
|
-
run_manifest_path=run_manifest_path,
|
|
598
|
-
metadata_path=project_root / run_manifest["leadPromptMetadataPath"],
|
|
599
|
-
enforcement_mode="host-native-spec-link-gate",
|
|
600
|
-
)
|
|
601
|
-
link_agent_dispatch_result(
|
|
602
|
-
project_root=project_root,
|
|
603
|
-
run_manifest_path=run_manifest_path,
|
|
604
|
-
dispatch_id=lead_record["dispatchId"],
|
|
605
|
-
result_path=report_path,
|
|
606
|
-
)
|
|
607
|
-
|
|
608
|
-
assignments = run_manifest["invocationAssignments"]
|
|
609
|
-
contract = run_manifest["agentContract"]
|
|
610
|
-
reservation_root = project_root / contract["invocationReservationRootPath"]
|
|
611
|
-
for worker in team_state.get("workers", []):
|
|
612
|
-
if not isinstance(worker, dict):
|
|
613
|
-
continue
|
|
614
|
-
worker_id = str(worker.get("workerId") or "").strip()
|
|
615
|
-
prompt_relative = str(worker.get("promptPath") or "").strip()
|
|
616
|
-
result_relative = str(worker.get("resultPath") or "").strip()
|
|
617
|
-
if not worker_id or not prompt_relative or not result_relative:
|
|
618
|
-
continue
|
|
619
|
-
source_prompt = project_root / prompt_relative
|
|
620
|
-
if not source_prompt.is_file():
|
|
621
|
-
continue
|
|
622
|
-
assignment_ref = f"initial/{worker_id}"
|
|
623
|
-
invocation_id = f"validation-fixture-{worker_id}"
|
|
624
|
-
invocation_prompt = reservation_root / f"{invocation_id}.prompt.md"
|
|
625
|
-
audience = (
|
|
626
|
-
"report-writer" if worker_id == "report-writer"
|
|
627
|
-
else analysis_audience
|
|
628
|
-
)
|
|
629
|
-
assignment = agent_model_assignment_from_payload(
|
|
630
|
-
assignments[assignment_ref]
|
|
631
|
-
)
|
|
632
|
-
identity = invocation_execution_identity_from_manifest(
|
|
633
|
-
run_manifest,
|
|
634
|
-
assignment=assignment,
|
|
635
|
-
assignment_ref=assignment_ref,
|
|
636
|
-
duty_id=audience,
|
|
637
|
-
)
|
|
638
|
-
identity_args = {
|
|
639
|
-
"participant_ref": (
|
|
640
|
-
identity.participant_ref if identity is not None else None
|
|
641
|
-
),
|
|
642
|
-
"role_execution_ref": (
|
|
643
|
-
identity.role_execution_ref if identity is not None else None
|
|
644
|
-
),
|
|
645
|
-
"duty_id": identity.duty_id if identity is not None else None,
|
|
646
|
-
"invocation_ref": invocation_id if identity is not None else None,
|
|
647
|
-
"attempt": 1,
|
|
648
|
-
}
|
|
649
|
-
prepared = prepare_agent_invocation(AgentInvocationRequest(
|
|
650
|
-
invocation_id=invocation_id,
|
|
651
|
-
worker_id=worker_id if identity is None else None,
|
|
652
|
-
audience=audience,
|
|
653
|
-
assignment_ref=assignment_ref,
|
|
654
|
-
purpose=None,
|
|
655
|
-
assignment=assignment,
|
|
656
|
-
instruction=AgentInstruction(
|
|
657
|
-
anchor_lines=(),
|
|
658
|
-
body=source_prompt.read_text(encoding="utf-8"),
|
|
659
|
-
source_paths=(
|
|
660
|
-
AgentInstructionSource("project", prompt_relative),
|
|
661
|
-
),
|
|
662
|
-
),
|
|
663
|
-
project_root=project_root,
|
|
664
|
-
run_manifest_path=run_manifest_path,
|
|
665
|
-
duty_root=project_root / contract["dutyRootPath"],
|
|
666
|
-
prompt_path=invocation_prompt,
|
|
667
|
-
metadata_path=invocation_prompt.with_name(
|
|
668
|
-
invocation_prompt.name + ".meta.json"
|
|
669
|
-
),
|
|
670
|
-
dispatch_kind="validation-fixture",
|
|
671
|
-
**identity_args,
|
|
672
|
-
))
|
|
673
|
-
dispatch = record_verified_agent_dispatch(
|
|
674
|
-
project_root=project_root,
|
|
675
|
-
run_manifest_path=run_manifest_path,
|
|
676
|
-
metadata_path=prepared.metadata_path,
|
|
677
|
-
enforcement_mode=(
|
|
678
|
-
"host-native-spec-link-gate"
|
|
679
|
-
if prepared.assignment.runner == "native-session"
|
|
680
|
-
else "core-pre-dispatch"
|
|
681
|
-
),
|
|
682
|
-
)
|
|
683
|
-
if worker.get("status") == "completed":
|
|
684
|
-
link_agent_dispatch_result(
|
|
685
|
-
project_root=project_root,
|
|
686
|
-
run_manifest_path=run_manifest_path,
|
|
687
|
-
dispatch_id=dispatch["dispatchId"],
|
|
688
|
-
result_path=project_root / result_relative,
|
|
689
|
-
)
|
|
690
|
-
|
|
691
|
-
# Preserve the workflow's historical missing-prompt negative after the v2
|
|
692
|
-
# invocation record has captured the prompt bytes that were actually sent.
|
|
693
|
-
for worker in team_state.get("workers", []):
|
|
694
|
-
if isinstance(worker, dict) and worker.get("workerId") == omitted_worker_id:
|
|
695
|
-
omitted_prompt = str(worker.get("promptPath") or "").strip()
|
|
696
|
-
if omitted_prompt:
|
|
697
|
-
(project_root / omitted_prompt).unlink(missing_ok=True)
|
|
698
|
-
break
|
|
699
|
-
PY
|
|
115
|
+
python3 "$OKSTRA_VALIDATOR_CHECKS/fixtures-02.py" "$PROJECT_ROOT" "$expected_task_manifest_relative_path" "$omitted_worker_id"
|
|
700
116
|
}
|
|
@@ -16,6 +16,19 @@ validate_project_root_safety() {
|
|
|
16
16
|
fi
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
# 검증 루트가 실행끼리 공유되면 한쪽의 reset_validation_root 가 다른 쪽의
|
|
20
|
+
# 진행 중 run 을 지운다(동시 npm run check). 기본값은 실행 단위로 유일한
|
|
21
|
+
# mktemp 디렉토리 — validate_project_root_safety 의 /tmp/okstra-validate.*
|
|
22
|
+
# 허용 패턴 안에 머무는 접두사를 유지해야 한다.
|
|
23
|
+
resolve_validation_project_root() {
|
|
24
|
+
if [[ -n "${OKSTRA_VALIDATION_PROJECT_ROOT:-}" ]]; then
|
|
25
|
+
printf '%s\n' "$OKSTRA_VALIDATION_PROJECT_ROOT"
|
|
26
|
+
return
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
mktemp -d /tmp/okstra-validate.workflow.XXXXXX
|
|
30
|
+
}
|
|
31
|
+
|
|
19
32
|
reset_validation_root() {
|
|
20
33
|
rm -rf "$PROJECT_ROOT"
|
|
21
34
|
mkdir -p "$PROJECT_ROOT"
|