okstra 0.34.1 → 0.36.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.
Files changed (108) hide show
  1. package/README.kr.md +27 -19
  2. package/README.md +27 -19
  3. package/docs/kr/architecture.md +59 -45
  4. package/docs/kr/cli.md +61 -18
  5. package/docs/pr-template-usage.md +65 -0
  6. package/docs/project-structure-overview.md +353 -354
  7. package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +1 -1
  8. package/docs/superpowers/plans/2026-05-14-convergence-queue-pruning.md +1 -1
  9. package/docs/superpowers/plans/2026-05-17-dual-format-final-report.md +1 -1
  10. package/docs/superpowers/plans/2026-05-20-final-report-language.md +1501 -0
  11. package/docs/superpowers/plans/2026-05-20-implementation-planning-multi-stage.md +1267 -0
  12. package/docs/superpowers/plans/2026-05-20-okstra-run-prompt-sot-b1.md +1007 -0
  13. package/docs/superpowers/plans/2026-05-20-wizard-messages-json-sot.md +720 -0
  14. package/docs/superpowers/plans/2026-05-20-wizard-prompt-json-sot-a1.md +681 -0
  15. package/docs/superpowers/plans/2026-05-21-improvement-discovery-task-type.md +1691 -0
  16. package/docs/superpowers/plans/2026-05-24-implementation-lead-context-slimming.md +1700 -0
  17. package/docs/superpowers/specs/2026-05-20-final-report-language-design.md +383 -0
  18. package/docs/superpowers/specs/2026-05-20-implementation-planning-multi-stage-design.md +320 -0
  19. package/docs/superpowers/specs/2026-05-20-okstra-run-prompt-sot-design.md +299 -0
  20. package/docs/superpowers/specs/2026-05-21-improvement-discovery-task-type-design.md +335 -0
  21. package/docs/task-process/README.md +74 -0
  22. package/docs/task-process/common-flow.md +166 -0
  23. package/docs/task-process/error-analysis.md +101 -0
  24. package/docs/task-process/final-verification.md +167 -0
  25. package/docs/task-process/implementation-planning.md +128 -0
  26. package/docs/task-process/implementation.md +149 -0
  27. package/docs/task-process/release-handoff.md +206 -0
  28. package/docs/task-process/requirements-discovery.md +115 -0
  29. package/package.json +1 -1
  30. package/runtime/BUILD.json +2 -2
  31. package/runtime/agents/SKILL.md +30 -7
  32. package/runtime/agents/workers/claude-worker.md +31 -6
  33. package/runtime/agents/workers/codex-worker.md +37 -10
  34. package/runtime/agents/workers/gemini-worker.md +34 -7
  35. package/runtime/agents/workers/report-writer-worker.md +19 -10
  36. package/runtime/bin/okstra-central.sh +6 -6
  37. package/runtime/bin/okstra-codex-exec.sh +49 -28
  38. package/runtime/bin/okstra-gemini-exec.sh +39 -21
  39. package/runtime/bin/okstra-render-final-report.py +13 -2
  40. package/runtime/bin/okstra-wrapper-status.py +155 -0
  41. package/runtime/bin/okstra.sh +2 -2
  42. package/runtime/prompts/launch.template.md +1 -0
  43. package/runtime/prompts/profiles/_common-contract.md +11 -6
  44. package/runtime/prompts/profiles/_implementation-deliverable.md +53 -0
  45. package/runtime/prompts/profiles/_implementation-executor.md +60 -0
  46. package/runtime/prompts/profiles/_implementation-verifier.md +76 -0
  47. package/runtime/prompts/profiles/error-analysis.md +3 -7
  48. package/runtime/prompts/profiles/implementation-planning.md +22 -21
  49. package/runtime/prompts/profiles/implementation.md +28 -118
  50. package/runtime/prompts/profiles/improvement-discovery.md +42 -0
  51. package/runtime/prompts/profiles/release-handoff.md +1 -1
  52. package/runtime/prompts/profiles/requirements-discovery.md +8 -12
  53. package/runtime/prompts/wizard/prompts.ko.json +230 -0
  54. package/runtime/python/lib/okstra/cli.sh +2 -49
  55. package/runtime/python/lib/okstra/globals.sh +21 -21
  56. package/runtime/python/lib/okstra/interactive.sh +7 -7
  57. package/runtime/python/okstra_ctl/clarification_items.py +3 -9
  58. package/runtime/python/okstra_ctl/consumers.py +53 -0
  59. package/runtime/python/okstra_ctl/final_report_schema.py +0 -7
  60. package/runtime/python/okstra_ctl/i18n.py +73 -0
  61. package/runtime/python/okstra_ctl/improvement_lenses.py +44 -0
  62. package/runtime/python/okstra_ctl/index.py +1 -1
  63. package/runtime/python/okstra_ctl/paths.py +26 -20
  64. package/runtime/python/okstra_ctl/render.py +166 -207
  65. package/runtime/python/okstra_ctl/render_final_report.py +53 -10
  66. package/runtime/python/okstra_ctl/run.py +299 -108
  67. package/runtime/python/okstra_ctl/run_context.py +22 -0
  68. package/runtime/python/okstra_ctl/seeding.py +186 -0
  69. package/runtime/python/okstra_ctl/session.py +65 -7
  70. package/runtime/python/okstra_ctl/wizard.py +348 -127
  71. package/runtime/python/okstra_ctl/workflow.py +21 -2
  72. package/runtime/python/okstra_ctl/worktree.py +54 -1
  73. package/runtime/python/okstra_project/resolver.py +4 -3
  74. package/runtime/python/okstra_token_usage/report.py +2 -2
  75. package/runtime/schemas/final-report-v1.0.schema.json +22 -16
  76. package/runtime/skills/okstra-brief/SKILL.md +102 -218
  77. package/runtime/skills/okstra-convergence/SKILL.md +2 -3
  78. package/runtime/skills/okstra-inspect/SKILL.md +581 -0
  79. package/runtime/skills/okstra-report-writer/SKILL.md +35 -15
  80. package/runtime/skills/okstra-run/SKILL.md +8 -7
  81. package/runtime/skills/okstra-schedule/SKILL.md +14 -157
  82. package/runtime/skills/okstra-setup/SKILL.md +28 -1
  83. package/runtime/skills/okstra-team-contract/SKILL.md +16 -107
  84. package/runtime/templates/okstra.CLAUDE.md +104 -0
  85. package/runtime/templates/reports/brief.template.md +204 -0
  86. package/runtime/templates/reports/final-report.template.md +93 -98
  87. package/runtime/templates/reports/i18n/en.json +135 -0
  88. package/runtime/templates/reports/i18n/ko.json +135 -0
  89. package/runtime/templates/reports/implementation-planning-input.template.md +18 -0
  90. package/runtime/templates/reports/improvement-discovery-input.template.md +78 -0
  91. package/runtime/templates/reports/schedule.template.md +12 -3
  92. package/runtime/templates/reports/task-brief.template.md +2 -2
  93. package/runtime/templates/worker-prompt-preamble.md +108 -0
  94. package/runtime/validators/lib/fixtures.sh +30 -0
  95. package/runtime/validators/lib/runners.sh +1 -1
  96. package/runtime/validators/validate-implementation-plan-stages.py +211 -0
  97. package/runtime/validators/validate-run.py +121 -26
  98. package/runtime/validators/validate-workflow.sh +2 -2
  99. package/runtime/validators/validate_improvement_report.py +275 -0
  100. package/src/config.mjs +18 -0
  101. package/src/install.mjs +41 -14
  102. package/src/setup.mjs +133 -1
  103. package/src/uninstall.mjs +27 -3
  104. package/runtime/skills/okstra-history/SKILL.md +0 -165
  105. package/runtime/skills/okstra-logs/SKILL.md +0 -173
  106. package/runtime/skills/okstra-report-finder/SKILL.md +0 -111
  107. package/runtime/skills/okstra-status/SKILL.md +0 -246
  108. package/runtime/skills/okstra-time-summary/SKILL.md +0 -172
