okstra 0.186.7 → 0.188.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli-registry.d.mts +88 -1
- package/dist/cli-registry.mjs +68 -111
- package/dist/cli-registry.mjs.map +1 -1
- package/dist/commands/execute/render-bundle.mjs +0 -1
- package/dist/commands/execute/render-bundle.mjs.map +1 -1
- package/dist/commands/execute/run.mjs +8 -3
- package/dist/commands/execute/run.mjs.map +1 -1
- package/dist/commands/lifecycle/check-project.mjs +1 -14
- package/dist/commands/lifecycle/check-project.mjs.map +1 -1
- package/dist/commands/lifecycle/config.mjs +38 -40
- package/dist/commands/lifecycle/config.mjs.map +1 -1
- package/dist/commands/lifecycle/doctor.d.mts +22 -7
- package/dist/commands/lifecycle/doctor.mjs +77 -49
- package/dist/commands/lifecycle/doctor.mjs.map +1 -1
- package/dist/commands/lifecycle/install.d.mts +12 -10
- package/dist/commands/lifecycle/install.mjs +107 -40
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/dist/commands/lifecycle/paths.mjs +8 -3
- package/dist/commands/lifecycle/paths.mjs.map +1 -1
- package/dist/commands/lifecycle/preflight.mjs +2 -1
- package/dist/commands/lifecycle/preflight.mjs.map +1 -1
- package/dist/commands/lifecycle/setup.mjs +22 -36
- package/dist/commands/lifecycle/setup.mjs.map +1 -1
- package/dist/commands/lifecycle/uninstall.d.mts +4 -2
- package/dist/commands/lifecycle/uninstall.mjs +59 -15
- package/dist/commands/lifecycle/uninstall.mjs.map +1 -1
- package/dist/commands/memory/memory.mjs +7 -1
- package/dist/commands/memory/memory.mjs.map +1 -1
- package/dist/lib/helper-scripts.d.mts +1 -1
- package/dist/lib/helper-scripts.mjs +10 -18
- package/dist/lib/helper-scripts.mjs.map +1 -1
- package/dist/lib/host-config.d.mts +72 -0
- package/dist/lib/host-config.mjs +404 -0
- package/dist/lib/host-config.mjs.map +1 -0
- package/dist/lib/host-registry-client.d.mts +2 -2
- package/dist/lib/host-registry-client.mjs +0 -3
- package/dist/lib/host-registry-client.mjs.map +1 -1
- package/dist/lib/install-assets.d.mts +1 -0
- package/dist/lib/install-assets.mjs +4 -0
- package/dist/lib/install-assets.mjs.map +1 -1
- package/dist/lib/proc.d.mts +2 -0
- package/dist/lib/proc.mjs +12 -0
- package/dist/lib/proc.mjs.map +1 -1
- package/dist/lib/python-command.d.mts +2 -0
- package/dist/lib/python-command.mjs +52 -0
- package/dist/lib/python-command.mjs.map +1 -0
- package/dist/lib/python-helper.d.mts +2 -5
- package/dist/lib/python-helper.mjs +3 -52
- package/dist/lib/python-helper.mjs.map +1 -1
- package/dist/lib/runtime-payload.d.mts +23 -0
- package/dist/lib/runtime-payload.mjs +57 -0
- package/dist/lib/runtime-payload.mjs.map +1 -0
- package/dist/lib/types.d.mts +24 -13
- package/docs/architecture/storage-model.md +21 -5
- package/docs/architecture.md +39 -38
- package/docs/cli.md +55 -76
- package/docs/coding-rules.md +295 -0
- package/docs/container.md +10 -36
- package/docs/contributor-change-matrix.md +1 -1
- package/docs/for-ai/skills/okstra-code-review.md +0 -1
- package/docs/for-ai/skills/okstra-container-build.md +8 -41
- package/docs/for-ai/skills/okstra-inspect.md +4 -4
- package/docs/for-ai/skills/okstra-manager.md +2 -2
- package/docs/for-ai/skills/okstra-rollup.md +0 -1
- package/docs/for-ai/skills/okstra-run.md +3 -3
- package/docs/for-ai/skills/okstra-user-response.md +0 -1
- package/docs/performance-improvement-plan-v2.md +1 -1
- package/docs/project-structure-overview.md +62 -62
- package/docs/task-process/README.md +3 -3
- package/docs/task-process/common-flow.md +1 -1
- package/docs/task-process/error-analysis.md +3 -3
- package/docs/task-process/implementation-planning.md +3 -1
- package/docs/task-process/release-handoff.md +1 -1
- package/package.json +3 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/claude-worker.md +6 -11
- package/runtime/agents/workers/report-writer-worker.md +1 -1
- package/runtime/bin/lib/okstra/cli.sh +4 -0
- package/runtime/bin/lib/okstra/globals.sh +2 -0
- package/runtime/bin/lib/okstra/interactive.sh +26 -173
- package/runtime/bin/lib/okstra/project-resolver.sh +23 -61
- package/runtime/bin/lib/okstra/usage.sh +3 -3
- package/runtime/bin/okstra-compact-reminder.sh +1 -5
- package/runtime/bin/okstra-error-log.py +19 -2
- package/runtime/bin/okstra-import-check.py +26 -0
- package/runtime/bin/okstra-inject-report-index.py +5 -4
- package/runtime/bin/okstra-provider-exec.py +22 -17
- package/runtime/bin/okstra-render-final-report.py +16 -6
- package/runtime/bin/okstra-render-report-views.py +47 -22
- package/runtime/bin/okstra-report-translate.py +30 -18
- package/runtime/bin/okstra-spawn-followups.py +4 -0
- package/runtime/bin/okstra-token-usage.py +3 -0
- package/runtime/bin/okstra.sh +4 -2
- package/runtime/bin/okstra_bootstrap.py +58 -0
- package/runtime/prompts/coding-preflight/overview.md +1 -1
- package/runtime/prompts/duties/planning-worker.md +1 -1
- package/runtime/prompts/launch.template.md +35 -9
- package/runtime/prompts/lead/adapters/cmux.md +3 -3
- package/runtime/prompts/lead/convergence.md +99 -88
- package/runtime/prompts/lead/okstra-lead-contract.md +63 -12
- package/runtime/prompts/lead/plan-body-verification.md +65 -46
- package/runtime/prompts/lead/report-writer.md +35 -5
- package/runtime/prompts/lead/team-contract.md +4 -1
- package/runtime/prompts/profiles/_clarification-recommendation.md +2 -1
- package/runtime/prompts/profiles/_coding-conventions-preflight.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +3 -3
- package/runtime/prompts/profiles/_coverage-critic.md +1 -1
- package/runtime/prompts/profiles/_implementation-deliverable.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +3 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +16 -2
- package/runtime/prompts/profiles/error-analysis.md +4 -3
- package/runtime/prompts/profiles/final-verification.md +2 -2
- package/runtime/prompts/profiles/implementation-planning.md +22 -17
- package/runtime/prompts/profiles/implementation.md +3 -2
- package/runtime/prompts/profiles/requirements-discovery.md +2 -1
- package/runtime/prompts/wizard/prompts.ko.json +29 -8
- package/runtime/python/okstra_ctl/__init__.py +6 -27
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -5
- package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +21 -2
- package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +3 -12
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +63 -22
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +20 -21
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +37 -20
- package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +86 -14
- package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +12 -12
- package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +4 -7
- package/runtime/python/okstra_ctl/agent/__init__.py +1 -0
- package/runtime/python/okstra_ctl/{agent_activity.py → agent/activity.py} +16 -2
- package/runtime/python/okstra_ctl/{agent_invocation.py → agent/invocation.py} +34 -5
- package/runtime/python/okstra_ctl/agent/prompt_cli/__init__.py +19 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/__main__.py +11 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +228 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/dynamic_verifier.py +155 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/emit.py +66 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/inputs.py +138 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +605 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/results.py +197 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +107 -0
- package/runtime/python/okstra_ctl/analysis_packet.py +47 -4
- package/runtime/python/okstra_ctl/approval_decisions.py +287 -10
- package/runtime/python/okstra_ctl/assignment_resolver.py +0 -12
- package/runtime/python/okstra_ctl/attempt_evidence.py +12 -24
- package/runtime/python/okstra_ctl/blocking_checks.py +251 -0
- package/runtime/python/okstra_ctl/brief_frontmatter.py +0 -7
- package/runtime/python/okstra_ctl/clarification_items/__init__.py +102 -0
- package/runtime/python/okstra_ctl/clarification_items/carry.py +224 -0
- package/runtime/python/okstra_ctl/clarification_items/dispositions.py +135 -0
- package/runtime/python/okstra_ctl/clarification_items/parsing.py +253 -0
- package/runtime/python/okstra_ctl/clarification_items/rows.py +115 -0
- package/runtime/python/okstra_ctl/clarification_items/scan.py +215 -0
- package/runtime/python/okstra_ctl/clarification_items/sidecars.py +211 -0
- package/runtime/python/okstra_ctl/cmux.py +38 -31
- package/runtime/python/okstra_ctl/code_review_target.py +163 -1
- package/runtime/python/okstra_ctl/conformance.py +23 -0
- package/runtime/python/okstra_ctl/container.py +38 -421
- package/runtime/python/okstra_ctl/context_cost.py +32 -4
- package/runtime/python/okstra_ctl/contract_graph_cli.py +7 -0
- package/runtime/python/okstra_ctl/convergence.py +107 -16
- package/runtime/python/okstra_ctl/convergence_critic_prompt.py +345 -0
- package/runtime/python/okstra_ctl/convergence_engine.py +382 -70
- package/runtime/python/okstra_ctl/convergence_store.py +5 -29
- package/runtime/python/okstra_ctl/design_prep.py +108 -12
- package/runtime/python/okstra_ctl/design_snapshot.py +11 -1
- package/runtime/python/okstra_ctl/design_surfaces.py +29 -2
- package/runtime/python/okstra_ctl/dispatch_core.py +236 -49
- package/runtime/python/okstra_ctl/dispatch_state.py +417 -41
- package/runtime/python/okstra_ctl/doctor_cli.py +48 -0
- package/runtime/python/okstra_ctl/domain/worker_exec.py +10 -5
- package/runtime/python/okstra_ctl/domain/worker_presentation.py +28 -1
- package/runtime/python/okstra_ctl/domain/worker_stream.py +52 -21
- package/runtime/python/okstra_ctl/domain/write_policy.py +219 -0
- package/runtime/python/okstra_ctl/entrypoints/hosts.py +9 -2
- package/runtime/python/okstra_ctl/error_log_core.py +1 -1
- package/runtime/python/okstra_ctl/error_report.py +14 -0
- package/runtime/python/okstra_ctl/error_zip.py +18 -2
- package/runtime/python/okstra_ctl/exact_coverage.py +5 -0
- package/runtime/python/okstra_ctl/execution_identity.py +100 -7
- package/runtime/python/okstra_ctl/execution_manifest.py +67 -20
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +90 -8
- package/runtime/python/okstra_ctl/final_report_paths.py +17 -0
- package/runtime/python/okstra_ctl/final_report_schema.py +319 -17
- package/runtime/python/okstra_ctl/git_reconcile.py +22 -2
- package/runtime/python/okstra_ctl/handoff.py +24 -1
- package/runtime/python/okstra_ctl/ids.py +6 -16
- package/runtime/python/okstra_ctl/implementation_direction.py +142 -33
- package/runtime/python/okstra_ctl/implementation_options.py +32 -13
- package/runtime/python/okstra_ctl/implementation_outcome.py +5 -2
- package/runtime/python/okstra_ctl/improvement_lenses.py +0 -14
- package/runtime/python/okstra_ctl/incremental_carry.py +69 -8
- package/runtime/python/okstra_ctl/incremental_scope.py +173 -12
- package/runtime/python/okstra_ctl/index.py +2 -2
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +48 -8
- package/runtime/python/okstra_ctl/interactive_cli.py +223 -0
- package/runtime/python/okstra_ctl/json_boundary.py +10 -0
- package/runtime/python/okstra_ctl/listing.py +0 -91
- package/runtime/python/okstra_ctl/locks.py +5 -19
- package/runtime/python/okstra_ctl/log_report.py +14 -0
- package/runtime/python/okstra_ctl/manager_cli.py +22 -3
- package/runtime/python/okstra_ctl/manager_launch.py +4 -8
- package/runtime/python/okstra_ctl/material.py +2 -2
- package/runtime/python/okstra_ctl/migrate.py +23 -1
- package/runtime/python/okstra_ctl/model_cli.py +19 -5
- package/runtime/python/okstra_ctl/model_discovery.py +46 -47
- package/runtime/python/okstra_ctl/model_io/__init__.py +1 -0
- package/runtime/python/okstra_ctl/model_io/lines.py +163 -0
- package/runtime/python/okstra_ctl/model_io/references.py +370 -0
- package/runtime/python/okstra_ctl/model_io/renderers.py +498 -0
- package/runtime/python/okstra_ctl/model_io_cli.py +30 -945
- package/runtime/python/okstra_ctl/model_pool.py +10 -6
- package/runtime/python/okstra_ctl/models.py +8 -8
- package/runtime/python/okstra_ctl/mutation_recovery.py +5 -63
- package/runtime/python/okstra_ctl/next_phase.py +121 -69
- package/runtime/python/okstra_ctl/pane_reclaim.py +23 -0
- package/runtime/python/okstra_ctl/pane_title.py +11 -8
- package/runtime/python/okstra_ctl/path_hints.py +36 -11
- package/runtime/python/okstra_ctl/paths.py +76 -8
- package/runtime/python/okstra_ctl/plan_items.py +132 -16
- package/runtime/python/okstra_ctl/plan_items_cli.py +486 -36
- package/runtime/python/okstra_ctl/plan_run_root.py +1 -1
- package/runtime/python/okstra_ctl/plan_validate_cli.py +51 -0
- package/runtime/python/okstra_ctl/plan_verify_cli.py +80 -0
- package/runtime/python/okstra_ctl/prepare_error.py +20 -0
- package/runtime/python/okstra_ctl/prior_planning.py +157 -0
- package/runtime/python/okstra_ctl/profile_show.py +18 -1
- package/runtime/python/okstra_ctl/project_setup_cli.py +140 -0
- package/runtime/python/okstra_ctl/recap.py +22 -1
- package/runtime/python/okstra_ctl/reconcile.py +84 -0
- package/runtime/python/okstra_ctl/registry/host_registry.py +18 -1
- package/runtime/python/okstra_ctl/render.py +98 -32
- package/runtime/python/okstra_ctl/render_final_report.py +4 -8
- package/runtime/python/okstra_ctl/report_assembly.py +297 -7
- package/runtime/python/okstra_ctl/report_contract.py +30 -7
- package/runtime/python/okstra_ctl/report_finalize.py +213 -16
- package/runtime/python/okstra_ctl/report_html/common.py +2 -2
- package/runtime/python/okstra_ctl/report_html/render.py +8 -12
- package/runtime/python/okstra_ctl/report_language.py +8 -4
- package/runtime/python/okstra_ctl/report_narrative.py +220 -34
- package/runtime/python/okstra_ctl/report_projections.py +8 -2
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +393 -1
- package/runtime/python/okstra_ctl/report_translation.py +2 -35
- package/runtime/python/okstra_ctl/report_view_artifacts.py +42 -2
- package/runtime/python/okstra_ctl/report_views.py +4 -22
- package/runtime/python/okstra_ctl/resolve_task_key.py +13 -0
- package/runtime/python/okstra_ctl/rollup.py +13 -0
- package/runtime/python/okstra_ctl/run.py +639 -138
- package/runtime/python/okstra_ctl/run_audit.py +13 -0
- package/runtime/python/okstra_ctl/run_index_row.py +0 -12
- package/runtime/python/okstra_ctl/seeding.py +21 -11
- package/runtime/python/okstra_ctl/sequence.py +1 -1
- package/runtime/python/okstra_ctl/session.py +64 -14
- package/runtime/python/okstra_ctl/set_work_status.py +18 -0
- package/runtime/python/okstra_ctl/stage_integrate.py +15 -1
- package/runtime/python/okstra_ctl/stage_ledger.py +1 -1
- package/runtime/python/okstra_ctl/stage_map.py +57 -11
- package/runtime/python/okstra_ctl/stage_map_cli.py +83 -0
- package/runtime/python/okstra_ctl/stage_map_view.py +65 -0
- package/runtime/python/okstra_ctl/stage_targets.py +3 -12
- package/runtime/python/okstra_ctl/task_list_cli.py +138 -0
- package/runtime/python/okstra_ctl/task_show_cli.py +66 -0
- package/runtime/python/okstra_ctl/task_target.py +4 -16
- package/runtime/python/okstra_ctl/team.py +49 -2
- package/runtime/python/okstra_ctl/time_report.py +17 -2
- package/runtime/python/okstra_ctl/usage_report.py +11 -0
- package/runtime/python/okstra_ctl/user_response.py +55 -218
- package/runtime/python/okstra_ctl/user_response_values.py +242 -0
- package/runtime/python/okstra_ctl/validation_contract.py +3 -0
- package/runtime/python/okstra_ctl/verdict_blocks.py +28 -8
- package/runtime/python/okstra_ctl/verification_target.py +68 -0
- package/runtime/python/okstra_ctl/wizard.py +457 -92
- package/runtime/python/okstra_ctl/worker_artifacts.py +75 -16
- package/runtime/python/okstra_ctl/worker_audit_check.py +22 -0
- package/runtime/python/okstra_ctl/worker_dispatch.py +21 -0
- package/runtime/python/okstra_ctl/worker_liveness.py +33 -0
- package/runtime/python/okstra_ctl/worker_prompt_body.py +15 -2
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +98 -7
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +24 -2
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +18 -3
- package/runtime/python/okstra_ctl/worker_request.py +2 -1
- package/runtime/python/okstra_ctl/worker_runner.py +58 -17
- package/runtime/python/okstra_ctl/worker_state.py +16 -1
- package/runtime/python/okstra_ctl/workflow.py +18 -1
- package/runtime/python/okstra_ctl/worktree/__init__.py +92 -0
- package/runtime/python/okstra_ctl/worktree/cleanliness.py +89 -0
- package/runtime/python/okstra_ctl/worktree/decisions.py +127 -0
- package/runtime/python/okstra_ctl/worktree/git_ops.py +165 -0
- package/runtime/python/okstra_ctl/worktree/linking.py +249 -0
- package/runtime/python/okstra_ctl/worktree/naming.py +91 -0
- package/runtime/python/okstra_ctl/worktree/provision.py +385 -0
- package/runtime/python/okstra_ctl/worktree/sync_config.py +181 -0
- package/runtime/python/okstra_ctl/worktree_cli.py +75 -0
- package/runtime/python/okstra_ctl/worktree_lookup_cli.py +39 -0
- package/runtime/python/okstra_ctl/worktree_registry.py +7 -0
- package/runtime/python/okstra_ctl/worktree_status_cli.py +53 -0
- package/runtime/python/okstra_ctl/write_policy.py +90 -213
- package/runtime/python/okstra_project/__init__.py +0 -4
- package/runtime/python/okstra_project/dirs.py +2 -2
- package/runtime/python/okstra_project/phase_pointer.py +84 -0
- package/runtime/python/okstra_project/slug.py +24 -0
- package/runtime/python/okstra_project/state.py +22 -230
- package/runtime/python/okstra_token_usage/antigravity.py +50 -12
- package/runtime/python/okstra_token_usage/claude.py +9 -1
- package/runtime/python/okstra_token_usage/cli.py +3 -1
- package/runtime/python/okstra_token_usage/collect.py +171 -36
- package/runtime/python/okstra_token_usage/cursor.py +2 -0
- package/runtime/python/okstra_token_usage/grok.py +1 -5
- package/runtime/python/okstra_token_usage/paths.py +26 -0
- package/runtime/python/okstra_token_usage/pricing.py +23 -8
- package/runtime/schemas/convergence-critic-results-v1.0.schema.json +5 -0
- package/runtime/schemas/execution-manifest-v2.schema.json +10 -10
- package/runtime/schemas/final-report-v2.0.schema.json +9 -26
- package/runtime/schemas/final-report-v3.0.schema.json +173 -41
- package/runtime/schemas/report-narrative-v3.0.schema.json +3 -2
- package/runtime/skills/okstra-brief-gen/SKILL.md +35 -2
- package/runtime/skills/okstra-container-build/SKILL.md +16 -47
- package/runtime/skills/okstra-inspect/facets/history.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +7 -6
- package/runtime/skills/okstra-pr-gen/SKILL.md +1 -1
- package/runtime/skills/okstra-run/SKILL.md +7 -5
- package/runtime/templates/report-writer-prompt-preamble.md +3 -1
- package/runtime/templates/reports/brief.template.md +6 -2
- package/runtime/templates/reports/error-analysis-input.template.md +2 -0
- package/runtime/templates/reports/final-verification-input.template.md +2 -0
- package/runtime/templates/reports/implementation-input.template.md +7 -1
- package/runtime/templates/reports/implementation-planning-input.template.md +4 -0
- package/runtime/templates/reports/quick-input.template.md +2 -0
- package/runtime/templates/reports/release-handoff-input.template.md +6 -1
- package/runtime/templates/reports/report.js +20 -3
- package/runtime/templates/reports/schedule.template.md +2 -0
- package/runtime/templates/reports/settings.template.json +0 -10
- package/runtime/templates/reports/task-brief.template.md +3 -0
- package/runtime/templates/reports/user-response.template.md +7 -3
- package/runtime/validators/checks/fixtures-01.py +57 -0
- package/runtime/validators/checks/fixtures-02.py +565 -0
- package/runtime/validators/checks/runners-01.py +108 -0
- package/runtime/validators/checks/validate-assets-01.py +60 -0
- package/runtime/validators/checks/validate-prompt-metadata-01.py +261 -0
- package/runtime/validators/checks/validate-tasks-01.py +46 -0
- package/runtime/validators/checks/validate-tasks-02.py +85 -0
- package/runtime/validators/checks/validate-tasks-03.py +61 -0
- package/runtime/validators/checks/validate-tasks-04.py +118 -0
- package/runtime/validators/forbidden_actions.py +73 -3
- package/runtime/validators/lib/common.sh +5 -0
- package/runtime/validators/lib/fixtures.sh +7 -591
- package/runtime/validators/lib/paths.sh +13 -0
- package/runtime/validators/lib/runners.sh +6 -104
- package/runtime/validators/lib/summary.sh +1 -1
- package/runtime/validators/lib/validate-assets.sh +6 -56
- package/runtime/validators/lib/validate-prompt-metadata.sh +6 -257
- package/runtime/validators/lib/validate-tasks.sh +9 -294
- package/runtime/validators/validate-implementation-plan-stages.py +4 -4
- package/runtime/validators/validate-run.py +1363 -2643
- package/runtime/validators/validate-workflow.sh +56 -16
- package/runtime/validators/validate_improvement_report.py +2 -1
- package/runtime/validators/validate_session_conformance.py +295 -49
- package/dist/commands/execute/agent-prompt.d.mts +0 -1
- package/dist/commands/execute/agent-prompt.mjs +0 -24
- package/dist/commands/execute/agent-prompt.mjs.map +0 -1
- package/dist/commands/execute/codex-dispatch.d.mts +0 -3
- package/dist/commands/execute/codex-dispatch.mjs +0 -6
- package/dist/commands/execute/codex-dispatch.mjs.map +0 -1
- package/dist/commands/execute/codex-run.d.mts +0 -3
- package/dist/commands/execute/codex-run.mjs +0 -62
- package/dist/commands/execute/codex-run.mjs.map +0 -1
- package/dist/commands/execute/convergence.d.mts +0 -1
- package/dist/commands/execute/convergence.mjs +0 -38
- package/dist/commands/execute/convergence.mjs.map +0 -1
- package/dist/commands/execute/error-log.d.mts +0 -1
- package/dist/commands/execute/error-log.mjs +0 -18
- package/dist/commands/execute/error-log.mjs.map +0 -1
- package/dist/commands/execute/git-reconcile.d.mts +0 -1
- package/dist/commands/execute/git-reconcile.mjs +0 -30
- package/dist/commands/execute/git-reconcile.mjs.map +0 -1
- package/dist/commands/execute/handoff.d.mts +0 -1
- package/dist/commands/execute/handoff.mjs +0 -31
- package/dist/commands/execute/handoff.mjs.map +0 -1
- package/dist/commands/execute/incremental-carry.d.mts +0 -1
- package/dist/commands/execute/incremental-carry.mjs +0 -20
- package/dist/commands/execute/incremental-carry.mjs.map +0 -1
- package/dist/commands/execute/incremental-scope.d.mts +0 -1
- package/dist/commands/execute/incremental-scope.mjs +0 -29
- package/dist/commands/execute/incremental-scope.mjs.map +0 -1
- package/dist/commands/execute/integrate-stages.d.mts +0 -1
- package/dist/commands/execute/integrate-stages.mjs +0 -24
- package/dist/commands/execute/integrate-stages.mjs.map +0 -1
- package/dist/commands/execute/pane-title.d.mts +0 -1
- package/dist/commands/execute/pane-title.mjs +0 -20
- package/dist/commands/execute/pane-title.mjs.map +0 -1
- package/dist/commands/execute/plan-items.d.mts +0 -1
- package/dist/commands/execute/plan-items.mjs +0 -9
- package/dist/commands/execute/plan-items.mjs.map +0 -1
- package/dist/commands/execute/plan-validate.d.mts +0 -1
- package/dist/commands/execute/plan-validate.mjs +0 -68
- package/dist/commands/execute/plan-validate.mjs.map +0 -1
- package/dist/commands/execute/plan-verify.d.mts +0 -1
- package/dist/commands/execute/plan-verify.mjs +0 -43
- package/dist/commands/execute/plan-verify.mjs.map +0 -1
- package/dist/commands/execute/spawn-followups.d.mts +0 -1
- package/dist/commands/execute/spawn-followups.mjs +0 -22
- package/dist/commands/execute/spawn-followups.mjs.map +0 -1
- package/dist/commands/execute/team.d.mts +0 -3
- package/dist/commands/execute/team.mjs +0 -66
- package/dist/commands/execute/team.mjs.map +0 -1
- package/dist/commands/execute/token-usage.d.mts +0 -1
- package/dist/commands/execute/token-usage.mjs +0 -19
- package/dist/commands/execute/token-usage.mjs.map +0 -1
- package/dist/commands/execute/worker-audit-check.d.mts +0 -1
- package/dist/commands/execute/worker-audit-check.mjs +0 -34
- package/dist/commands/execute/worker-audit-check.mjs.map +0 -1
- package/dist/commands/execute/worker-dispatch.d.mts +0 -7
- package/dist/commands/execute/worker-dispatch.mjs +0 -64
- package/dist/commands/execute/worker-dispatch.mjs.map +0 -1
- package/dist/commands/execute/worker-state.d.mts +0 -1
- package/dist/commands/execute/worker-state.mjs +0 -28
- package/dist/commands/execute/worker-state.mjs.map +0 -1
- package/dist/commands/execute/worktree-lookup.d.mts +0 -1
- package/dist/commands/execute/worktree-lookup.mjs +0 -92
- package/dist/commands/execute/worktree-lookup.mjs.map +0 -1
- package/dist/commands/execute/worktree-status.d.mts +0 -1
- package/dist/commands/execute/worktree-status.mjs +0 -121
- package/dist/commands/execute/worktree-status.mjs.map +0 -1
- package/dist/commands/inspect/code-review.d.mts +0 -1
- package/dist/commands/inspect/code-review.mjs +0 -32
- package/dist/commands/inspect/code-review.mjs.map +0 -1
- package/dist/commands/inspect/container.d.mts +0 -1
- package/dist/commands/inspect/container.mjs +0 -25
- package/dist/commands/inspect/container.mjs.map +0 -1
- package/dist/commands/inspect/context-cost.d.mts +0 -1
- package/dist/commands/inspect/context-cost.mjs +0 -25
- package/dist/commands/inspect/context-cost.mjs.map +0 -1
- package/dist/commands/inspect/design-prep.d.mts +0 -1
- package/dist/commands/inspect/design-prep.mjs +0 -22
- package/dist/commands/inspect/design-prep.mjs.map +0 -1
- package/dist/commands/inspect/error-report.d.mts +0 -1
- package/dist/commands/inspect/error-report.mjs +0 -25
- package/dist/commands/inspect/error-report.mjs.map +0 -1
- package/dist/commands/inspect/error-zip.d.mts +0 -1
- package/dist/commands/inspect/error-zip.mjs +0 -24
- package/dist/commands/inspect/error-zip.mjs.map +0 -1
- package/dist/commands/inspect/log-report.d.mts +0 -1
- package/dist/commands/inspect/log-report.mjs +0 -26
- package/dist/commands/inspect/log-report.mjs.map +0 -1
- package/dist/commands/inspect/model-io.d.mts +0 -1
- package/dist/commands/inspect/model-io.mjs +0 -25
- package/dist/commands/inspect/model-io.mjs.map +0 -1
- package/dist/commands/inspect/profile-show.d.mts +0 -1
- package/dist/commands/inspect/profile-show.mjs +0 -28
- package/dist/commands/inspect/profile-show.mjs.map +0 -1
- package/dist/commands/inspect/recap.d.mts +0 -1
- package/dist/commands/inspect/recap.mjs +0 -30
- package/dist/commands/inspect/recap.mjs.map +0 -1
- package/dist/commands/inspect/resolve-task-key.d.mts +0 -1
- package/dist/commands/inspect/resolve-task-key.mjs +0 -24
- package/dist/commands/inspect/resolve-task-key.mjs.map +0 -1
- package/dist/commands/inspect/rollup.d.mts +0 -1
- package/dist/commands/inspect/rollup.mjs +0 -25
- package/dist/commands/inspect/rollup.mjs.map +0 -1
- package/dist/commands/inspect/run-audit.d.mts +0 -1
- package/dist/commands/inspect/run-audit.mjs +0 -25
- package/dist/commands/inspect/run-audit.mjs.map +0 -1
- package/dist/commands/inspect/set-work-status.d.mts +0 -1
- package/dist/commands/inspect/set-work-status.mjs +0 -29
- package/dist/commands/inspect/set-work-status.mjs.map +0 -1
- package/dist/commands/inspect/stage-map.d.mts +0 -1
- package/dist/commands/inspect/stage-map.mjs +0 -131
- package/dist/commands/inspect/stage-map.mjs.map +0 -1
- package/dist/commands/inspect/task-list.d.mts +0 -1
- package/dist/commands/inspect/task-list.mjs +0 -149
- package/dist/commands/inspect/task-list.mjs.map +0 -1
- package/dist/commands/inspect/task-show.d.mts +0 -1
- package/dist/commands/inspect/task-show.mjs +0 -108
- package/dist/commands/inspect/task-show.mjs.map +0 -1
- package/dist/commands/inspect/time-report.d.mts +0 -1
- package/dist/commands/inspect/time-report.mjs +0 -24
- package/dist/commands/inspect/time-report.mjs.map +0 -1
- package/dist/commands/inspect/usage-report.d.mts +0 -1
- package/dist/commands/inspect/usage-report.mjs +0 -23
- package/dist/commands/inspect/usage-report.mjs.map +0 -1
- package/dist/commands/inspect/user-response.d.mts +0 -1
- package/dist/commands/inspect/user-response.mjs +0 -35
- package/dist/commands/inspect/user-response.mjs.map +0 -1
- package/dist/commands/inspect/worker-liveness.d.mts +0 -1
- package/dist/commands/inspect/worker-liveness.mjs +0 -45
- package/dist/commands/inspect/worker-liveness.mjs.map +0 -1
- package/dist/commands/lifecycle/contract-check.d.mts +0 -1
- package/dist/commands/lifecycle/contract-check.mjs +0 -18
- package/dist/commands/lifecycle/contract-check.mjs.map +0 -1
- package/dist/commands/lifecycle/migrate.d.mts +0 -1
- package/dist/commands/lifecycle/migrate.mjs +0 -30
- package/dist/commands/lifecycle/migrate.mjs.map +0 -1
- package/dist/commands/lifecycle/model.d.mts +0 -1
- package/dist/commands/lifecycle/model.mjs +0 -22
- package/dist/commands/lifecycle/model.mjs.map +0 -1
- package/dist/commands/manager.d.mts +0 -3
- package/dist/commands/manager.mjs +0 -50
- package/dist/commands/manager.mjs.map +0 -1
- package/dist/commands/report/agent-activity.d.mts +0 -1
- package/dist/commands/report/agent-activity.mjs +0 -20
- package/dist/commands/report/agent-activity.mjs.map +0 -1
- package/dist/commands/report/approval-decision.d.mts +0 -1
- package/dist/commands/report/approval-decision.mjs +0 -21
- package/dist/commands/report/approval-decision.mjs.map +0 -1
- package/dist/commands/report/design-snapshot.d.mts +0 -1
- package/dist/commands/report/design-snapshot.mjs +0 -19
- package/dist/commands/report/design-snapshot.mjs.map +0 -1
- package/dist/commands/report/finalize.d.mts +0 -4
- package/dist/commands/report/finalize.mjs +0 -64
- package/dist/commands/report/finalize.mjs.map +0 -1
- package/dist/commands/report/inject-report-index.d.mts +0 -1
- package/dist/commands/report/inject-report-index.mjs +0 -21
- package/dist/commands/report/inject-report-index.mjs.map +0 -1
- package/dist/commands/report/render-final-report.d.mts +0 -1
- package/dist/commands/report/render-final-report.mjs +0 -23
- package/dist/commands/report/render-final-report.mjs.map +0 -1
- package/dist/commands/report/render-views.d.mts +0 -1
- package/dist/commands/report/render-views.mjs +0 -27
- package/dist/commands/report/render-views.mjs.map +0 -1
- package/dist/commands/report/translate.d.mts +0 -1
- package/dist/commands/report/translate.mjs +0 -33
- package/dist/commands/report/translate.mjs.map +0 -1
- package/runtime/bin/lib/okstra/tmux-pane.sh +0 -40
- package/runtime/bin/lib/okstra-ctl/cmd-batch.sh +0 -59
- package/runtime/bin/lib/okstra-ctl/cmd-list.sh +0 -35
- package/runtime/bin/lib/okstra-ctl/cmd-open.sh +0 -36
- package/runtime/bin/lib/okstra-ctl/cmd-projects.sh +0 -26
- package/runtime/bin/lib/okstra-ctl/cmd-reconcile.sh +0 -29
- package/runtime/bin/lib/okstra-ctl/cmd-reindex.sh +0 -38
- package/runtime/bin/lib/okstra-ctl/cmd-rerun.sh +0 -345
- package/runtime/bin/lib/okstra-ctl/cmd-show.sh +0 -27
- package/runtime/bin/lib/okstra-ctl/cmd-tail.sh +0 -92
- package/runtime/bin/lib/okstra-ctl/main.sh +0 -41
- package/runtime/bin/lib/okstra-ctl/prepare.sh +0 -31
- package/runtime/bin/lib/okstra-ctl/usage.sh +0 -23
- package/runtime/bin/okstra-central.sh +0 -152
- package/runtime/bin/okstra-incremental-carry.py +0 -10
- package/runtime/bin/okstra-incremental-scope.py +0 -10
- package/runtime/bin/okstra-team-reconcile.sh +0 -36
- package/runtime/python/okstra_ctl/agent_prompt_cli.py +0 -1156
- package/runtime/python/okstra_ctl/batch.py +0 -60
- package/runtime/python/okstra_ctl/clarification_items.py +0 -1050
- package/runtime/python/okstra_ctl/container_registry.py +0 -72
- package/runtime/python/okstra_ctl/improvement_assignment.py +0 -61
- package/runtime/python/okstra_ctl/resolver.py +0 -54
- package/runtime/python/okstra_ctl/team_reconcile.py +0 -275
- package/runtime/python/okstra_ctl/tmux.py +0 -134
- package/runtime/python/okstra_ctl/worktree.py +0 -1099
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
import json
|
|
5
|
+
import sys
|
|
5
6
|
import os
|
|
6
7
|
from datetime import datetime, timezone
|
|
7
8
|
from pathlib import Path
|
|
@@ -20,7 +21,12 @@ from .codex import (
|
|
|
20
21
|
codex_session_total,
|
|
21
22
|
find_codex_sessions,
|
|
22
23
|
)
|
|
23
|
-
from .antigravity import
|
|
24
|
+
from .antigravity import (
|
|
25
|
+
antigravity_session_total,
|
|
26
|
+
antigravity_status_total,
|
|
27
|
+
find_antigravity_sessions,
|
|
28
|
+
status_carries_usage,
|
|
29
|
+
)
|
|
24
30
|
from .grok import (
|
|
25
31
|
find_grok_sessions,
|
|
26
32
|
grok_session_is_non_interactive,
|
|
@@ -113,22 +119,115 @@ def _aggregate_totals(items: list[dict]) -> dict:
|
|
|
113
119
|
def run_artifact_suffix(team_state_path: Path) -> str | None:
|
|
114
120
|
"""``team-state-<task-type>-<seq>.json`` → ``<task-type>-<seq>``.
|
|
115
121
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
122
|
+
task 디렉토리 한 곳에 여러 run(재시도·이전 phase·레거시 타임스탬프)의 산출물이
|
|
123
|
+
섞여 있어, glob 으로 아무거나 집으면 엉뚱한 run 의 시각을 쓰게 된다(관측: 가장
|
|
124
|
+
오래된 레거시 manifest 의 createdAt 을 집어 윈도우가 한 달로 벌어짐).
|
|
125
|
+
|
|
126
|
+
**접미사가 곧 매니페스트 이름은 아니다.** okstra 는 카테고리별로 seq 를 따로
|
|
127
|
+
매기므로 한 run 이 `manifests: 025` 와 `state: 023` 을 동시에 가질 수 있다.
|
|
128
|
+
run-manifest 는 `_run_manifest_for_team_state` 가 매니페스트의 `teamStatePath`
|
|
129
|
+
역참조로 짚는다. status 산출물은 team-state 와 같은 카테고리라 이 접미사로
|
|
130
|
+
계속 짚는다."""
|
|
120
131
|
name = team_state_path.name
|
|
121
132
|
if not (name.startswith("team-state-") and name.endswith(".json")):
|
|
122
133
|
return None
|
|
123
134
|
return name[len("team-state-"):-len(".json")]
|
|
124
135
|
|
|
125
136
|
|
|
126
|
-
def
|
|
127
|
-
p = run_dir / "manifests" / f"run-manifest-{suffix}.json"
|
|
137
|
+
def _read_json_or_none(path: Path) -> dict | None:
|
|
128
138
|
try:
|
|
129
|
-
|
|
139
|
+
data = json.loads(path.read_text())
|
|
130
140
|
except (OSError, json.JSONDecodeError):
|
|
131
141
|
return None
|
|
142
|
+
return data if isinstance(data, dict) else None
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _run_manifest_for_team_state(
|
|
146
|
+
run_dir: Path, suffix: str, team_state_path: Path
|
|
147
|
+
) -> dict | None:
|
|
148
|
+
"""이 team-state 가 속한 run 의 매니페스트.
|
|
149
|
+
|
|
150
|
+
접미사가 곧 매니페스트 이름이라는 전제는 카테고리별 seq 가 갈리는 순간
|
|
151
|
+
깨진다. 실측(2026-08-27, fontsninja-nlpvibe `nestjs-migration-…`): 한 run 의
|
|
152
|
+
`manifests` 가 025, `state`·`prompts`·`worker-results` 가 023, `reports` 가
|
|
153
|
+
017 이었다. team-state 이름에서 뽑은 `023` 으로 매니페스트를 집으면 **12시간
|
|
154
|
+
전 run** 의 `createdAt`(04:45:34Z) 이 창의 시작이 되고, 그 사이 같은 세션이
|
|
155
|
+
돈 이전 run 들이 통째로 창에 들어온다 — `relax_start=False` 가 막으려던 바로
|
|
156
|
+
그 오탐이다(그 run 에서 로스터에 없는 워커 5명이 이 run 의 위반으로 보고됐다).
|
|
157
|
+
|
|
158
|
+
매니페스트는 자기 team-state 를 `teamStatePath` 에 적으므로 그것으로 맞춘다.
|
|
159
|
+
맞는 것이 없으면 접미사 방식으로 돌아간다 — 그 필드가 없던 옛 매니페스트다.
|
|
160
|
+
"""
|
|
161
|
+
direct = run_dir / "manifests" / f"run-manifest-{suffix}.json"
|
|
162
|
+
# `Path.glob` 는 디렉터리가 없어도 빈 결과를 낸다 — 감쌀 예외가 없다.
|
|
163
|
+
candidates = [
|
|
164
|
+
direct,
|
|
165
|
+
*sorted((run_dir / "manifests").glob("run-manifest-*.json")),
|
|
166
|
+
]
|
|
167
|
+
for path in candidates:
|
|
168
|
+
data = _read_json_or_none(path)
|
|
169
|
+
if data is None:
|
|
170
|
+
continue
|
|
171
|
+
recorded = str(data.get("teamStatePath") or "")
|
|
172
|
+
if recorded and Path(recorded).name == team_state_path.name:
|
|
173
|
+
return data
|
|
174
|
+
return _read_json_or_none(direct)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _created_at_by_suffix(run_dir: Path, suffix: str) -> str | None:
|
|
178
|
+
"""접미사가 곧 매니페스트 이름인 조회.
|
|
179
|
+
|
|
180
|
+
**다른** run 을 접미사로 지목할 때만 쓴다(`_previous_run_end`). 이번 run 은
|
|
181
|
+
team-state 로 맞춰야 한다 — 두 접미사가 갈리는 run 이 실재한다.
|
|
182
|
+
"""
|
|
183
|
+
data = _read_json_or_none(run_dir / "manifests" / f"run-manifest-{suffix}.json")
|
|
184
|
+
return None if data is None else data.get("createdAt")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def relaxation_floor(run_dir: Path, suffix: str, manifest: dict | None) -> str | None:
|
|
188
|
+
"""since 완화가 내려갈 수 있는 하한.
|
|
189
|
+
|
|
190
|
+
in-session 리드(`entryMode: current-session`)의 세션은 run 을 위해 태어난 것이
|
|
191
|
+
아니다 — 한 세션이 여러 날에 걸쳐 여러 task 의 run 을 돌린다(관측 2026-09-02,
|
|
192
|
+
dev-10626 error-analysis r04: 세션 첫 ts 08-17T08:00Z, run createdAt
|
|
193
|
+
09-02T20:03Z, 리드 소요 398h / $292 로 보고). 그 세션의 첫 ts 는 이 run 의
|
|
194
|
+
시작에 대해 아무것도 말하지 않으므로 하한은 매니페스트 createdAt 자체다 —
|
|
195
|
+
완화가 일어나지 않는다. 프로세스를 새로 띄운 리드는 세션이 prep 직전에
|
|
196
|
+
태어나므로 종전대로 직전 run 의 종료가 하한이다(`_previous_run_end`).
|
|
197
|
+
"""
|
|
198
|
+
if manifest is not None and manifest.get("entryMode") == "current-session":
|
|
199
|
+
created = manifest.get("createdAt")
|
|
200
|
+
if created:
|
|
201
|
+
return str(created)
|
|
202
|
+
return _previous_run_end(run_dir, suffix)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def window_start_is_pinned(since: str | None, floor: str | None) -> bool:
|
|
206
|
+
"""하한이 시작점 이상이면 완화할 여지가 없다 — 세션 jsonl 을 훑을 이유도 없다."""
|
|
207
|
+
return bool(since and floor and floor >= since)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def relax_window_start(
|
|
211
|
+
since: str | None, earliest: str | None, floor: str | None
|
|
212
|
+
) -> str | None:
|
|
213
|
+
"""`earliest` 가 `since` 보다 앞서면 하한 안에서 시작점을 앞당긴다."""
|
|
214
|
+
if not earliest:
|
|
215
|
+
return since
|
|
216
|
+
if floor and earliest < floor:
|
|
217
|
+
earliest = floor
|
|
218
|
+
if since is None or earliest < since:
|
|
219
|
+
return earliest
|
|
220
|
+
return since
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def run_window_relaxation_floor(team_state_path: Path) -> str | None:
|
|
224
|
+
"""collect 의 found-sessions 완화가 쓰는 하한 — `resolve_run_window` 와 같은 규칙."""
|
|
225
|
+
suffix = run_artifact_suffix(team_state_path)
|
|
226
|
+
if not suffix:
|
|
227
|
+
return None
|
|
228
|
+
run_dir = team_state_path.parent.parent
|
|
229
|
+
manifest = _run_manifest_for_team_state(run_dir, suffix, team_state_path)
|
|
230
|
+
return relaxation_floor(run_dir, suffix, manifest)
|
|
132
231
|
|
|
133
232
|
|
|
134
233
|
def _run_end_estimate(run_dir: Path, suffix: str) -> str | None:
|
|
@@ -233,9 +332,15 @@ def _previous_run_end(run_dir: Path, suffix: str) -> str | None:
|
|
|
233
332
|
ended_at = prev_state.get("runEndedAt")
|
|
234
333
|
if ended_at:
|
|
235
334
|
return str(ended_at)
|
|
236
|
-
except
|
|
335
|
+
except OSError:
|
|
336
|
+
# expected-miss: 직전 run 이 team-state 를 남기지 않고 끝났으면 파일이
|
|
337
|
+
# 없다. 아래 두 추정 경로가 바로 그 경우를 위한 폴백이다.
|
|
237
338
|
pass
|
|
238
|
-
|
|
339
|
+
except json.JSONDecodeError as exc:
|
|
340
|
+
# 파일은 있는데 깨진 것은 폴백이 상정한 상황이 아니다.
|
|
341
|
+
print(f"token-usage: team-state for the previous run ({prev}) is not "
|
|
342
|
+
f"valid JSON, estimating instead ({exc})", file=sys.stderr)
|
|
343
|
+
return _run_end_estimate(run_dir, prev) or _created_at_by_suffix(run_dir, prev)
|
|
239
344
|
|
|
240
345
|
|
|
241
346
|
def resolve_run_window(
|
|
@@ -258,7 +363,10 @@ def resolve_run_window(
|
|
|
258
363
|
since 를 앞당긴다. `leadSessionIds` 부재(legacy)면 createdAt 그대로 — 기존
|
|
259
364
|
동작 불변. 완화 하한: 직전 run 의 종료 시각 이전으로는 내려가지 않는다
|
|
260
365
|
(`_previous_run_end`). 세션 jsonl 은 run 마다 새로 생기지 않으므로 하한이
|
|
261
|
-
없으면 같은 세션의 이전 run 이 이 윈도우에 통째로 들어온다.
|
|
366
|
+
없으면 같은 세션의 이전 run 이 이 윈도우에 통째로 들어온다. in-session
|
|
367
|
+
리드(`entryMode: current-session`)는 완화하지 않는다 — 그 세션은 run 보다
|
|
368
|
+
먼저 태어났고 다른 task 의 run 도 돌렸으므로 첫 ts 는 세션 탄생일이다
|
|
369
|
+
(`relaxation_floor`).
|
|
262
370
|
|
|
263
371
|
`relax_start=False` (세션 스코프 검증기 전용 — session-conformance /
|
|
264
372
|
forbidden-actions): 완화를 건너뛰고 since 를 createdAt 에 고정한다. createdAt
|
|
@@ -271,14 +379,13 @@ def resolve_run_window(
|
|
|
271
379
|
if not suffix:
|
|
272
380
|
return None, None
|
|
273
381
|
run_dir = team_state_path.parent.parent
|
|
274
|
-
|
|
382
|
+
manifest = _run_manifest_for_team_state(run_dir, suffix, team_state_path)
|
|
383
|
+
since = None if manifest is None else manifest.get("createdAt")
|
|
275
384
|
if relax_start:
|
|
276
|
-
|
|
277
|
-
if
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if floor and since and since < floor:
|
|
281
|
-
since = floor
|
|
385
|
+
floor = relaxation_floor(run_dir, suffix, manifest)
|
|
386
|
+
if not window_start_is_pinned(since, floor):
|
|
387
|
+
earliest = _earliest_lead_session_ts(state, team_state_path)
|
|
388
|
+
since = relax_window_start(since, earliest, floor)
|
|
282
389
|
until = state.get("runEndedAt") or _run_end_estimate(run_dir, suffix) or utc_now()
|
|
283
390
|
return since, until
|
|
284
391
|
|
|
@@ -455,10 +562,18 @@ def _codex_worker_windows(project_root: Path, state: dict) -> dict[str, list[tup
|
|
|
455
562
|
return windows
|
|
456
563
|
|
|
457
564
|
|
|
565
|
+
# Claude 의 트랜스크립트는 세션 jsonl 이고, 그것은 이 모듈의 Claude 경로가
|
|
566
|
+
# 읽는다. 별도의 CLI 트랜스크립트가 없으므로 CLI 경로에 태우면 매번
|
|
567
|
+
# `no transcript was found` 가 붙는다 — 세션을 찾아 토큰을 붙인 행에도.
|
|
568
|
+
_SESSION_JSONL_PROVIDERS = frozenset({"claude"})
|
|
569
|
+
|
|
570
|
+
|
|
458
571
|
def _cli_assignment_provider(worker: dict) -> str:
|
|
459
572
|
worker_id = str(worker.get("workerId") or "").strip()
|
|
460
573
|
explicit_provider = str(worker.get("provider") or "").strip()
|
|
461
574
|
provider = explicit_provider or str(worker.get("agent") or "").strip()
|
|
575
|
+
if provider in _SESSION_JSONL_PROVIDERS:
|
|
576
|
+
return ""
|
|
462
577
|
runner = str(worker.get("runner") or "").strip()
|
|
463
578
|
if runner and runner != "cli-wrapper":
|
|
464
579
|
return ""
|
|
@@ -496,7 +611,11 @@ def _cli_session_totals(provider: str, session_paths: list[Path]) -> list[dict]:
|
|
|
496
611
|
if provider == "codex":
|
|
497
612
|
total = codex_session_total(session_path)
|
|
498
613
|
elif provider == "antigravity":
|
|
499
|
-
total =
|
|
614
|
+
total = (
|
|
615
|
+
antigravity_status_total(session_path)
|
|
616
|
+
if status_carries_usage(session_path)
|
|
617
|
+
else antigravity_session_total(session_path)
|
|
618
|
+
)
|
|
500
619
|
elif provider == "grok":
|
|
501
620
|
total = grok_session_total(session_path)
|
|
502
621
|
else:
|
|
@@ -642,12 +761,23 @@ def _worker_cli_windows(
|
|
|
642
761
|
return fallback_windows, status_path, True
|
|
643
762
|
|
|
644
763
|
|
|
645
|
-
def
|
|
764
|
+
def _antigravity_usage_sources(
|
|
646
765
|
project_root: Path,
|
|
647
766
|
worker: dict,
|
|
648
767
|
status_path: Path | None,
|
|
649
768
|
) -> list[Path]:
|
|
650
|
-
"""agy
|
|
769
|
+
"""agy 의 토큰 스냅샷이 있는 곳. 홈 세션 디렉터리가 아니다.
|
|
770
|
+
|
|
771
|
+
정본은 래퍼 status 사이드카의 `usage` 다 — 러너가 스트림의 마지막
|
|
772
|
+
`result.usage` 를 종료 시점에 적는다(`worker_runner`). 워커 로그는 러너가
|
|
773
|
+
사람이 읽는 줄로 옮겨 적은 것이라 stream-json 이 아니고, 그 로그에서
|
|
774
|
+
usage 를 찾던 동안 antigravity 워커 전부가 `transcript found but no final
|
|
775
|
+
token snapshot was recorded` 였다(관측 2026-09-02, dev-10626 r01·r02·r04).
|
|
776
|
+
로그를 읽는 경로는 러너 이전의 raw stream-json 로그를 위해 남긴다 — 스냅샷이
|
|
777
|
+
있는 run 의 로그는 옮겨 적은 텍스트라 트랜스크립트로 나열하지 않는다.
|
|
778
|
+
"""
|
|
779
|
+
if status_path is not None and status_carries_usage(status_path):
|
|
780
|
+
return [status_path]
|
|
651
781
|
paths: list[Path] = []
|
|
652
782
|
prompt_path = _resolve_project_path(project_root, str(worker.get("promptPath") or ""))
|
|
653
783
|
if prompt_path is not None:
|
|
@@ -676,9 +806,9 @@ def _worker_cli_usage_block(
|
|
|
676
806
|
)
|
|
677
807
|
session_paths = _cli_sessions_for_windows(provider, project_root, windows)
|
|
678
808
|
if provider == "antigravity":
|
|
679
|
-
for
|
|
680
|
-
if
|
|
681
|
-
session_paths.append(
|
|
809
|
+
for source in _antigravity_usage_sources(project_root, worker, status_path):
|
|
810
|
+
if source not in session_paths:
|
|
811
|
+
session_paths.append(source)
|
|
682
812
|
return collect_cli_usage(
|
|
683
813
|
provider=provider,
|
|
684
814
|
status_path=status_path,
|
|
@@ -701,8 +831,8 @@ def _attach_cli_usage(
|
|
|
701
831
|
window produces several rollout jsonls; pricing only the latest (the old
|
|
702
832
|
``find_codex_session`` -> ``sessions[-1]`` behavior) dropped the earlier
|
|
703
833
|
attempts' tokens. We sum every in-window session here so the redispatched
|
|
704
|
-
CLI spend is fully reported. antigravity 는
|
|
705
|
-
|
|
834
|
+
CLI spend is fully reported. antigravity 는 status 사이드카의 ``usage``
|
|
835
|
+
스냅샷을 같은 합산 경로에 붙인다.
|
|
706
836
|
"""
|
|
707
837
|
session_paths = _cli_sessions_for_windows(provider, project_root, windows)
|
|
708
838
|
cli = collect_cli_usage(
|
|
@@ -733,7 +863,8 @@ def _collect_cli_runtime_usage(
|
|
|
733
863
|
provider = _cli_assignment_provider(worker)
|
|
734
864
|
if not provider:
|
|
735
865
|
worker["usage"] = na_block(
|
|
736
|
-
"worker is
|
|
866
|
+
"worker usage is not read from a provider CLI transcript "
|
|
867
|
+
"(host-native, session-jsonl provider, or no registered CLI provider): "
|
|
737
868
|
f"{worker.get('provider') or worker.get('agent') or worker.get('workerId')}"
|
|
738
869
|
)
|
|
739
870
|
continue
|
|
@@ -963,16 +1094,20 @@ def collect_claude_runtime_usage(
|
|
|
963
1094
|
claude_sessions = find_claude_team_sessions(cwd, team_needles, lead_sid,
|
|
964
1095
|
incremental=incremental)
|
|
965
1096
|
# Task 9: 축1 기록(observed-team-names)으로 발견한 세션들의 min first-ts 로
|
|
966
|
-
# run_since 를 완화한다.
|
|
967
|
-
#
|
|
1097
|
+
# run_since 를 완화한다. 불확실한 reconstruct/none source 는 완화하지
|
|
1098
|
+
# 않는다(오귀속 방지). 하한은 `resolve_run_window` 와 같다 — 발견 세션에는
|
|
1099
|
+
# 리드 세션 자신이 들어 있고, in-session 리드의 세션 첫 ts 는 run 이 아니라
|
|
1100
|
+
# 세션의 탄생일이다(관측: 16일 전). 하한 없이 두던 동안 리드 소요 시간과
|
|
1101
|
+
# 비용이 세션 수명 전체로 보고됐다.
|
|
968
1102
|
if needle_source == "observed-team-names":
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1103
|
+
floor = run_window_relaxation_floor(team_state_path)
|
|
1104
|
+
if not window_start_is_pinned(run_since, floor):
|
|
1105
|
+
found_earliest = None
|
|
1106
|
+
for path in claude_sessions.values():
|
|
1107
|
+
ts = _session_first_ts(path)
|
|
1108
|
+
if ts and (found_earliest is None or ts < found_earliest):
|
|
1109
|
+
found_earliest = ts
|
|
1110
|
+
run_since = relax_window_start(run_since, found_earliest, floor)
|
|
976
1111
|
by_agent: dict[str, list[tuple[str, Path, dict]]] = {}
|
|
977
1112
|
lead_path: Path | None = None
|
|
978
1113
|
# Team-tagged non-lead sessions that carry no agentName. These are almost
|
|
@@ -92,4 +92,6 @@ def save_cache(jsonl_path: Path, cache: dict) -> None:
|
|
|
92
92
|
tmp.write_text(json.dumps(cache, ensure_ascii=False, separators=(",", ":")))
|
|
93
93
|
os.replace(tmp, p)
|
|
94
94
|
except OSError:
|
|
95
|
+
# expected-miss: 이 캐시는 jsonl 에서 언제든 다시 만들 수 있는 파생물이다.
|
|
96
|
+
# 저장에 실패해도 집계 결과가 달라지지 않으므로 없는 것이 정상 분기다.
|
|
95
97
|
pass
|
|
@@ -11,7 +11,7 @@ import os
|
|
|
11
11
|
from datetime import datetime, timezone
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import Mapping
|
|
14
|
-
from urllib.parse import
|
|
14
|
+
from urllib.parse import unquote
|
|
15
15
|
|
|
16
16
|
from .jsonl_io import iter_jsonl
|
|
17
17
|
from .paths import ts_in_window
|
|
@@ -132,10 +132,6 @@ def find_grok_sessions(
|
|
|
132
132
|
return sorted(matches)
|
|
133
133
|
|
|
134
134
|
|
|
135
|
-
def grok_session_dir_name(cwd: Path) -> str:
|
|
136
|
-
return quote(str(cwd), safe="")
|
|
137
|
-
|
|
138
|
-
|
|
139
135
|
def grok_session_is_non_interactive(updates_path: Path) -> bool:
|
|
140
136
|
"""워커 래퍼 세션은 prompt_context.is_non_interactive 가 true 이다."""
|
|
141
137
|
context_path = updates_path.parent / "prompt_context.json"
|
|
@@ -72,3 +72,29 @@ def claude_project_dir(cwd: Path, projects_root: Path | None = None) -> Path:
|
|
|
72
72
|
# `projects_root` 는 테스트/진단용 주입 시드 — 기본은 실제 ~/.claude/projects.
|
|
73
73
|
encoded = "-" + str(cwd).strip("/").replace("/", "-")
|
|
74
74
|
return (projects_root or CLAUDE_PROJECTS) / encoded
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def find_session_jsonl(
|
|
78
|
+
session_id: str, cwd: Path, projects_root: Path | None = None
|
|
79
|
+
) -> Path | None:
|
|
80
|
+
"""세션 id 하나의 transcript 경로. 못 찾으면 None.
|
|
81
|
+
|
|
82
|
+
프로젝트로 인코딩된 디렉터리를 먼저 보고, 없으면 projects_root 아래의
|
|
83
|
+
모든 인코딩 디렉터리를 훑는다. 리드 세션의 cwd 가 대상 프로젝트 루트와
|
|
84
|
+
다를 수 있기 때문이다 — `okstra preflight --cwd <다른 프로젝트>` 는
|
|
85
|
+
지원되는 실행 방식이고, 그때 transcript 는 **리드 세션의 cwd** 로 인코딩된
|
|
86
|
+
디렉터리에 놓인다. 프로젝트 디렉터리만 보면 실재하는 세션을 없다고 답한다.
|
|
87
|
+
|
|
88
|
+
세션 id 는 전역 유일하므로 디렉터리를 넓혀도 다른 세션을 잘못 집지 않는다.
|
|
89
|
+
파일 내용을 읽지 않는 경로 조회다.
|
|
90
|
+
"""
|
|
91
|
+
if not session_id:
|
|
92
|
+
return None
|
|
93
|
+
direct = claude_project_dir(cwd, projects_root) / f"{session_id}.jsonl"
|
|
94
|
+
if direct.is_file():
|
|
95
|
+
return direct
|
|
96
|
+
root = projects_root or CLAUDE_PROJECTS
|
|
97
|
+
try:
|
|
98
|
+
return next(iter(sorted(root.glob(f"*/{session_id}.jsonl"))), None)
|
|
99
|
+
except OSError:
|
|
100
|
+
return None
|
|
@@ -4,18 +4,19 @@ Pricing is matched by substring against the model id recorded in the session
|
|
|
4
4
|
transcript, so keys must reflect the *actual* model id form emitted by each
|
|
5
5
|
provider:
|
|
6
6
|
|
|
7
|
-
* Anthropic — `claude-fable-5*`, `claude-opus-5*`, `claude-opus-4-*`, `claude-sonnet-5*`, `claude-sonnet-4-*`,
|
|
7
|
+
* Anthropic — `claude-fable-5-1*`, `claude-fable-5*`, `claude-opus-5*`, `claude-opus-4-*`, `claude-sonnet-5*`, `claude-sonnet-4-*`,
|
|
8
8
|
`claude-haiku-4-5-*`, `claude-3-5-sonnet-*`, `claude-3-5-haiku-*`,
|
|
9
9
|
`claude-3-opus-*`, `claude-3-haiku-*`.
|
|
10
10
|
* OpenAI / Codex — `gpt-5*`, `gpt-4o*`, `gpt-4*`.
|
|
11
|
-
* Google / Gemini — `gemini-3.6-flash*`, `gemini-3.5-flash*`, `gemini-3.1-pro*`, `gemini-3-flash*`,
|
|
11
|
+
* Google / Gemini — `gemini-3.7-flash*`, `gemini-3.6-flash*`, `gemini-3.5-flash*`, `gemini-3.1-pro*`, `gemini-3-flash*`,
|
|
12
12
|
`gemini-2.5-pro*`, `gemini-2.5-flash*`, `gemini-2.0-flash*`.
|
|
13
13
|
|
|
14
14
|
Matching prefers the longest key that is a substring of the model id (most
|
|
15
15
|
specific wins), so table ordering does not affect the result. Update when
|
|
16
16
|
providers change list pricing.
|
|
17
17
|
|
|
18
|
-
Sources (last verified 2026-08-03
|
|
18
|
+
Sources (last verified 2026-08-03 — Anthropic Fable 5.1 re-verified 2026-09-02,
|
|
19
|
+
Google table re-verified 2026-08-26, public list prices, USD per 1M tokens):
|
|
19
20
|
* Anthropic: https://www.anthropic.com/pricing
|
|
20
21
|
* OpenAI: https://openai.com/api/pricing
|
|
21
22
|
* Google: https://ai.google.dev/gemini-api/docs/pricing
|
|
@@ -49,6 +50,9 @@ CLAUDE_PRICING = {
|
|
|
49
50
|
"3-sonnet": (3.0, 3.75, 0.30, 15.0), # legacy 3 Sonnet
|
|
50
51
|
"3-haiku": (0.25, 0.30, 0.03, 1.25), # Haiku 3
|
|
51
52
|
|
|
53
|
+
# Claude Fable 5.1 — input/output match Fable 5; cache_read is 75% lower
|
|
54
|
+
# ($0.25, not the 0.1x ratio). Longest-key match so this beats "fable-5".
|
|
55
|
+
"fable-5-1": (10.0, 12.5, 0.25, 50.0), # Fable 5.1 (Anthropic 2026-09-01)
|
|
52
56
|
# Claude Fable 5 (tier above Opus).
|
|
53
57
|
"fable-5": (10.0, 12.5, 1.0, 50.0), # Fable 5 (cache prices derived from ratios)
|
|
54
58
|
|
|
@@ -74,9 +78,10 @@ CLAUDE_PRICING = {
|
|
|
74
78
|
# Anthropic 1h ephemeral cache_creation multiplier on the base input rate.
|
|
75
79
|
CLAUDE_CACHE_CREATE_1H_MULT = 2.0
|
|
76
80
|
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
# `catalog_pricing("codex")`. Substring match order is
|
|
81
|
+
# Codex prices for slugs the provider catalog no longer offers. Prices for
|
|
82
|
+
# registered models -- selectable or hidden -- live in the model catalog and are
|
|
83
|
+
# merged in below via `catalog_pricing("codex")`. Substring match order is
|
|
84
|
+
# longest-key-first
|
|
80
85
|
# (see `_match_pricing`), so this dict's ordering no longer affects matching.
|
|
81
86
|
# For models with no published cached-input rate (o1-pro, o3-pro), cached is set
|
|
82
87
|
# equal to input as a conservative no-discount default.
|
|
@@ -84,6 +89,10 @@ _LEGACY_CODEX_PRICING = {
|
|
|
84
89
|
# model substring -> (input USD/1M, cached_input USD/1M, output USD/1M).
|
|
85
90
|
|
|
86
91
|
# GPT-5 series.
|
|
92
|
+
# gpt-5.6 was dropped from the provider catalog; its rate stays so past runs
|
|
93
|
+
# keep pricing. Substring matching means sol / terra / luna resolve here too
|
|
94
|
+
# -- the 5.6 family rate, not a per-variant price we have a source for.
|
|
95
|
+
"gpt-5.6": (5.00, 0.50, 30.0),
|
|
87
96
|
"gpt-5.2-pro": (21.0, 2.10, 168.0),
|
|
88
97
|
"gpt-5.1": (1.25, 0.125, 10.0),
|
|
89
98
|
"gpt-5-mini": (0.25, 0.025, 2.00),
|
|
@@ -126,8 +135,14 @@ GEMINI_PRICING = {
|
|
|
126
135
|
# forms appear in the wild, so include both for the new 3.x families.
|
|
127
136
|
|
|
128
137
|
# Gemini 3 series.
|
|
129
|
-
|
|
130
|
-
|
|
138
|
+
# 3.7 Flash 와 3.6 Flash 는 2026-12-31 까지 도입 요율 $0.75/$3.75 이고
|
|
139
|
+
# 2027-01-01 에 표준 요율 $1.50/$7.50 으로 오른다(2026-08-26 확인). 이 표에는
|
|
140
|
+
# 시점 개념이 없으므로 지금 청구되는 값을 담는다 — 그날 이후 두 계열을
|
|
141
|
+
# (1.50, 7.50) 으로 갱신해야 한다.
|
|
142
|
+
"3.7-flash": (0.75, 3.75),
|
|
143
|
+
"3-7-flash": (0.75, 3.75),
|
|
144
|
+
"3.6-flash": (0.75, 3.75),
|
|
145
|
+
"3-6-flash": (0.75, 3.75),
|
|
131
146
|
"3.5-flash": (1.50, 9.00),
|
|
132
147
|
"3-5-flash": (1.50, 9.00),
|
|
133
148
|
"3.1-pro": (2.00, 12.0),
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
"items": { "type": "string", "pattern": "\\S" }
|
|
32
32
|
},
|
|
33
33
|
"originEvidence": { "type": "string", "pattern": "\\S" },
|
|
34
|
+
"duplicateOf": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"pattern": "\\S",
|
|
37
|
+
"description": "The existing finding id (`F-NNN`) this candidate overlaps. A declared duplicate is recorded and skips gap verification entirely; restating the finding instead costs one verification round to reject it. The shape stays free-form because `findingId` is free-form in convergence-groups-v2.0; `okstra convergence apply-critic-gaps` owns the check that the id names a finding the state actually carries."
|
|
38
|
+
},
|
|
34
39
|
"severity": { "enum": ["critical", "major", "minor"] },
|
|
35
40
|
"evidenceArtifacts": {
|
|
36
41
|
"type": "array",
|
|
@@ -236,10 +236,7 @@
|
|
|
236
236
|
"dutyId",
|
|
237
237
|
"dispatchKind",
|
|
238
238
|
"round",
|
|
239
|
-
"inputDigest"
|
|
240
|
-
"writePolicy",
|
|
241
|
-
"writePolicyDigest",
|
|
242
|
-
"writeEnforcement"
|
|
239
|
+
"inputDigest"
|
|
243
240
|
],
|
|
244
241
|
"properties": {
|
|
245
242
|
"invocationRef": {"type": "string", "pattern": "\\S"},
|
|
@@ -250,10 +247,7 @@
|
|
|
250
247
|
"dutyId": {"type": "string", "pattern": "\\S"},
|
|
251
248
|
"dispatchKind": {"type": "string", "pattern": "\\S"},
|
|
252
249
|
"round": {"type": "integer", "minimum": 1},
|
|
253
|
-
"inputDigest": {"$ref": "#/$defs/Digest"}
|
|
254
|
-
"writePolicy": {"$ref": "#/$defs/WritePolicy"},
|
|
255
|
-
"writePolicyDigest": {"$ref": "#/$defs/Digest"},
|
|
256
|
-
"writeEnforcement": {"$ref": "#/$defs/WriteEnforcement"}
|
|
250
|
+
"inputDigest": {"$ref": "#/$defs/Digest"}
|
|
257
251
|
},
|
|
258
252
|
"additionalProperties": false
|
|
259
253
|
},
|
|
@@ -268,7 +262,10 @@
|
|
|
268
262
|
"resultPath",
|
|
269
263
|
"errorPath",
|
|
270
264
|
"changeSummary",
|
|
271
|
-
"evidenceSealRef"
|
|
265
|
+
"evidenceSealRef",
|
|
266
|
+
"writePolicy",
|
|
267
|
+
"writePolicyDigest",
|
|
268
|
+
"writeEnforcement"
|
|
272
269
|
],
|
|
273
270
|
"properties": {
|
|
274
271
|
"invocationRef": {"type": "string", "pattern": "\\S"},
|
|
@@ -279,7 +276,10 @@
|
|
|
279
276
|
"resultPath": {"type": ["string", "null"]},
|
|
280
277
|
"errorPath": {"type": ["string", "null"]},
|
|
281
278
|
"changeSummary": {"type": "object"},
|
|
282
|
-
"evidenceSealRef": {"type": ["string", "null"]}
|
|
279
|
+
"evidenceSealRef": {"type": ["string", "null"]},
|
|
280
|
+
"writePolicy": {"$ref": "#/$defs/WritePolicy"},
|
|
281
|
+
"writePolicyDigest": {"$ref": "#/$defs/Digest"},
|
|
282
|
+
"writeEnforcement": {"$ref": "#/$defs/WriteEnforcement"}
|
|
283
283
|
},
|
|
284
284
|
"additionalProperties": false
|
|
285
285
|
},
|
|
@@ -251,7 +251,7 @@
|
|
|
251
251
|
},
|
|
252
252
|
"verdictCard": {
|
|
253
253
|
"type": "object",
|
|
254
|
-
"description": "Top-of-report at-a-glance card. It carries no verdict token — the token lives once, in finalVerdict. `direction` and `nextStep`
|
|
254
|
+
"description": "Top-of-report at-a-glance card. It carries no verdict token — the token lives once, in finalVerdict, and additionalProperties:false keeps it from being copied here. Authoring guideline: write `direction` to agree with finalVerdict.direction and `nextStep` to agree with recommendedNextSteps[0]. Nothing compares the two copies afterwards — assembly rewrites `nextStep` on both cards together when the plan-body gate passes, and leaves `direction` as the writer wrote it — so a disagreement between them is published as written.",
|
|
255
255
|
"required": [
|
|
256
256
|
"finalConclusion",
|
|
257
257
|
"direction",
|
|
@@ -312,9 +312,8 @@
|
|
|
312
312
|
},
|
|
313
313
|
"summary": {
|
|
314
314
|
"type": "array",
|
|
315
|
-
"description": "## Summary of the Problem or Verification Target. 3-5 rows.",
|
|
315
|
+
"description": "## Summary of the Problem or Verification Target. Usually 3-5 rows; no upper limit.",
|
|
316
316
|
"minItems": 1,
|
|
317
|
-
"maxItems": 8,
|
|
318
317
|
"items": {
|
|
319
318
|
"$ref": "#/$defs/SummaryRow"
|
|
320
319
|
}
|
|
@@ -3897,8 +3896,8 @@
|
|
|
3897
3896
|
},
|
|
3898
3897
|
"summary": {
|
|
3899
3898
|
"type": "string",
|
|
3900
|
-
"minLength": 1
|
|
3901
|
-
|
|
3899
|
+
"minLength": 1
|
|
3900
|
+
|
|
3902
3901
|
},
|
|
3903
3902
|
"details": {
|
|
3904
3903
|
"type": "string",
|
|
@@ -7527,8 +7526,8 @@
|
|
|
7527
7526
|
},
|
|
7528
7527
|
"summary": {
|
|
7529
7528
|
"type": "string",
|
|
7530
|
-
"minLength": 1
|
|
7531
|
-
|
|
7529
|
+
"minLength": 1
|
|
7530
|
+
|
|
7532
7531
|
},
|
|
7533
7532
|
"details": {
|
|
7534
7533
|
"type": "string",
|
|
@@ -9030,24 +9029,6 @@
|
|
|
9030
9029
|
"type": "string",
|
|
9031
9030
|
"minLength": 1
|
|
9032
9031
|
}
|
|
9033
|
-
},
|
|
9034
|
-
"rewrittenPaths": {
|
|
9035
|
-
"type": "array",
|
|
9036
|
-
"description": "data.json paths this round actually rewrote for this cause group. A self-fix round is contractually a targeted correction, not a full draft regeneration; recording the reach is what makes that claim checkable later.",
|
|
9037
|
-
"uniqueItems": true,
|
|
9038
|
-
"items": {
|
|
9039
|
-
"type": "string",
|
|
9040
|
-
"minLength": 1
|
|
9041
|
-
}
|
|
9042
|
-
},
|
|
9043
|
-
"outsideScopePaths": {
|
|
9044
|
-
"type": "array",
|
|
9045
|
-
"description": "The subset of rewrittenPaths that lies outside the sections this group's itemIds point at. Carrying a correction to its contradictions legitimately reaches further than the flagged item, so this is a measurement, not a violation.",
|
|
9046
|
-
"uniqueItems": true,
|
|
9047
|
-
"items": {
|
|
9048
|
-
"type": "string",
|
|
9049
|
-
"minLength": 1
|
|
9050
|
-
}
|
|
9051
9032
|
}
|
|
9052
9033
|
}
|
|
9053
9034
|
},
|
|
@@ -9569,10 +9550,12 @@
|
|
|
9569
9550
|
"minLength": 1
|
|
9570
9551
|
},
|
|
9571
9552
|
"verdict": {
|
|
9553
|
+
"description": "`not-run` is not a rejection: the verifier produced no verdict at all (timeout, error, usage limit). `FAIL` rejects the diff and opens the stage fix cycle, so spending it on a verifier that never ran manufactures a defect nobody found \u2014 see `_implementation-verifier.md` \"All-verifier-failure policy\".",
|
|
9572
9554
|
"enum": [
|
|
9573
9555
|
"PASS",
|
|
9574
9556
|
"CONCERNS",
|
|
9575
|
-
"FAIL"
|
|
9557
|
+
"FAIL",
|
|
9558
|
+
"not-run"
|
|
9576
9559
|
]
|
|
9577
9560
|
},
|
|
9578
9561
|
"readOnlyCommandLog": {
|