okstra 0.206.0 → 0.206.1
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 +2 -2
- package/dist/commands/lifecycle/install.mjs +1 -1
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/docs/architecture.md +12 -12
- package/docs/cli.md +4 -4
- package/docs/contributor-change-matrix.md +3 -2
- package/docs/performance-improvement-plan-v2.md +1 -1
- package/docs/project-structure-overview.md +39 -18
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/bin/okstra-spawn-followups.py +2 -2
- package/runtime/prompts/launch.template.md +1 -1
- package/runtime/prompts/lead/context-loader.md +1 -1
- package/runtime/prompts/lead/convergence.md +3 -3
- package/runtime/prompts/lead/okstra-lead-contract.md +13 -54
- package/runtime/prompts/lead/phase-routing.md +64 -0
- package/runtime/prompts/lead/report-writer.md +2 -2
- package/runtime/prompts/lead/team-contract.md +1 -1
- package/runtime/prompts/profiles/_coding-conventions-preflight.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +1 -1
- package/runtime/prompts/profiles/_coverage-critic.md +1 -1
- package/runtime/prompts/profiles/forbidden-actions.json +0 -94
- package/runtime/python/okstra_ctl/agent/prompt_cli/corrections.py +1 -1
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +10 -1
- package/runtime/python/okstra_ctl/analysis_inputs.py +0 -39
- package/runtime/python/okstra_ctl/analysis_scope.py +31 -0
- package/runtime/python/okstra_ctl/asset_roots.py +19 -0
- package/runtime/python/okstra_ctl/consumers.py +12 -0
- package/runtime/python/okstra_ctl/dispatch_state.py +22 -0
- package/runtime/python/okstra_ctl/doctor.py +2 -1
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +27 -1
- package/runtime/python/okstra_ctl/handoff.py +11 -466
- package/runtime/python/okstra_ctl/handoff_error.py +5 -0
- package/runtime/python/okstra_ctl/implementation_direction.py +0 -477
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +8 -1
- package/runtime/python/okstra_ctl/option_comparison.py +3 -165
- package/runtime/python/okstra_ctl/option_votes.py +3 -191
- package/runtime/python/okstra_ctl/paths.py +8 -6
- package/runtime/python/okstra_ctl/phases/catalog.py +56 -12
- package/runtime/python/okstra_ctl/phases/change_impact_analysis/boundary.json +11 -0
- package/runtime/python/okstra_ctl/phases/change_impact_analysis/entry.py +39 -0
- package/runtime/python/okstra_ctl/{report_html/view_models/change_impact_analysis.py → phases/change_impact_analysis/report.py} +3 -3
- package/runtime/python/okstra_ctl/phases/change_impact_analysis/spec.md +26 -0
- package/runtime/python/okstra_ctl/phases/change_impact_analysis/validation.py +23 -0
- package/runtime/python/okstra_ctl/phases/error_analysis/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/error_analysis/boundary.json +9 -0
- package/runtime/{prompts/profiles/error-analysis.md → python/okstra_ctl/phases/error_analysis/profile.md} +2 -2
- package/runtime/python/okstra_ctl/{report_html/view_models/error_analysis.py → phases/error_analysis/report.py} +9 -8
- package/runtime/{templates/reports → python/okstra_ctl/phases/error_analysis/report_assets}/error-analysis-input.template.md +1 -1
- package/runtime/python/okstra_ctl/phases/error_analysis/spec.md +118 -0
- package/runtime/python/okstra_ctl/phases/error_analysis/validation.py +241 -0
- package/runtime/python/okstra_ctl/phases/feature_analysis/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/feature_analysis/boundary.json +8 -0
- package/runtime/python/okstra_ctl/phases/feature_analysis/entry.py +63 -0
- package/runtime/python/okstra_ctl/{report_html/view_models/feature_analysis.py → phases/feature_analysis/report.py} +12 -5
- package/runtime/python/okstra_ctl/phases/feature_analysis/spec.md +22 -0
- package/runtime/python/okstra_ctl/phases/feature_analysis/validation.py +27 -0
- package/runtime/python/okstra_ctl/phases/feature_analysis/wizard.py +95 -0
- package/runtime/python/okstra_ctl/phases/final_verification/boundary.json +8 -0
- package/runtime/python/okstra_ctl/phases/final_verification/profile.md +1 -1
- package/runtime/{templates/reports → python/okstra_ctl/phases/final_verification/report_assets}/final-verification-input.template.md +1 -1
- package/runtime/python/okstra_ctl/phases/final_verification/spec.md +1 -1
- package/runtime/python/okstra_ctl/phases/implementation/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/implementation/boundary.json +17 -0
- package/runtime/python/okstra_ctl/{implementation_stage.py → phases/implementation/entry.py} +22 -10
- package/runtime/{prompts/host-orchestration/implementation.md → python/okstra_ctl/phases/implementation/host-rules.md} +1 -1
- package/runtime/{prompts/profiles → python/okstra_ctl/phases/implementation/instructions}/_implementation-deliverable.md +1 -1
- package/runtime/{prompts/profiles → python/okstra_ctl/phases/implementation/instructions}/_implementation-executor.md +4 -3
- package/runtime/{prompts/profiles → python/okstra_ctl/phases/implementation/instructions}/_implementation-verifier.md +4 -4
- package/runtime/{prompts/profiles/implementation.md → python/okstra_ctl/phases/implementation/profile.md} +5 -5
- package/runtime/python/okstra_ctl/{report_html/view_models/implementation.py → phases/implementation/report.py} +3 -3
- package/runtime/{templates/reports → python/okstra_ctl/phases/implementation/report_assets}/implementation-input.template.md +1 -1
- package/runtime/python/okstra_ctl/phases/implementation/spec.md +238 -0
- package/runtime/python/okstra_ctl/phases/implementation/validation.py +205 -0
- package/runtime/python/okstra_ctl/phases/implementation/wizard.py +39 -0
- package/runtime/python/okstra_ctl/phases/implementation_option_selection/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/implementation_option_selection/authoring.py +80 -0
- package/runtime/python/okstra_ctl/phases/implementation_option_selection/boundary.json +10 -0
- package/runtime/python/okstra_ctl/phases/implementation_option_selection/comparison.py +168 -0
- package/runtime/python/okstra_ctl/phases/implementation_option_selection/entry.py +27 -0
- package/runtime/{prompts/profiles/implementation-option-selection.md → python/okstra_ctl/phases/implementation_option_selection/profile.md} +2 -2
- package/runtime/python/okstra_ctl/{report_html/view_models/implementation_option_selection.py → phases/implementation_option_selection/report.py} +2 -2
- package/runtime/python/okstra_ctl/phases/implementation_option_selection/spec.md +83 -0
- package/runtime/python/okstra_ctl/{implementation_options.py → phases/implementation_option_selection/validation.py} +3 -3
- package/runtime/python/okstra_ctl/phases/implementation_option_selection/votes.py +194 -0
- package/runtime/python/okstra_ctl/phases/implementation_planning/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/implementation_planning/authoring.py +2345 -0
- package/runtime/python/okstra_ctl/phases/implementation_planning/boundary.json +12 -0
- package/runtime/python/okstra_ctl/phases/implementation_planning/entry.py +161 -0
- package/runtime/python/okstra_ctl/phases/implementation_planning/guidance.py +178 -0
- package/runtime/{prompts/lead → python/okstra_ctl/phases/implementation_planning/instructions}/plan-body-verification.md +61 -51
- package/runtime/python/okstra_ctl/phases/implementation_planning/plan_body.py +3295 -0
- package/runtime/{prompts/profiles/implementation-planning.md → python/okstra_ctl/phases/implementation_planning/profile.md} +74 -25
- package/runtime/python/okstra_ctl/phases/implementation_planning/report.py +237 -0
- package/runtime/{templates/reports → python/okstra_ctl/phases/implementation_planning/report_assets}/implementation-planning-input.template.md +2 -2
- package/runtime/python/okstra_ctl/phases/implementation_planning/spec.md +204 -0
- package/runtime/python/okstra_ctl/phases/implementation_planning/validation.py +597 -0
- package/runtime/python/okstra_ctl/phases/implementation_planning/wizard.py +166 -0
- package/runtime/python/okstra_ctl/phases/improvement_discovery/boundary.json +12 -0
- package/runtime/python/okstra_ctl/{improvement_lenses.py → phases/improvement_discovery/lenses.py} +1 -6
- package/runtime/{prompts/profiles/improvement-discovery.md → python/okstra_ctl/phases/improvement_discovery/profile.md} +5 -5
- package/runtime/python/okstra_ctl/{report_html/view_models/improvement_discovery.py → phases/improvement_discovery/report.py} +3 -3
- package/runtime/{templates/reports → python/okstra_ctl/phases/improvement_discovery/report_assets}/improvement-discovery-input.template.md +1 -2
- package/runtime/python/okstra_ctl/phases/improvement_discovery/spec.md +29 -0
- package/runtime/{validators/validate_improvement_report.py → python/okstra_ctl/phases/improvement_discovery/validation.py} +5 -14
- package/runtime/python/okstra_ctl/phases/project_analysis/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/project_analysis/boundary.json +8 -0
- package/runtime/python/okstra_ctl/phases/project_analysis/entry.py +11 -0
- package/runtime/python/okstra_ctl/{report_html/view_models/project_analysis.py → phases/project_analysis/report.py} +3 -3
- package/runtime/python/okstra_ctl/phases/project_analysis/spec.md +33 -0
- package/runtime/python/okstra_ctl/phases/project_analysis/validation.py +55 -0
- package/runtime/python/okstra_ctl/phases/release_handoff/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/release_handoff/boundary.json +17 -0
- package/runtime/python/okstra_ctl/phases/release_handoff/entry.py +147 -0
- package/runtime/python/okstra_ctl/phases/release_handoff/operations.py +446 -0
- package/runtime/{prompts/profiles/release-handoff.md → python/okstra_ctl/phases/release_handoff/profile.md} +3 -3
- package/runtime/python/okstra_ctl/{report_html/view_models/release_handoff.py → phases/release_handoff/report.py} +3 -3
- package/runtime/{templates/reports → python/okstra_ctl/phases/release_handoff/report_assets}/release-handoff-input.template.md +1 -1
- package/runtime/python/okstra_ctl/phases/release_handoff/spec.md +233 -0
- package/runtime/python/okstra_ctl/phases/release_handoff/wizard.py +84 -0
- package/runtime/python/okstra_ctl/phases/requirements_discovery/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/requirements_discovery/boundary.json +9 -0
- package/runtime/{prompts/profiles/requirements-discovery.md → python/okstra_ctl/phases/requirements_discovery/profile.md} +2 -3
- package/runtime/python/okstra_ctl/{report_html/view_models/requirements_discovery.py → phases/requirements_discovery/report.py} +3 -3
- package/runtime/python/okstra_ctl/phases/requirements_discovery/spec.md +132 -0
- package/runtime/{validators/validate_fanout.py → python/okstra_ctl/phases/requirements_discovery/validation.py} +11 -12
- package/runtime/python/okstra_ctl/phases/technical_verification/__init__.py +1 -0
- package/runtime/python/okstra_ctl/phases/technical_verification/boundary.json +9 -0
- package/runtime/python/okstra_ctl/phases/technical_verification/entry.py +100 -0
- package/runtime/{prompts/profiles/technical-verification.md → python/okstra_ctl/phases/technical_verification/profile.md} +1 -1
- package/runtime/python/okstra_ctl/{report_html/view_models/technical_verification.py → phases/technical_verification/report.py} +2 -2
- package/runtime/python/okstra_ctl/phases/technical_verification/spec.md +37 -0
- package/runtime/python/okstra_ctl/phases/technical_verification/validation.py +90 -0
- package/runtime/python/okstra_ctl/plan_approval.py +70 -0
- package/runtime/python/okstra_ctl/plan_items_cli.py +2 -2130
- package/runtime/python/okstra_ctl/profile_show.py +3 -3
- package/runtime/python/okstra_ctl/render.py +9 -2
- package/runtime/python/okstra_ctl/report_assembly.py +11 -90
- package/runtime/python/okstra_ctl/report_html/context_links.py +1 -1
- package/runtime/python/okstra_ctl/report_projections.py +1 -36
- package/runtime/python/okstra_ctl/report_routing.py +23 -0
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +4 -73
- package/runtime/python/okstra_ctl/report_validation_identity.py +38 -0
- package/runtime/python/okstra_ctl/report_views.py +1 -1
- package/runtime/python/okstra_ctl/run.py +67 -349
- package/runtime/python/okstra_ctl/stage_map.py +13 -0
- package/runtime/python/okstra_ctl/technical_verification_facts.py +52 -0
- package/runtime/python/okstra_ctl/wizard/__init__.py +31 -31
- package/runtime/python/okstra_ctl/wizard/api.py +18 -0
- package/runtime/python/okstra_ctl/wizard/outcome.py +3 -12
- package/runtime/python/okstra_ctl/wizard/registry.py +20 -12
- package/runtime/python/okstra_ctl/wizard/steps_analysis.py +0 -97
- package/runtime/python/okstra_ctl/wizard/steps_plan.py +10 -263
- package/runtime/python/okstra_ctl/wizard/steps_roles.py +2 -1
- package/runtime/python/okstra_ctl/work_categories.py +1 -1
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +36 -0
- package/runtime/python/okstra_ctl/workflow.py +26 -143
- package/runtime/skills/okstra-brief-gen/SKILL.md +3 -3
- package/runtime/skills/okstra-run/SKILL.md +1 -1
- package/runtime/templates/reports/quick-input.template.md +1 -1
- package/runtime/templates/reports/task-brief.template.md +1 -1
- package/runtime/validators/validate-brief.py +2 -2
- package/runtime/validators/validate-run.py +299 -3940
- package/runtime/validators/validate_analysis_report.py +14 -126
- package/runtime/python/okstra_ctl/report_html/view_models/implementation_planning.py +0 -147
- package/runtime/python/okstra_ctl/technical_verification.py +0 -195
- /package/runtime/{prompts/profiles/change-impact-analysis.json → python/okstra_ctl/phases/change_impact_analysis/profile.json} +0 -0
- /package/runtime/{prompts/profiles/change-impact-analysis.md → python/okstra_ctl/phases/change_impact_analysis/profile.md} +0 -0
- /package/runtime/{templates/reports → python/okstra_ctl/phases/change_impact_analysis/report_assets}/change-impact-analysis-input.template.md +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/change_impact_analysis/report_assets}/change-impact-analysis.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/change_impact_analysis/report_assets}/change-impact-analysis.template.md +0 -0
- /package/runtime/{prompts/profiles/error-analysis.json → python/okstra_ctl/phases/error_analysis/profile.json} +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/error_analysis/report_assets}/error-analysis.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/error_analysis/report_assets}/error-analysis.template.md +0 -0
- /package/runtime/{prompts/profiles/feature-analysis.json → python/okstra_ctl/phases/feature_analysis/profile.json} +0 -0
- /package/runtime/{prompts/profiles/feature-analysis.md → python/okstra_ctl/phases/feature_analysis/profile.md} +0 -0
- /package/runtime/{templates/reports → python/okstra_ctl/phases/feature_analysis/report_assets}/feature-analysis-input.template.md +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/feature_analysis/report_assets}/feature-analysis.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/feature_analysis/report_assets}/feature-analysis.template.md +0 -0
- /package/runtime/{prompts/profiles → python/okstra_ctl/phases/implementation/instructions}/_implementation-diff-review.md +0 -0
- /package/runtime/{prompts/profiles → python/okstra_ctl/phases/implementation/instructions}/_implementation-self-check.md +0 -0
- /package/runtime/{prompts/profiles/implementation.json → python/okstra_ctl/phases/implementation/profile.json} +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/implementation/report_assets}/implementation.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/implementation/report_assets}/implementation.template.md +0 -0
- /package/runtime/{prompts/profiles/implementation-option-selection.json → python/okstra_ctl/phases/implementation_option_selection/profile.json} +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/implementation_option_selection/report_assets}/implementation-option-selection.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/implementation_option_selection/report_assets}/implementation-option-selection.template.md +0 -0
- /package/runtime/{prompts/host-orchestration/implementation-planning.md → python/okstra_ctl/phases/implementation_planning/host-rules.md} +0 -0
- /package/runtime/{prompts/profiles/implementation-planning.json → python/okstra_ctl/phases/implementation_planning/profile.json} +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/implementation_planning/report_assets}/implementation-planning.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/implementation_planning/report_assets}/implementation-planning.template.md +0 -0
- /package/runtime/{prompts/profiles/improvement-discovery.json → python/okstra_ctl/phases/improvement_discovery/profile.json} +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/improvement_discovery/report_assets}/improvement-discovery.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/improvement_discovery/report_assets}/improvement-discovery.template.md +0 -0
- /package/runtime/{prompts/profiles/project-analysis.json → python/okstra_ctl/phases/project_analysis/profile.json} +0 -0
- /package/runtime/{prompts/profiles/project-analysis.md → python/okstra_ctl/phases/project_analysis/profile.md} +0 -0
- /package/runtime/{templates/reports → python/okstra_ctl/phases/project_analysis/report_assets}/project-analysis-input.template.md +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/project_analysis/report_assets}/project-analysis.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/project_analysis/report_assets}/project-analysis.template.md +0 -0
- /package/runtime/{prompts/profiles/release-handoff.json → python/okstra_ctl/phases/release_handoff/profile.json} +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/release_handoff/report_assets}/release-handoff.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/release_handoff/report_assets}/release-handoff.template.md +0 -0
- /package/runtime/python/okstra_ctl/{fanout.py → phases/requirements_discovery/fanout.py} +0 -0
- /package/runtime/{prompts/profiles/requirements-discovery.json → python/okstra_ctl/phases/requirements_discovery/profile.json} +0 -0
- /package/runtime/{templates/reports → python/okstra_ctl/phases/requirements_discovery/report_assets}/fan-out-unit.template.md +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/requirements_discovery/report_assets}/requirements-discovery.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/requirements_discovery/report_assets}/requirements-discovery.template.md +0 -0
- /package/runtime/{prompts/profiles/technical-verification.json → python/okstra_ctl/phases/technical_verification/profile.json} +0 -0
- /package/runtime/{templates/reports/html/tasks → python/okstra_ctl/phases/technical_verification/report_assets}/technical-verification.template.html +0 -0
- /package/runtime/{templates/reports/md/tasks → python/okstra_ctl/phases/technical_verification/report_assets}/technical-verification.template.md +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""방향 비교와 기술 검증이 함께 읽는 미확정 사실 계약."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from collections.abc import Mapping
|
|
5
|
+
from typing import Any, TypedDict
|
|
6
|
+
|
|
7
|
+
from .clarification_items import USER_INPUT_BLOCKS, progress_blocking_ids
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class VerificationFact(TypedDict):
|
|
11
|
+
id: str
|
|
12
|
+
candidateId: str
|
|
13
|
+
factIndex: int
|
|
14
|
+
fact: str
|
|
15
|
+
whyItMatters: str
|
|
16
|
+
evidence: list[str]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TechnicalVerificationError(ValueError):
|
|
20
|
+
"""시험 입력 또는 관측 결과가 원본 사실과 일치하지 않는다."""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def technical_verification_facts(data: Mapping[str, Any]) -> list[VerificationFact]:
|
|
24
|
+
"""안전 차단이 없는 후보의 명시적인 기술 검증 사실만 추출한다."""
|
|
25
|
+
blockers = progress_blocking_ids(
|
|
26
|
+
data.get("clarificationItems"), USER_INPUT_BLOCKS, report_data=data
|
|
27
|
+
)
|
|
28
|
+
if blockers:
|
|
29
|
+
raise TechnicalVerificationError(
|
|
30
|
+
"unresolved user decisions: " + ", ".join(blockers)
|
|
31
|
+
)
|
|
32
|
+
selection = data.get("implementationOptionSelection") or {}
|
|
33
|
+
facts: list[VerificationFact] = []
|
|
34
|
+
for candidate in selection.get("candidateAudit") or []:
|
|
35
|
+
if candidate.get("safetyBlockers"):
|
|
36
|
+
continue
|
|
37
|
+
for index, fact in enumerate(candidate.get("unresolvedFeasibilityFacts") or []):
|
|
38
|
+
if fact.get("resolutionKind") != "technical-verification":
|
|
39
|
+
continue
|
|
40
|
+
facts.append(
|
|
41
|
+
{
|
|
42
|
+
"id": f"TV-{len(facts) + 1:03d}",
|
|
43
|
+
"candidateId": candidate["id"],
|
|
44
|
+
"factIndex": index,
|
|
45
|
+
"fact": fact["fact"],
|
|
46
|
+
"whyItMatters": fact["whyItMatters"],
|
|
47
|
+
"evidence": fact["evidence"],
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
if not facts:
|
|
51
|
+
raise TechnicalVerificationError("no eligible technical-verification facts")
|
|
52
|
+
return facts
|
|
@@ -15,11 +15,11 @@ Public surface (re-exported here; the skill calls it through the
|
|
|
15
15
|
- ``render_args()`` - final args for ``okstra render-bundle`` (``render``).
|
|
16
16
|
- ``wizard_outcome()`` - final args plus persistence actions and confirmation (``render``).
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
``tests/contract/test_no_import_cycles.py`` keeps it that way.
|
|
18
|
+
Package initialization loads identifiers and state types only. Public execution
|
|
19
|
+
functions are composed by ``api`` when requested. Phase modules can import state
|
|
20
|
+
and prompt readers without initializing the registry that imports those phases.
|
|
22
21
|
"""
|
|
22
|
+
|
|
23
23
|
from __future__ import annotations
|
|
24
24
|
|
|
25
25
|
from .ids import (
|
|
@@ -118,31 +118,31 @@ from .state import (
|
|
|
118
118
|
WizardError,
|
|
119
119
|
WizardState,
|
|
120
120
|
)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
next_prompt,
|
|
138
|
-
prompt_payload,
|
|
139
|
-
submit,
|
|
140
|
-
)
|
|
141
|
-
from .render import (
|
|
142
|
-
render_args,
|
|
143
|
-
render_role_args,
|
|
144
|
-
)
|
|
145
|
-
from .outcome import wizard_outcome
|
|
146
|
-
from .cli import (
|
|
147
|
-
main,
|
|
121
|
+
|
|
122
|
+
_API_EXPORTS = (
|
|
123
|
+
"next_role_prompt",
|
|
124
|
+
"load_state_file",
|
|
125
|
+
"save_state_file",
|
|
126
|
+
"confirmation_block",
|
|
127
|
+
"STEPS",
|
|
128
|
+
"STEP_BY_ID",
|
|
129
|
+
"init_state",
|
|
130
|
+
"next_prompt",
|
|
131
|
+
"prompt_payload",
|
|
132
|
+
"submit",
|
|
133
|
+
"render_args",
|
|
134
|
+
"render_role_args",
|
|
135
|
+
"wizard_outcome",
|
|
136
|
+
"main",
|
|
148
137
|
)
|
|
138
|
+
|
|
139
|
+
__all__ = [name for name in globals() if not name.startswith("_")] + list(_API_EXPORTS)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def __getattr__(name: str):
|
|
143
|
+
"""기존 공개 이름을 실행 조립 모듈에 연결한다."""
|
|
144
|
+
if name not in _API_EXPORTS:
|
|
145
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
146
|
+
from . import api
|
|
147
|
+
|
|
148
|
+
return getattr(api, name)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""질문 실행기의 공개 조립 지점. 단계의 값·프롬프트 판독에서는 적재하지 않는다."""
|
|
2
|
+
|
|
3
|
+
from .roles import next_role_prompt as next_role_prompt
|
|
4
|
+
from .statefile import (
|
|
5
|
+
load_state_file as load_state_file,
|
|
6
|
+
save_state_file as save_state_file,
|
|
7
|
+
)
|
|
8
|
+
from .confirmation import confirmation_block as confirmation_block
|
|
9
|
+
from .registry import STEPS as STEPS, STEP_BY_ID as STEP_BY_ID
|
|
10
|
+
from .engine import (
|
|
11
|
+
init_state as init_state,
|
|
12
|
+
next_prompt as next_prompt,
|
|
13
|
+
prompt_payload as prompt_payload,
|
|
14
|
+
submit as submit,
|
|
15
|
+
)
|
|
16
|
+
from .render import render_args as render_args, render_role_args as render_role_args
|
|
17
|
+
from .outcome import wizard_outcome as wizard_outcome
|
|
18
|
+
from .cli import main as main
|
|
@@ -25,18 +25,9 @@ def _render_argv(rendered: dict[str, Any], *, host_runtime: str) -> list[str]:
|
|
|
25
25
|
def _wizard_persist_actions(state: WizardState) -> list[dict[str, str]]:
|
|
26
26
|
if state.task_type != "release-handoff":
|
|
27
27
|
return []
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return []
|
|
32
|
-
return [
|
|
33
|
-
{
|
|
34
|
-
"command": "config.set",
|
|
35
|
-
"key": "pr-template-path",
|
|
36
|
-
"scope": state.pr_template_scope,
|
|
37
|
-
"value": state.pr_template_path,
|
|
38
|
-
}
|
|
39
|
-
]
|
|
28
|
+
from okstra_ctl.phases.release_handoff.wizard import pr_template_persist_actions
|
|
29
|
+
|
|
30
|
+
return pr_template_persist_actions(state)
|
|
40
31
|
|
|
41
32
|
|
|
42
33
|
def wizard_outcome(state: WizardState) -> dict[str, Any]:
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
"""단계 등록표 — 순서가 곧 질문 순서인 `STEPS`, `STEP_BY_ID`, 등록표를 되감는 `_reset_from` 과 되감기를 일으키는 단계(edit target, brief carry)."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
+
from okstra_ctl.phases.change_impact_analysis.entry import (
|
|
5
|
+
_build_feature_evidence,
|
|
6
|
+
_build_feature_evidence_pick,
|
|
7
|
+
_submit_feature_evidence,
|
|
8
|
+
_submit_feature_evidence_pick,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from okstra_ctl.phases.implementation_planning.wizard import (
|
|
12
|
+
_selected_direction_candidates,
|
|
13
|
+
_planning_rerun_selected,
|
|
14
|
+
_build_selected_direction_pick,
|
|
15
|
+
_submit_selected_direction_pick,
|
|
16
|
+
)
|
|
17
|
+
|
|
4
18
|
from typing import Optional
|
|
5
19
|
|
|
6
20
|
from .ids import (
|
|
@@ -119,27 +133,25 @@ from .steps_identity import (
|
|
|
119
133
|
_submit_task_type,
|
|
120
134
|
_submit_task_type_text,
|
|
121
135
|
)
|
|
122
|
-
from .
|
|
123
|
-
_analysis_inputs_after_reuse,
|
|
136
|
+
from okstra_ctl.phases.feature_analysis.wizard import (
|
|
124
137
|
_build_analysis_target,
|
|
125
138
|
_build_analysis_target_pick,
|
|
139
|
+
_submit_analysis_target,
|
|
140
|
+
_submit_analysis_target_pick,
|
|
141
|
+
)
|
|
142
|
+
from .steps_analysis import (
|
|
143
|
+
_analysis_inputs_after_reuse,
|
|
126
144
|
_build_design_prep_confirm,
|
|
127
145
|
_build_design_prep_decision,
|
|
128
146
|
_build_design_prep_overrides,
|
|
129
|
-
_build_feature_evidence,
|
|
130
|
-
_build_feature_evidence_pick,
|
|
131
147
|
_build_project_evidence,
|
|
132
148
|
_build_project_evidence_pick,
|
|
133
149
|
_design_prep_confirm_applies,
|
|
134
150
|
_design_prep_decision_applies,
|
|
135
151
|
_design_prep_overrides_applies,
|
|
136
|
-
_submit_analysis_target,
|
|
137
|
-
_submit_analysis_target_pick,
|
|
138
152
|
_submit_design_prep_confirm,
|
|
139
153
|
_submit_design_prep_decision,
|
|
140
154
|
_submit_design_prep_overrides,
|
|
141
|
-
_submit_feature_evidence,
|
|
142
|
-
_submit_feature_evidence_pick,
|
|
143
155
|
_submit_project_evidence,
|
|
144
156
|
_submit_project_evidence_pick,
|
|
145
157
|
)
|
|
@@ -151,12 +163,9 @@ from .steps_plan import (
|
|
|
151
163
|
_build_handoff_stage_pick,
|
|
152
164
|
_build_reverify_scope_pick,
|
|
153
165
|
_build_reverify_scope_stages,
|
|
154
|
-
_build_selected_direction_pick,
|
|
155
166
|
_build_stage_pick,
|
|
156
167
|
_fix_cycle_confirm_required,
|
|
157
|
-
_planning_rerun_selected,
|
|
158
168
|
_reverify_scope_step_pending,
|
|
159
|
-
_selected_direction_candidates,
|
|
160
169
|
_submit_approve_plan_confirm,
|
|
161
170
|
_submit_approved_plan,
|
|
162
171
|
_submit_approved_plan_pick,
|
|
@@ -164,7 +173,6 @@ from .steps_plan import (
|
|
|
164
173
|
_submit_handoff_stage_pick,
|
|
165
174
|
_submit_reverify_scope_pick,
|
|
166
175
|
_submit_reverify_scope_stages,
|
|
167
|
-
_submit_selected_direction_pick,
|
|
168
176
|
_submit_stage_pick,
|
|
169
177
|
)
|
|
170
178
|
from .steps_options import (
|
|
@@ -12,7 +12,6 @@ from okstra_ctl.analysis_inputs import (
|
|
|
12
12
|
AnalysisReportCandidate,
|
|
13
13
|
list_evidence_candidates,
|
|
14
14
|
load_analysis_report_candidate,
|
|
15
|
-
resolve_analysis_target,
|
|
16
15
|
resolve_evidence_inputs,
|
|
17
16
|
)
|
|
18
17
|
from okstra_ctl.design_prep import (
|
|
@@ -25,13 +24,9 @@ from okstra_ctl.design_prep import (
|
|
|
25
24
|
from .ids import (
|
|
26
25
|
PICK_SKIP,
|
|
27
26
|
PICK_TYPE_CUSTOM,
|
|
28
|
-
S_ANALYSIS_TARGET,
|
|
29
|
-
S_ANALYSIS_TARGET_PICK,
|
|
30
27
|
S_DESIGN_PREP_CONFIRM,
|
|
31
28
|
S_DESIGN_PREP_DECISION,
|
|
32
29
|
S_DESIGN_PREP_OVERRIDES,
|
|
33
|
-
S_FEATURE_EVIDENCE,
|
|
34
|
-
S_FEATURE_EVIDENCE_PICK,
|
|
35
30
|
S_PROJECT_EVIDENCE,
|
|
36
31
|
S_PROJECT_EVIDENCE_PICK,
|
|
37
32
|
_RESUME_REUSE_PHASES,
|
|
@@ -128,32 +123,6 @@ def _submit_analysis_evidence_pick(
|
|
|
128
123
|
return t["echo_variants"]["selected"].format(path=candidate.report_path)
|
|
129
124
|
|
|
130
125
|
|
|
131
|
-
def _build_feature_evidence_pick(state: WizardState) -> Prompt:
|
|
132
|
-
return _build_analysis_evidence_pick(
|
|
133
|
-
state, step=S_FEATURE_EVIDENCE_PICK, relation="feature-baseline"
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def _submit_feature_evidence_pick(state: WizardState, value: str) -> Optional[str]:
|
|
138
|
-
return _submit_analysis_evidence_pick(
|
|
139
|
-
state, value, step=S_FEATURE_EVIDENCE_PICK,
|
|
140
|
-
field_name="feature_evidence_path",
|
|
141
|
-
pending_name="feature_evidence_pending_text",
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def _build_feature_evidence(state: WizardState) -> Prompt:
|
|
146
|
-
t = _p(state.workspace_root, S_FEATURE_EVIDENCE)
|
|
147
|
-
return Prompt(step=S_FEATURE_EVIDENCE, kind="text", label=t["label"],
|
|
148
|
-
echo_template=t["echo_template"])
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def _submit_feature_evidence(state: WizardState, value: str) -> Optional[str]:
|
|
152
|
-
candidate = _accept_analysis_evidence(state, value, "feature_evidence_path")
|
|
153
|
-
state.feature_evidence_pending_text = False
|
|
154
|
-
return f"feature-evidence: {candidate.report_path}"
|
|
155
|
-
|
|
156
|
-
|
|
157
126
|
def _build_project_evidence_pick(state: WizardState) -> Prompt:
|
|
158
127
|
return _build_analysis_evidence_pick(
|
|
159
128
|
state, step=S_PROJECT_EVIDENCE_PICK, relation="project-context"
|
|
@@ -181,72 +150,6 @@ def _submit_project_evidence(state: WizardState, value: str) -> Optional[str]:
|
|
|
181
150
|
return f"project-evidence: {candidate.report_path}"
|
|
182
151
|
|
|
183
152
|
|
|
184
|
-
def _feature_description(feature: dict[object, object]) -> str:
|
|
185
|
-
name = str(feature.get("name") or "")
|
|
186
|
-
summary = str(feature.get("summary") or "")
|
|
187
|
-
entry_point = str(
|
|
188
|
-
feature.get("entryPoint") or feature.get("entrypoint") or ""
|
|
189
|
-
)
|
|
190
|
-
return " · ".join(value for value in (name, summary, entry_point) if value)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
def _build_analysis_target_pick(state: WizardState) -> Prompt:
|
|
194
|
-
t = _p(state.workspace_root, S_ANALYSIS_TARGET_PICK)
|
|
195
|
-
try:
|
|
196
|
-
candidate = load_analysis_report_candidate(
|
|
197
|
-
Path(state.project_root), Path(state.project_evidence_path)
|
|
198
|
-
)
|
|
199
|
-
except AnalysisInputError as exc:
|
|
200
|
-
raise WizardError(str(exc)) from exc
|
|
201
|
-
options = [
|
|
202
|
-
_opt(str(feature["id"]), str(feature["id"]), _feature_description(feature))
|
|
203
|
-
for feature in candidate.feature_index
|
|
204
|
-
if isinstance(feature, dict) and isinstance(feature.get("id"), str)
|
|
205
|
-
][:3]
|
|
206
|
-
options.append(_opt(PICK_TYPE_CUSTOM, t["options"][PICK_TYPE_CUSTOM]))
|
|
207
|
-
return Prompt(step=S_ANALYSIS_TARGET_PICK, kind="pick", label=t["label"],
|
|
208
|
-
options=options, echo_template=t["echo_template"])
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
def _accept_analysis_target(state: WizardState, value: str) -> str:
|
|
212
|
-
candidates: dict[Path, AnalysisReportCandidate] = {}
|
|
213
|
-
for path in _analysis_evidence_paths(state):
|
|
214
|
-
try:
|
|
215
|
-
candidate = load_analysis_report_candidate(Path(state.project_root), path)
|
|
216
|
-
except AnalysisInputError as exc:
|
|
217
|
-
raise WizardError(str(exc)) from exc
|
|
218
|
-
candidates[candidate.report_path] = candidate
|
|
219
|
-
try:
|
|
220
|
-
target = resolve_analysis_target(
|
|
221
|
-
value, _resolve_analysis_evidence(state), candidates
|
|
222
|
-
)
|
|
223
|
-
except AnalysisInputError as exc:
|
|
224
|
-
raise WizardError(str(exc)) from exc
|
|
225
|
-
requested_value = target["requestedValue"]
|
|
226
|
-
if not isinstance(requested_value, str):
|
|
227
|
-
raise WizardError("analysis target resolver returned an invalid requestedValue")
|
|
228
|
-
state.analysis_target = requested_value
|
|
229
|
-
state.analysis_target_pending_text = False
|
|
230
|
-
return requested_value
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
def _submit_analysis_target_pick(state: WizardState, value: str) -> Optional[str]:
|
|
234
|
-
if value == PICK_TYPE_CUSTOM:
|
|
235
|
-
state.analysis_target_pending_text = True
|
|
236
|
-
return None
|
|
237
|
-
return f"analysis-target: {_accept_analysis_target(state, value)}"
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
def _build_analysis_target(state: WizardState) -> Prompt:
|
|
241
|
-
t = _p(state.workspace_root, S_ANALYSIS_TARGET)
|
|
242
|
-
return Prompt(step=S_ANALYSIS_TARGET, kind="text", label=t["label"],
|
|
243
|
-
echo_template=t["echo_template"])
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
def _submit_analysis_target(state: WizardState, value: str) -> Optional[str]:
|
|
247
|
-
return f"analysis-target: {_accept_analysis_target(state, value)}"
|
|
248
|
-
|
|
249
|
-
|
|
250
153
|
def _design_prep_items_by_id(state: WizardState) -> dict[str, dict[str, Any]]:
|
|
251
154
|
try:
|
|
252
155
|
items = load_design_prep_items(Path(state.approved_plan_path))
|