@@ -20,6 +20,7 @@ PHASE_SEQUENCE = [
20
20
 
21
21
  DEFAULT_NEXT_PHASE = {
22
22
  "requirements-discovery": "pending-routing-decision",
23
+ "improvement-discovery": "pending-routing-decision",
23
24
  "error-analysis": "implementation-planning",
24
25
  "implementation-planning": "implementation",
25
26
  "implementation": "final-verification",
@@ -47,6 +48,24 @@ PHASE_RULES: dict[str, dict[str, str]] = {
47
48
  " - starting `error-analysis`, `implementation-planning`, or `implementation` inside this run (each must be a separate run, and `implementation` additionally requires an approved `implementation-planning` deliverable)"
48
49
  ),
49
50
  },
51
+ "improvement-discovery": {
52
+ "allowed": (
53
+ " - improvement candidate discovery within the lens whitelist defined in `scripts/okstra_ctl/improvement_lenses.py`\n"
54
+ " - top-N ranking (default 8, brief `candidate-cap` overrides within 1..12)\n"
55
+ " - per-candidate columns Lens / Scope / Severity / Effort / Consensus / Source workers / Recommended next-phase / Evidence (path:line)\n"
56
+ " - Phase 1.5 reflect-back grilling log at `runs/improvement-discovery/<seq>/state/phase-1.5-grilling.md`\n"
57
+ " - Phase 5.5 consensus classification (full / partial / contested / worker-unique)"
58
+ ),
59
+ "forbidden": (
60
+ " - source code edits of any kind\n"
61
+ " - implementation planning, root-cause analysis, builds, migrations, or deployments\n"
62
+ " - starting `implementation-planning`, `implementation`, `error-analysis`, or any other lifecycle phase inside this run\n"
63
+ " - generating candidates outside the lens whitelist (Lens enum violation rejects the report)\n"
64
+ " - exceeding the candidate cap (absolute cap 12)\n"
65
+ " - free external data fetch beyond the brief's Source Material or Phase 1.5 resolved scope\n"
66
+ " - interpreting user phrases like `다음 단계 진행해` as authorisation to enter another phase"
67
+ ),
68
+ },
50
69
  "error-analysis": {
51
70
  "allowed": (
52
71
  " - symptom and trigger evidence\n"
@@ -69,7 +88,7 @@ PHASE_RULES: dict[str, dict[str, str]] = {
69
88
  " - bite-sized stepwise execution order for the recommended option (each step ~2-5 min, exact file paths and commands, TDD ordering when applicable, no placeholders)\n"
70
89
  " - dependency / migration risk assessment, validation checklist (pre / mid / post with exact commands), rollback strategy with revert path and trigger signal\n"
71
90
  " - every unresolved ambiguity registered as a `Blocks=approval` row in the `## 5. Clarification Items` table (do NOT create a separate `Open Questions` block under `4.5.x` — the unified table is the single home)\n"
72
- " - explicit `User Approval Request` block awaiting human approval\n"
91
+ " - YAML frontmatter line `approved: false` awaiting human flip to `true`\n"
73
92
  " - self-review confirmation (spec coverage, placeholder scan, internal consistency, ambiguity, scope)"
74
93
  ),
75
94
  "forbidden": (
@@ -95,7 +114,7 @@ PHASE_RULES: dict[str, dict[str, str]] = {
95
114
  " - routing recommendation for `final-verification` (ready / needs new error-analysis or planning loop)"
96
115
  ),
97
116
  "forbidden": (
98
- " - any Edit/Write or state-mutating Bash before the pre-implementation gate passes (gate requires --approved-plan pointing to a final-report.md with a recorded user approval marker)\n"
117
+ " - any Edit/Write or state-mutating Bash before the pre-implementation gate passes (gate requires --approved-plan pointing to a final-report.md whose frontmatter has `approved: true`)\n"
99
118
  " - `git push` of any kind, `npm publish` / `cargo publish` / `pip publish`, `gh release`, `docker push`\n"
100
119
  " - real database migrations, schema changes against shared environments, or writes to non-local datastores\n"
101
120
  " - production credentials, deploy commands, infra mutation (`terraform apply`, `kubectl apply` against non-local cluster, etc.)\n"
@@ -43,7 +43,14 @@ from typing import Optional
43
43
 
44
44
  from .ids import _safe_fs_segment
45
45
  from . import worktree_registry
46
- from .seeding import SettingsLinkError, ensure_project_settings_symlink
46
+ from .seeding import (
47
+ AgentsMdLinkError,
48
+ ClaudeMdLinkError,
49
+ SettingsLinkError,
50
+ ensure_project_agents_md,
51
+ ensure_project_claude_md,
52
+ ensure_project_settings_symlink,
53
+ )
47
54
 
48
55
 
49
56
  # Project-root directories that hold okstra task state, ignored by git, or
@@ -390,6 +397,48 @@ def _seed_worktree_settings_symlink(worktree_path: Path) -> None:
390
397
  )
391
398
 
392
399
 
400
+ def _seed_worktree_claude_md(worktree_path: Path) -> None:
401
+ """Seed `.project-docs/okstra/CLAUDE.md` symlink + `<worktree>/CLAUDE.md`
402
+ import block in the worker worktree so dispatched Claude sessions auto-load
403
+ okstra's runtime guidance. Mirrors `_seed_worktree_settings_symlink` —
404
+ needed because the worktree's `CLAUDE.md` comes from the git checkout (no
405
+ marker block unless committed) and `.project-docs/` is only dir-symlinked,
406
+ not its contents.
407
+ """
408
+ try:
409
+ link = ensure_project_claude_md(project_root=worktree_path)
410
+ except ClaudeMdLinkError as exc:
411
+ print(
412
+ f"okstra-claude-md: failed to seed worker worktree CLAUDE.md at "
413
+ f"{worktree_path} — dispatched Claude sessions will not auto-load "
414
+ f"okstra guidance. ({exc})",
415
+ file=__import__("sys").stderr,
416
+ )
417
+ return
418
+ if link is None:
419
+ print(
420
+ "okstra-claude-md: ~/.okstra/templates/okstra.CLAUDE.md missing — "
421
+ "re-run 'npx okstra@latest install' to provision the symlink target.",
422
+ file=__import__("sys").stderr,
423
+ )
424
+
425
+
426
+ def _seed_worktree_agents_md(worktree_path: Path) -> None:
427
+ """Seed `<worktree>/AGENTS.md` symlink so codex / aider sessions dispatched
428
+ into this worktree auto-load okstra's guidance. Only acts when AGENTS.md
429
+ is absent — never overwrites user content.
430
+ """
431
+ try:
432
+ ensure_project_agents_md(project_root=worktree_path)
433
+ except AgentsMdLinkError as exc:
434
+ print(
435
+ f"okstra-agents-md: failed to seed worker worktree AGENTS.md at "
436
+ f"{worktree_path} — dispatched codex / aider sessions will not "
437
+ f"auto-load okstra guidance. ({exc})",
438
+ file=__import__("sys").stderr,
439
+ )
440
+
441
+
393
442
  def _copy_snapshot_files(source_root: Path, worktree_path: Path) -> list[str]:
394
443
  """Copy fixture files from MAIN → task worktree as read-only snapshots
395
444
  (FU-V3).
@@ -515,6 +564,8 @@ def provision_task_worktree(
515
564
  if existing is not None and existing.status == "active":
516
565
  worktree_registry.touch_phase(safe_project, safe_group, safe_task, task_type)
517
566
  _seed_worktree_settings_symlink(Path(existing.worktree_path))
567
+ _seed_worktree_claude_md(Path(existing.worktree_path))
568
+ _seed_worktree_agents_md(Path(existing.worktree_path))
518
569
  return WorktreeProvision(
519
570
  status="reused",
520
571
  path=existing.worktree_path,
@@ -617,6 +668,8 @@ def provision_task_worktree(
617
668
  raise
618
669
 
619
670
  _seed_worktree_settings_symlink(worktree_path)
671
+ _seed_worktree_claude_md(worktree_path)
672
+ _seed_worktree_agents_md(worktree_path)
620
673
 
621
674
  base_label = (
622
675
  f"{base_origin} @ {resolved_base_ref[:12]}"
@@ -118,9 +118,10 @@ def upsert_project_json(project_root: Path, project_id: str, *,
118
118
  f"under a different id. "
119
119
  f"(projectId 불일치: 한 PROJECT_ROOT 에는 하나의 projectId 만 허용됩니다.)")
120
120
  # Preserve any user-managed fields (e.g. `worktreeSyncDirs`,
121
- # `mcpServers`) so manual edits to project.json are not wiped
122
- # by the per-run self-registration upsert. Only the canonical
123
- # identity/timestamp fields below are owned by this function.
121
+ # `qaCommands`, `prTemplatePath`, `reportLanguage`, `mcpServers`) so
122
+ # manual edits to project.json are not wiped by the per-run
123
+ # self-registration upsert. Only the canonical identity/timestamp
124
+ # fields below are owned by this function.
124
125
  result = dict(data) if isinstance(data, dict) else {}
125
126
  result["projectId"] = project_id
126
127
  result["projectRoot"] = abs_root
@@ -15,7 +15,7 @@ if str(_HERE) not in sys.path:
15
15
  sys.path.insert(0, str(_HERE))
16
16
 
17
17
  from okstra_ctl.render_final_report import ( # noqa: E402
18
- RenderError,
18
+ FinalReportRenderError,
19
19
  render_to_file,
20
20
  )
21
21
 
@@ -171,6 +171,6 @@ def populate_and_render(
171
171
 
172
172
  try:
173
173
  bytes_written = render_to_file(data_path, output_path)
174
- except RenderError as exc:
174
+ except FinalReportRenderError as exc:
175
175
  raise SubstituteRefusedError(f"render after substitute failed: {exc}") from exc
176
176
  return changes, bytes_written
@@ -6,6 +6,7 @@
6
6
  "type": "object",
7
7
  "required": [
8
8
  "schemaVersion",
9
+ "meta",
9
10
  "frontmatter",
10
11
  "header",
11
12
  "verdictCard",
@@ -27,6 +28,19 @@
27
28
  "description": "Schema version. Renderer refuses to process unknown versions."
28
29
  },
29
30
 
31
+ "meta": {
32
+ "type": "object",
33
+ "additionalProperties": true,
34
+ "required": ["reportLanguage"],
35
+ "properties": {
36
+ "reportLanguage": {
37
+ "type": "string",
38
+ "enum": ["en", "ko"],
39
+ "description": "Resolved language used for prose + i18n dictionary. 'auto' must be resolved to 'en' or 'ko' by the lead before the report-writer worker writes data.json."
40
+ }
41
+ }
42
+ },
43
+
30
44
  "frontmatter": {
31
45
  "type": "object",
32
46
  "required": [
@@ -40,7 +54,8 @@
40
54
  "taskGroup",
41
55
  "projectId",
42
56
  "taskType",
43
- "workerId"
57
+ "workerId",
58
+ "approved"
44
59
  ],
45
60
  "additionalProperties": false,
46
61
  "properties": {
@@ -64,7 +79,11 @@
64
79
  "taskGroup": { "type": "string", "minLength": 1 },
65
80
  "projectId": { "type": "string", "minLength": 1 },
66
81
  "taskType": { "$ref": "#/$defs/TaskType" },
67
- "workerId": { "const": "report-writer" }
82
+ "workerId": { "const": "report-writer" },
83
+ "approved": {
84
+ "type": "boolean",
85
+ "description": "사용자 승인 플래그. report-writer 는 항상 false 로 발행하고, 사용자가 `--approve` 또는 직접 편집으로 true 로 토글합니다. `implementation` task-type 의 prepare 단계가 `--approved-plan` 으로 지정된 보고서의 이 필드를 읽어 진입 여부를 결정합니다. 다른 task-type 에서는 의미 없이 false 로 유지됩니다."
86
+ }
68
87
  }
69
88
  },
70
89
 
@@ -94,19 +113,6 @@
94
113
  }
95
114
  },
96
115
 
97
- "approvalBlock": {
98
- "type": "object",
99
- "description": "RENDER_IF taskType == implementation-planning. Renderer emits the User Approval Request section.",
100
- "required": ["approved"],
101
- "additionalProperties": false,
102
- "properties": {
103
- "approved": {
104
- "type": "boolean",
105
- "description": "When true, renders `- [x] Approved`; when false, `- [ ] Approved`. Plan Body Verification gate decides which."
106
- }
107
- }
108
- },
109
-
110
116
  "clarificationCarryIn": {
111
117
  "type": "object",
112
118
  "description": "RENDER_IF non-empty. Carry-in clarifications from the previous run.",
@@ -593,7 +599,7 @@
593
599
  "required": ["header"]
594
600
  },
595
601
  "then": {
596
- "required": ["implementationPlanning", "approvalBlock"]
602
+ "required": ["implementationPlanning"]
597
603
  }
598
604
  },
599
605
  {