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
|
@@ -11,6 +11,17 @@ from pathlib import Path
|
|
|
11
11
|
from typing import Any, Mapping
|
|
12
12
|
|
|
13
13
|
from .json_boundary import JsonBoundaryError, load_owned_object, write_owned_object_atomic
|
|
14
|
+
from .implementation_options import (
|
|
15
|
+
CANDIDATE_COMPARISON_ROUTING,
|
|
16
|
+
EVALUATION_CRITERIA,
|
|
17
|
+
MAX_CRITERION_VALUE,
|
|
18
|
+
MAX_RANKED_OPTIONS,
|
|
19
|
+
MIN_CRITERION_VALUE,
|
|
20
|
+
MIN_FEASIBLE_VOTES,
|
|
21
|
+
NO_VALID_OPTIONS_ROUTING,
|
|
22
|
+
)
|
|
23
|
+
from .report_narrative import writer_owned_data
|
|
24
|
+
from .scope_provenance import brief_end_state_id_sequence
|
|
14
25
|
|
|
15
26
|
|
|
16
27
|
@dataclass(frozen=True)
|
|
@@ -52,6 +63,97 @@ class ReportSynthesisPacket:
|
|
|
52
63
|
result_path: str
|
|
53
64
|
sources: tuple[ReportSynthesisSource, ...]
|
|
54
65
|
accounting_snapshot: dict[str, Any]
|
|
66
|
+
original_requirement_ids: tuple[str, ...] = ()
|
|
67
|
+
participating_analysers: tuple[str, ...] = ()
|
|
68
|
+
# 증분 판정. 저작 계약이 이번 run 의 stage 번호를 말할 수 있는 유일한 출처다.
|
|
69
|
+
incremental_decision: dict[str, Any] | None = None
|
|
70
|
+
|
|
71
|
+
def _carry_instructions(self) -> list[str]:
|
|
72
|
+
"""이번 run 의 이월 지시. 증분이 아니면 빈 목록.
|
|
73
|
+
|
|
74
|
+
일반 규칙으로 두면 계획 분석자 프로필의 한 줄이 되고, 그 줄은 이번
|
|
75
|
+
run 의 `carry_stages` 값을 말하지 못한다. 번호를 박아 넣는 자리는
|
|
76
|
+
판정을 아는 여기뿐이다.
|
|
77
|
+
"""
|
|
78
|
+
decision = self.incremental_decision
|
|
79
|
+
if not decision:
|
|
80
|
+
return []
|
|
81
|
+
carried = ", ".join(str(stage) for stage in decision.get("carryStages", []))
|
|
82
|
+
reverify = ", ".join(str(stage) for stage in decision.get("reverifyStages", []))
|
|
83
|
+
return [
|
|
84
|
+
"This run is an incremental re-plan. Record the decision verbatim as "
|
|
85
|
+
"`implementationPlanning.incrementalDecision` with keys mode, "
|
|
86
|
+
"reverifyStages, carryStages, reason.",
|
|
87
|
+
f"Copy stage rows {carried} from the \"{CARRIED_STAGES_LABEL}\" source "
|
|
88
|
+
f"into `implementationPlanning.stages` unchanged - every field, byte for "
|
|
89
|
+
f"byte. Author only stage(s) {reverify}. `okstra incremental-carry` "
|
|
90
|
+
f"rejects a carried stage that changed or is missing.",
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
def _carry_validation_rules(self) -> list[str]:
|
|
94
|
+
return ["carried-stages-unchanged"] if self.incremental_decision else []
|
|
95
|
+
|
|
96
|
+
def _task_instructions(self) -> list[str]:
|
|
97
|
+
if self.task_type == "implementation-planning":
|
|
98
|
+
return self._planning_requirement_instructions()
|
|
99
|
+
if self.task_type != "implementation-option-selection":
|
|
100
|
+
return []
|
|
101
|
+
criteria = ", ".join(f"`{item}`" for item in EVALUATION_CRITERIA)
|
|
102
|
+
requirement_ids = ", ".join(
|
|
103
|
+
f"`{item}`" for item in self.original_requirement_ids
|
|
104
|
+
)
|
|
105
|
+
analysers = ", ".join(
|
|
106
|
+
f"`{item}`" for item in self.participating_analysers
|
|
107
|
+
)
|
|
108
|
+
return [
|
|
109
|
+
f"Original requirement ids, in order: {requirement_ids}.",
|
|
110
|
+
f"Participating analysers: {analysers}.",
|
|
111
|
+
f"Evaluation criteria, in exact order: {criteria}.",
|
|
112
|
+
"Every `rankedOptions` and `candidateAudit` row must contain one "
|
|
113
|
+
"`requirementCoverage` row per original requirement id and one "
|
|
114
|
+
"`criterionScores` row per evaluation criterion. Weights and scores "
|
|
115
|
+
f"are integers from {MIN_CRITERION_VALUE} through {MAX_CRITERION_VALUE}; "
|
|
116
|
+
"`weightedScore` is the recalculated weighted mean.",
|
|
117
|
+
"A ranked option is valid only when every participating analyser "
|
|
118
|
+
"supplied one feasibility vote, at least "
|
|
119
|
+
f"{MIN_FEASIBLE_VOTES} votes are `feasible`, and both `safetyBlockers` "
|
|
120
|
+
"and `unresolvedFeasibilityFacts` are empty.",
|
|
121
|
+
f"Rank at most {MAX_RANKED_OPTIONS} valid options by descending "
|
|
122
|
+
"`requirement-fit`, `correctness-risk`, `architecture-fit`, "
|
|
123
|
+
"`weightedScore`, then id. With valid options set routing to "
|
|
124
|
+
f"`{CANDIDATE_COMPARISON_ROUTING}`; without a valid option use "
|
|
125
|
+
f"`{NO_VALID_OPTIONS_ROUTING}`.",
|
|
126
|
+
"In `candidate-comparison`, keep `preselectedDirection` null and do "
|
|
127
|
+
"not route directly to `implementation-planning`. In "
|
|
128
|
+
"`preselected-validation`, emit exactly one validated option, an empty "
|
|
129
|
+
"`candidateAudit`, a cited `preselectedDirection`, and routing "
|
|
130
|
+
"`implementation-planning`.",
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
def _planning_requirement_instructions(self) -> list[str]:
|
|
134
|
+
"""계획 저작 계약에 브리프 요구사항 id 순서를 박아 넣는다.
|
|
135
|
+
|
|
136
|
+
`validate_selected_direction_plan` 은 `requirementCoverage` 행 순서가
|
|
137
|
+
taskBriefPath 의 end-state id 순서와 정확히 한 번씩 일치할 것을
|
|
138
|
+
요구한다 (`implementation_direction._coverage_summary_errors`). 그
|
|
139
|
+
순서가 저작 계약에 없으면 작성자는 브리프 원문에서 재유도해야 하고,
|
|
140
|
+
오차는 §5.5.9 라운드 낭비와 조립 거부로 돌아온다. 레거시 브리프
|
|
141
|
+
(end-state id 없음)는 빈 목록이므로 지시도 싣지 않는다 — 검증기도
|
|
142
|
+
같은 조건으로 자기 비활성화한다.
|
|
143
|
+
"""
|
|
144
|
+
if not self.original_requirement_ids:
|
|
145
|
+
return []
|
|
146
|
+
requirement_ids = ", ".join(
|
|
147
|
+
f"`{item}`" for item in self.original_requirement_ids
|
|
148
|
+
)
|
|
149
|
+
return [
|
|
150
|
+
f"Original requirement ids, in order: {requirement_ids}.",
|
|
151
|
+
"`implementationPlanning.requirementCoverage` must contain exactly "
|
|
152
|
+
"one row per original requirement id (`originalRequirementId`), in "
|
|
153
|
+
"that exact order.",
|
|
154
|
+
"`endStateCoverage` must contain exactly one row per original "
|
|
155
|
+
"requirement id; an `addressed` row names its `coveredBy` anchor.",
|
|
156
|
+
]
|
|
55
157
|
|
|
56
158
|
def to_dict(self) -> dict[str, Any]:
|
|
57
159
|
return {
|
|
@@ -67,6 +169,9 @@ class ReportSynthesisPacket:
|
|
|
67
169
|
"Preserve settled source values, identities, dissent, and user responses.",
|
|
68
170
|
"Do not invent a value when a source is missing or contradictory.",
|
|
69
171
|
"Write only the narrative, pointer, and audit artifacts named by the dispatch.",
|
|
172
|
+
*_INTERNAL_IDENTIFIER_INSTRUCTION,
|
|
173
|
+
*self._task_instructions(),
|
|
174
|
+
*self._carry_instructions(),
|
|
70
175
|
],
|
|
71
176
|
"runtimeOwnedContent": [
|
|
72
177
|
"session identifiers",
|
|
@@ -78,6 +183,7 @@ class ReportSynthesisPacket:
|
|
|
78
183
|
"source-digest-match",
|
|
79
184
|
"writer-owned-fields-only",
|
|
80
185
|
"all-defects-collected",
|
|
186
|
+
*self._carry_validation_rules(),
|
|
81
187
|
],
|
|
82
188
|
},
|
|
83
189
|
"accountingSnapshot": self.accounting_snapshot,
|
|
@@ -99,6 +205,11 @@ class ReportSynthesisPacket:
|
|
|
99
205
|
"user response carry-in",
|
|
100
206
|
"- Validation: source digest match, writer-owned fields, all defects collected",
|
|
101
207
|
]
|
|
208
|
+
# 작성자가 실제로 읽는 것은 마크다운이다. JSON 정본에만 실으면 지시가
|
|
209
|
+
# 도달하지 않는다.
|
|
210
|
+
lines.extend(f"- {text}" for text in _INTERNAL_IDENTIFIER_INSTRUCTION)
|
|
211
|
+
lines.extend(f"- {text}" for text in self._task_instructions())
|
|
212
|
+
lines.extend(f"- {text}" for text in self._carry_instructions())
|
|
102
213
|
lines.extend(_accounting_markdown(self.accounting_snapshot))
|
|
103
214
|
for source in self.sources:
|
|
104
215
|
lines.extend(_source_markdown(source))
|
|
@@ -190,12 +301,129 @@ def _context_path(
|
|
|
190
301
|
return _string(manifest.get(key))
|
|
191
302
|
|
|
192
303
|
|
|
304
|
+
# 패킷은 워커 결과를 통째로 나른다. 그 안의 finding id(`F-001`)는 수렴 상태에만
|
|
305
|
+
# 있고 리포트는 그 id 를 정의하는 객체를 싣지 않는다 — 인용하면 독자가 해소할 수
|
|
306
|
+
# 없는 참조가 된다. 규칙은 여기에 둔다: 워커 결과를 보여 주는 자리가 여기뿐이다.
|
|
307
|
+
# 집행 코드는 없다(리포트 산문은 자유 서술이다). 저자 지시로만 전달한다.
|
|
308
|
+
_INTERNAL_IDENTIFIER_INSTRUCTION = (
|
|
309
|
+
"Do not cite worker-internal identifiers in reader-facing prose - finding "
|
|
310
|
+
"ids (`F-NNN`), worker ids, round labels. This report defines none of them, "
|
|
311
|
+
"so the reader cannot resolve them. State the substance instead, and cite "
|
|
312
|
+
"only identifiers the report itself defines (`R-NNN`, `C-NNN`, `A-NNN`, "
|
|
313
|
+
"stage numbers).",
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
CARRIED_STAGES_LABEL = "Carried plan stages"
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def read_incremental_decision(
|
|
321
|
+
project_root: Path, manifest: Mapping[str, Any],
|
|
322
|
+
) -> dict | None:
|
|
323
|
+
"""이 run 의 증분 판정. 없거나 증분이 아니면 ``None``.
|
|
324
|
+
|
|
325
|
+
레코드가 없으면 full 로 읽는다 — 그것이 이 기능이 없던 동안의 동작이고,
|
|
326
|
+
"판정을 못 찾았으니 좁혀도 된다"는 반대 방향의 실패보다 안전하다.
|
|
327
|
+
"""
|
|
328
|
+
value = _string(manifest.get("incrementalDecisionPath"))
|
|
329
|
+
if not value:
|
|
330
|
+
return None
|
|
331
|
+
path = _resolve(project_root, value)
|
|
332
|
+
if not path.is_file():
|
|
333
|
+
return None
|
|
334
|
+
try:
|
|
335
|
+
record = load_owned_object(path, artifact="incremental scope decision")
|
|
336
|
+
except (OSError, UnicodeError, JsonBoundaryError):
|
|
337
|
+
return None
|
|
338
|
+
if not isinstance(record, Mapping) or record.get("mode") != "incremental":
|
|
339
|
+
return None
|
|
340
|
+
stages = record.get("carryStages")
|
|
341
|
+
if not isinstance(stages, list) or not stages:
|
|
342
|
+
return None
|
|
343
|
+
return dict(record)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def carried_stage_rows(prior_data: Mapping[str, Any], carry_stages: list) -> list[dict]:
|
|
347
|
+
"""직전 리포트에서 이월 대상 stage 의 **본문 행**을 뽑는다.
|
|
348
|
+
|
|
349
|
+
Stage Ledger 가 싣는 것은 `stage`/`title`/`status`/`dependsOn`/`headCommit`
|
|
350
|
+
뿐이다. narrative 의 `stages[]` 한 행은 `sliceValue`·`acceptance`·`carryIn`·
|
|
351
|
+
`stepwiseExecution`·`exitContract`·`stageValidation` 을 요구하므로, 원장만
|
|
352
|
+
받은 작성자는 이월 행을 옮길 수 없다.
|
|
353
|
+
"""
|
|
354
|
+
# 작성자에게 넘기는 행은 작성자 소유 필드만이어야 한다. 완성 리포트의
|
|
355
|
+
# stage 행에는 `designSurfaceCoverage` 같은 assembly 소유 필드가 함께 있고,
|
|
356
|
+
# 그것까지 실으면 "옮겨 적으라"는 지시가 곧 소유권 위반 지시가 된다.
|
|
357
|
+
planning = writer_owned_data(prior_data).get("implementationPlanning")
|
|
358
|
+
rows = planning.get("stages") if isinstance(planning, Mapping) else None
|
|
359
|
+
if not isinstance(rows, list):
|
|
360
|
+
return []
|
|
361
|
+
wanted = {int(stage) for stage in carry_stages if isinstance(stage, int)}
|
|
362
|
+
return [
|
|
363
|
+
dict(row)
|
|
364
|
+
for row in rows
|
|
365
|
+
if isinstance(row, Mapping) and row.get("stage") in wanted
|
|
366
|
+
]
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def carried_stages_path(narrative_path: Path) -> Path:
|
|
370
|
+
_, markdown_path = report_synthesis_packet_paths(narrative_path)
|
|
371
|
+
return markdown_path.with_name(
|
|
372
|
+
markdown_path.name.replace(
|
|
373
|
+
"report-writer-synthesis-packet", "report-writer-carried-stages"
|
|
374
|
+
)
|
|
375
|
+
).with_suffix(".json")
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def materialize_carried_stages(
|
|
379
|
+
*,
|
|
380
|
+
project_root: Path,
|
|
381
|
+
manifest: Mapping[str, Any],
|
|
382
|
+
narrative_path: Path,
|
|
383
|
+
) -> tuple[str, dict] | None:
|
|
384
|
+
"""이월 stage 본문을 파일로 남기고 (프로젝트 상대 경로, 판정) 을 돌려준다.
|
|
385
|
+
|
|
386
|
+
묶음의 source 는 파일과 그 다이제스트다. 파생 내용을 특례로 인라인하지 않고
|
|
387
|
+
실제 파일로 만드는 이유는 두 가지다 — 다이제스트가 다른 source 와 같은
|
|
388
|
+
의미를 갖고, 어긋났을 때 사람이 열어 볼 수 있다.
|
|
389
|
+
"""
|
|
390
|
+
decision = read_incremental_decision(project_root, manifest)
|
|
391
|
+
if decision is None:
|
|
392
|
+
return None
|
|
393
|
+
prior = _resolve(project_root, _string(decision.get("prevDataPath")))
|
|
394
|
+
if not prior.is_file():
|
|
395
|
+
return None
|
|
396
|
+
try:
|
|
397
|
+
prior_data = load_owned_object(prior, artifact="prior planning report")
|
|
398
|
+
except (OSError, UnicodeError, JsonBoundaryError):
|
|
399
|
+
return None
|
|
400
|
+
rows = carried_stage_rows(prior_data, decision["carryStages"])
|
|
401
|
+
if not rows:
|
|
402
|
+
return None
|
|
403
|
+
path = carried_stages_path(narrative_path)
|
|
404
|
+
write_owned_object_atomic(
|
|
405
|
+
path,
|
|
406
|
+
{
|
|
407
|
+
"schemaVersion": "1.0",
|
|
408
|
+
"sourcePlanPath": _string(decision.get("prevDataPath")),
|
|
409
|
+
"carryStages": list(decision["carryStages"]),
|
|
410
|
+
"stages": rows,
|
|
411
|
+
},
|
|
412
|
+
artifact="carried plan stages",
|
|
413
|
+
)
|
|
414
|
+
try:
|
|
415
|
+
return str(path.resolve().relative_to(project_root.resolve())), decision
|
|
416
|
+
except ValueError:
|
|
417
|
+
return str(path), decision
|
|
418
|
+
|
|
419
|
+
|
|
193
420
|
def _source_specs(
|
|
194
421
|
project_root: Path,
|
|
195
422
|
manifest: Mapping[str, Any],
|
|
196
423
|
active_context: Mapping[str, Any],
|
|
197
424
|
team_state: Mapping[str, Any],
|
|
198
425
|
narrative_path: Path,
|
|
426
|
+
carried_source: str,
|
|
199
427
|
) -> list[tuple[str, str, str, bool]]:
|
|
200
428
|
specs: list[tuple[str, str, str, bool]] = []
|
|
201
429
|
for label, owner, section, key, required in _SOURCE_FIELDS:
|
|
@@ -212,6 +440,8 @@ def _source_specs(
|
|
|
212
440
|
path = str(Path(instruction_set) / "final-report-schema.json")
|
|
213
441
|
if path or required:
|
|
214
442
|
specs.append((label, owner, path, required))
|
|
443
|
+
if carried_source:
|
|
444
|
+
specs.append((CARRIED_STAGES_LABEL, "orchestrator", carried_source, True))
|
|
215
445
|
specs.extend(_user_response_specs(project_root, narrative_path))
|
|
216
446
|
attempt_specs = _attempt_result_specs(manifest)
|
|
217
447
|
if attempt_specs:
|
|
@@ -382,6 +612,9 @@ def build_report_synthesis_packet(
|
|
|
382
612
|
team_state: Mapping[str, Any],
|
|
383
613
|
narrative_path: Path,
|
|
384
614
|
) -> ReportSynthesisPacket:
|
|
615
|
+
carried = materialize_carried_stages(
|
|
616
|
+
project_root=project_root, manifest=manifest, narrative_path=narrative_path,
|
|
617
|
+
)
|
|
385
618
|
sources = _read_sources(
|
|
386
619
|
project_root,
|
|
387
620
|
_source_specs(
|
|
@@ -390,14 +623,38 @@ def build_report_synthesis_packet(
|
|
|
390
623
|
active_context,
|
|
391
624
|
team_state,
|
|
392
625
|
narrative_path,
|
|
626
|
+
carried[0] if carried else "",
|
|
393
627
|
),
|
|
394
628
|
)
|
|
629
|
+
task_type = _string(manifest.get("taskType"))
|
|
630
|
+
original_requirement_ids: tuple[str, ...] = ()
|
|
631
|
+
participating_analysers: tuple[str, ...] = ()
|
|
632
|
+
# 계획 저작도 같은 id 순서를 계약으로 받는다 — 커버리지 행 순서 검증
|
|
633
|
+
# (`validate_selected_direction_plan`)의 기준값이 이 목록이다.
|
|
634
|
+
if task_type in ("implementation-option-selection", "implementation-planning"):
|
|
635
|
+
brief_value = _context_path(
|
|
636
|
+
manifest, active_context, "instructionSet", "taskBriefPath"
|
|
637
|
+
)
|
|
638
|
+
original_requirement_ids = brief_end_state_id_sequence(
|
|
639
|
+
_resolve(project_root, brief_value)
|
|
640
|
+
)
|
|
641
|
+
if task_type == "implementation-option-selection":
|
|
642
|
+
roster = manifest.get("recommendedWorkers")
|
|
643
|
+
if isinstance(roster, list):
|
|
644
|
+
participating_analysers = tuple(
|
|
645
|
+
_string(worker)
|
|
646
|
+
for worker in roster
|
|
647
|
+
if _string(worker) and _string(worker) != "report-writer"
|
|
648
|
+
)
|
|
395
649
|
return ReportSynthesisPacket(
|
|
396
650
|
task_key=_string(manifest.get("taskKey")),
|
|
397
|
-
task_type=
|
|
651
|
+
task_type=task_type,
|
|
398
652
|
result_path=_relative(project_root, narrative_path),
|
|
399
653
|
sources=sources,
|
|
400
654
|
accounting_snapshot=_accounting_snapshot(team_state),
|
|
655
|
+
original_requirement_ids=original_requirement_ids,
|
|
656
|
+
participating_analysers=participating_analysers,
|
|
657
|
+
incremental_decision=carried[1] if carried else None,
|
|
401
658
|
)
|
|
402
659
|
|
|
403
660
|
|
|
@@ -69,6 +69,7 @@ PROSE_KEYS = frozenset({
|
|
|
69
69
|
"expectedForm",
|
|
70
70
|
"expectedOutcome",
|
|
71
71
|
"expectedResult",
|
|
72
|
+
"expectedVerification",
|
|
72
73
|
"failureHandling",
|
|
73
74
|
"finalConclusion",
|
|
74
75
|
"headline",
|
|
@@ -108,6 +109,7 @@ PROSE_KEYS = frozenset({
|
|
|
108
109
|
"rolloutCost",
|
|
109
110
|
"routingRecommendation",
|
|
110
111
|
"selfFixNote",
|
|
112
|
+
"satisfaction",
|
|
111
113
|
"stageTitle",
|
|
112
114
|
"stageValidation",
|
|
113
115
|
"statement",
|
|
@@ -293,10 +295,6 @@ STRUCTURAL_KEYS = frozenset({
|
|
|
293
295
|
})
|
|
294
296
|
|
|
295
297
|
|
|
296
|
-
class UnclassifiedKeys(ValueError):
|
|
297
|
-
"""A schema string field belongs to neither set."""
|
|
298
|
-
|
|
299
|
-
|
|
300
298
|
# A key name says what a field is *for*; these say what one value actually is.
|
|
301
299
|
# `evidence` is the largest prose bucket in a real report and also holds bare
|
|
302
300
|
# `src/server.ts:33` citations — the key cannot separate them, the value can.
|
|
@@ -429,17 +427,6 @@ def hangul_share(data: Mapping[str, Any]) -> tuple[float, int]:
|
|
|
429
427
|
return hangul / len(text), len(text)
|
|
430
428
|
|
|
431
429
|
|
|
432
|
-
def prose_is_english(data: Mapping[str, Any]) -> bool:
|
|
433
|
-
"""Whether the data.json was authored in English, as the SSOT contract requires.
|
|
434
|
-
|
|
435
|
-
The report language names what the human HTML renders in, not what the
|
|
436
|
-
worker writes. A worker that authors Korean anyway hands every later phase,
|
|
437
|
-
validator and agent a record in a language they do not read.
|
|
438
|
-
"""
|
|
439
|
-
share, _ = hangul_share(data)
|
|
440
|
-
return share < HANGUL_PROSE_LIMIT
|
|
441
|
-
|
|
442
|
-
|
|
443
430
|
def _schema_string_keys(schema: Mapping[str, Any], *, enums: bool) -> set[str]:
|
|
444
431
|
found: set[str] = set()
|
|
445
432
|
|
|
@@ -465,23 +452,3 @@ def _schema_string_keys(schema: Mapping[str, Any], *, enums: bool) -> set[str]:
|
|
|
465
452
|
walk(definition)
|
|
466
453
|
walk(schema)
|
|
467
454
|
return found
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
def schema_string_keys(schema: Mapping[str, Any]) -> set[str]:
|
|
471
|
-
"""Every leaf key in the schema whose value is a free-form string.
|
|
472
|
-
|
|
473
|
-
The drift guard compares this against the two sets above, so adding a
|
|
474
|
-
report field forces a decision about whether a translator may touch it.
|
|
475
|
-
"""
|
|
476
|
-
return _schema_string_keys(schema, enums=False)
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
def schema_enum_keys(schema: Mapping[str, Any]) -> set[str]:
|
|
480
|
-
"""Every leaf key the schema constrains to an enum, anywhere.
|
|
481
|
-
|
|
482
|
-
A name can be an enum in one definition and free prose in another —
|
|
483
|
-
`risk` is `high|medium|low` on a hotspot and a sentence on a risk row.
|
|
484
|
-
The renderer reaches for the same name either way (`tone-{{ row.risk }}`),
|
|
485
|
-
so one enum occurrence makes the name structural everywhere.
|
|
486
|
-
"""
|
|
487
|
-
return _schema_string_keys(schema, enums=True)
|
|
@@ -34,6 +34,10 @@ from dataclasses import dataclass
|
|
|
34
34
|
from pathlib import Path
|
|
35
35
|
from typing import Iterable, Optional
|
|
36
36
|
|
|
37
|
+
from .user_response_values import ( # noqa: F401 — 재노출(값 타입은 leaf 소유)
|
|
38
|
+
UserPlanDecision,
|
|
39
|
+
UserResponseEntry,
|
|
40
|
+
)
|
|
37
41
|
from .final_report_paths import final_report_data_path
|
|
38
42
|
from .json_boundary import JsonBoundaryError, load_owned_object
|
|
39
43
|
from .report_html.view_models.implementation_planning import (
|
|
@@ -1077,28 +1081,6 @@ def _slugify(text: str) -> str:
|
|
|
1077
1081
|
# templates/reports/report.js implements the byte-identical client side).
|
|
1078
1082
|
# --------------------------------------------------------------------------- #
|
|
1079
1083
|
|
|
1080
|
-
@dataclass(frozen=True)
|
|
1081
|
-
class UserResponseEntry:
|
|
1082
|
-
response_id: str
|
|
1083
|
-
kind: str
|
|
1084
|
-
value: str
|
|
1085
|
-
rationale: Optional[str] = None
|
|
1086
|
-
disposition: str = "answer"
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
@dataclass(frozen=True)
|
|
1090
|
-
class UserPlanDecision:
|
|
1091
|
-
"""HTML 계획 결정 위젯의 Export 결과.
|
|
1092
|
-
|
|
1093
|
-
``status`` 가 승인이 아니면 ``reason`` 이 필수다 — 사유 없는 반려는 다음
|
|
1094
|
-
run 이 무엇을 고쳐야 하는지 알 수 없어 되돌아올 수밖에 없다.
|
|
1095
|
-
``implementation_option`` 이 빈 문자열이면 라인을 생략한다 (소비 측은
|
|
1096
|
-
Recommended Option 폴백)."""
|
|
1097
|
-
status: str
|
|
1098
|
-
implementation_option: str = ""
|
|
1099
|
-
reason: str = ""
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
1084
|
@dataclass(frozen=True)
|
|
1103
1085
|
class UserDirectionSelection:
|
|
1104
1086
|
option_id: str
|
|
@@ -19,8 +19,21 @@ from okstra_project import (
|
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
_CLI_EPILOG = r"""Usage:
|
|
23
|
+
okstra resolve-task-key <task-id> [--task-group <g>] [--project-root <dir>] [--cwd <dir>] [--json]
|
|
24
|
+
|
|
25
|
+
Output: JSON { ok, projectRoot, matches: [ { taskKey, taskGroup, taskId,
|
|
26
|
+
taskGroupPathSegment, taskIdPathSegment, taskManifestPath, ... } ] }.
|
|
27
|
+
matches.length 0 = not found, 1 = unambiguous, N = ambiguous (caller asks).
|
|
28
|
+
This is read-only; it never mutates task state.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
|
|
22
32
|
def main(argv: list[str] | None = None) -> int:
|
|
23
33
|
parser = argparse.ArgumentParser(
|
|
34
|
+
prog="okstra resolve-task-key",
|
|
35
|
+
epilog=_CLI_EPILOG,
|
|
36
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
24
37
|
description="Resolve a bare token (task-id or task-group) to candidate "
|
|
25
38
|
"task-keys from the catalog."
|
|
26
39
|
)
|
|
@@ -139,8 +139,21 @@ def build_rollup(project_root: Path, task_group: str | None) -> dict:
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
|
|
142
|
+
_CLI_EPILOG = r"""Usage:
|
|
143
|
+
okstra rollup [--task-group <group>] [--project-root <dir>] [--cwd <dir>]
|
|
144
|
+
|
|
145
|
+
Read-only. Prints a JSON roll-up of every catalog task (optionally scoped to one
|
|
146
|
+
task-group): per-task run count, elapsed time (raw ms), error count, and the
|
|
147
|
+
latest report path, plus group-level totals and status/category/phase tallies.
|
|
148
|
+
With no --task-group it covers the whole project catalog. Time is raw ms; the
|
|
149
|
+
caller formats HH:MM:SS and synthesizes the prose digest from the report files.
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
|
|
142
153
|
def main(argv: list[str] | None = None) -> int:
|
|
143
154
|
parser = argparse.ArgumentParser(
|
|
155
|
+
epilog=_CLI_EPILOG,
|
|
156
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
144
157
|
prog="okstra rollup",
|
|
145
158
|
description="Roll up run results across a task-group's tasks (raw ms).")
|
|
146
159
|
parser.add_argument("--task-group", default="",
|