okstra 0.123.0 → 0.125.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.
Files changed (98) hide show
  1. package/README.md +1 -0
  2. package/docs/architecture/storage-model.md +3 -1
  3. package/docs/architecture.md +16 -2
  4. package/docs/cli.md +3 -1
  5. package/docs/for-ai/README.md +41 -35
  6. package/docs/for-ai/skills/okstra-brief-gen.md +105 -105
  7. package/docs/for-ai/skills/okstra-container-build.md +61 -61
  8. package/docs/for-ai/skills/okstra-graphify.md +64 -0
  9. package/docs/for-ai/skills/okstra-inspect.md +87 -86
  10. package/docs/for-ai/skills/okstra-manager.md +32 -32
  11. package/docs/for-ai/skills/okstra-memory.md +49 -50
  12. package/docs/for-ai/skills/okstra-pr-gen.md +48 -0
  13. package/docs/for-ai/skills/okstra-rollup.md +58 -58
  14. package/docs/for-ai/skills/okstra-run.md +95 -95
  15. package/docs/for-ai/skills/okstra-schedule-gen.md +106 -106
  16. package/docs/for-ai/skills/okstra-setup.md +63 -64
  17. package/docs/for-ai/skills/okstra-user-response.md +48 -0
  18. package/docs/performance-improvement-plan-v2.md +6 -6
  19. package/docs/pr-template-usage.md +34 -34
  20. package/docs/project-structure-overview.md +91 -70
  21. package/docs/task-process/README.md +33 -33
  22. package/docs/task-process/common-flow.md +26 -26
  23. package/docs/task-process/error-analysis.md +20 -21
  24. package/docs/task-process/final-verification.md +41 -41
  25. package/docs/task-process/implementation-planning.md +33 -33
  26. package/docs/task-process/implementation.md +38 -38
  27. package/docs/task-process/release-handoff.md +46 -46
  28. package/docs/task-process/requirements-discovery.md +22 -23
  29. package/package.json +1 -1
  30. package/runtime/BUILD.json +2 -2
  31. package/runtime/agents/workers/antigravity-worker.md +4 -4
  32. package/runtime/agents/workers/claude-worker.md +2 -2
  33. package/runtime/agents/workers/codex-worker.md +4 -4
  34. package/runtime/agents/workers/report-writer-worker.md +4 -4
  35. package/runtime/bin/lib/okstra/usage.sh +1 -1
  36. package/runtime/prompts/coding-preflight/frameworks/node-server.md +1 -1
  37. package/runtime/prompts/launch.template.md +1 -1
  38. package/runtime/prompts/lead/convergence.md +10 -20
  39. package/runtime/prompts/lead/okstra-lead-contract.md +15 -17
  40. package/runtime/prompts/lead/plan-body-verification.md +18 -18
  41. package/runtime/prompts/lead/report-writer.md +46 -44
  42. package/runtime/prompts/lead/team-contract.md +11 -122
  43. package/runtime/prompts/profiles/_common-contract.md +15 -22
  44. package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
  45. package/runtime/prompts/profiles/_implementation-executor.md +1 -1
  46. package/runtime/prompts/profiles/_implementation-verifier.md +28 -2
  47. package/runtime/prompts/profiles/error-analysis.md +2 -2
  48. package/runtime/prompts/profiles/final-verification.md +1 -1
  49. package/runtime/prompts/profiles/implementation-planning.md +13 -13
  50. package/runtime/prompts/profiles/implementation.md +2 -1
  51. package/runtime/prompts/profiles/improvement-discovery.md +1 -1
  52. package/runtime/prompts/profiles/release-handoff.md +3 -3
  53. package/runtime/prompts/profiles/requirements-discovery.md +17 -18
  54. package/runtime/python/okstra_ctl/models.py +4 -2
  55. package/runtime/python/okstra_ctl/run.py +8 -2
  56. package/runtime/python/okstra_ctl/stage_fix_carry.py +112 -0
  57. package/runtime/schemas/final-report-v1.0.schema.json +6 -6
  58. package/runtime/skills/_fragments/bash-invocation-rule.md +1 -0
  59. package/runtime/skills/_fragments/preflight-outdated-cli.md +1 -0
  60. package/runtime/skills/_fragments/python-bootstrap-note.md +1 -0
  61. package/runtime/skills/okstra-brief-gen/SKILL.md +117 -122
  62. package/runtime/skills/okstra-container-build/SKILL.md +24 -14
  63. package/runtime/skills/okstra-graphify/SKILL.md +12 -4
  64. package/runtime/skills/okstra-inspect/SKILL.md +39 -747
  65. package/runtime/skills/okstra-inspect/facets/cost.md +84 -0
  66. package/runtime/skills/okstra-inspect/facets/error-zip.md +41 -0
  67. package/runtime/skills/okstra-inspect/facets/errors.md +69 -0
  68. package/runtime/skills/okstra-inspect/facets/history.md +90 -0
  69. package/runtime/skills/okstra-inspect/facets/logs.md +89 -0
  70. package/runtime/skills/okstra-inspect/facets/recap.md +96 -0
  71. package/runtime/skills/okstra-inspect/facets/report.md +61 -0
  72. package/runtime/skills/okstra-inspect/facets/status.md +145 -0
  73. package/runtime/skills/okstra-inspect/facets/time.md +56 -0
  74. package/runtime/skills/okstra-manager/SKILL.md +1 -1
  75. package/runtime/skills/okstra-memory/SKILL.md +3 -3
  76. package/runtime/skills/okstra-pr-gen/SKILL.md +3 -3
  77. package/runtime/skills/okstra-rollup/SKILL.md +12 -6
  78. package/runtime/skills/okstra-run/SKILL.md +49 -88
  79. package/runtime/skills/okstra-schedule-gen/SKILL.md +36 -30
  80. package/runtime/skills/okstra-setup/SKILL.md +1 -1
  81. package/runtime/skills/okstra-setup/references/project-config.md +17 -16
  82. package/runtime/skills/okstra-usage/SKILL.md +5 -2
  83. package/runtime/skills/okstra-user-response/SKILL.md +15 -3
  84. package/runtime/templates/prd/brief.template.md +92 -92
  85. package/runtime/templates/project-docs/task-index.template.md +1 -1
  86. package/runtime/templates/reports/error-analysis-input.template.md +1 -1
  87. package/runtime/templates/reports/fan-out-unit.template.md +6 -6
  88. package/runtime/templates/reports/final-verification-input.template.md +6 -6
  89. package/runtime/templates/reports/implementation-input.template.md +1 -1
  90. package/runtime/templates/reports/implementation-planning-input.template.md +1 -1
  91. package/runtime/templates/reports/improvement-discovery-input.template.md +1 -1
  92. package/runtime/templates/reports/quick-input.template.md +1 -1
  93. package/runtime/templates/reports/release-handoff-input.template.md +1 -1
  94. package/runtime/templates/reports/schedule.template.md +22 -22
  95. package/runtime/templates/reports/task-brief.template.md +3 -3
  96. package/runtime/templates/reports/user-response.template.md +20 -20
  97. package/runtime/templates/worker-prompt-preamble.md +111 -13
  98. package/runtime/validators/validate-schedule.py +1 -1
@@ -0,0 +1,145 @@
1
+ # okstra-inspect facet — status
2
+
3
+ Loaded lazily by the dispatch table in `SKILL.md` (core). Shared rules — Step 0 preflight, the standard task-key resolution rule (0/1/N), the no-task fallback, and Output Rules — live in the core file and still apply here.
4
+
5
+ ## status
6
+
7
+ Trigger phrases: "okstra status", "task status", "current phase", "next phase", "what is pending", "resume point", "okstra status set", "okstra mark", "<task-id> done", "<task-id> in-progress", "<task-id> in progress", "<task-id> complete".
8
+
9
+ ### status.1 — Overall project status
10
+
11
+ Read `.okstra/discovery/task-catalog.json`. The catalog is the authoritative source — every field listed below (including `workStatus`, `workStatusUpdatedAt`, `workStatusNote`) is projected directly from each `task-manifest.json` by `scripts/okstra_ctl/render.py :: render_task_catalog_discovery`. Do NOT re-open individual manifests for the overview.
12
+
13
+ | Field | Description |
14
+ |------|------|
15
+ | `taskKey` | `<project-id>:<task-group>:<task-id>` |
16
+ | `taskType` | latest task type |
17
+ | `workCategory` | bugfix / feature / improvement / refactor / ops / unknown. Display `unknown` as-is, but flag with `(unset)` annotation so the reader knows the requirements-discovery classification was skipped or no `--work-category` flag was passed. |
18
+ | `currentStatus` | task-level status |
19
+ | `currentPhase` | lifecycle current phase |
20
+ | `currentPhaseState` | lifecycle phase state |
21
+ | `nextRecommendedPhase` | next recommended phase |
22
+ | `routingStatus` | routing decision status |
23
+ | `awaitingApproval` | whether awaiting approval |
24
+ | `latestRunStatus` | latest run status |
25
+ | `latestReportPath` | latest report path |
26
+ | `latestResumeCommandPath` | latest resume command |
27
+ | `workStatus` | user-managed work status (todo / in-progress / blocked / done; default in-progress) |
28
+ | `updatedAt` | last update time |
29
+
30
+ Sort by `updatedAt` desc, then `taskKey`.
31
+
32
+ The overview table is intentionally narrow so it renders cleanly in a terminal. Only six columns are shown; for any task that needs a closer look (phase state, routing, approval gate, last run status, resume path, etc.) tell the user to run `/okstra-inspect status <task-key>` for the detail view in `status.2`.
33
+
34
+ If `awaitingApproval` is true OR `routingStatus == "pending"`, append a `*` to the `Next` cell and explain the marker once below the table.
35
+
36
+ ```markdown
37
+ ## okstra Status — <project-id>
38
+
39
+ | # | Task Key | Category | Phase | workStatus | Next |
40
+ |---|----------|----------|-------|------------|------|
41
+ | 1 | proj:group:id | bugfix | error-analysis | in-progress | implementation-planning |
42
+ | 2 | proj:group:id2 | feature | requirements-discovery | done | pending-routing-decision* |
43
+
44
+ `*` = awaiting user approval or pending routing decision. Run `/okstra-inspect status <task-key>` for details.
45
+ ```
46
+
47
+ ### status.2 — Specific task status
48
+
49
+ Given a specific `task-key` or `task-group + task-id`:
50
+
51
+ 1. If possible, quickly look it up in `task-catalog.json`.
52
+ 2. If necessary, read `.okstra/tasks/<task-group>/<task-id>/task-manifest.json` directly.
53
+ 3. If you need the latest run information, read `history/timeline.json` along with the latest run manifest.
54
+
55
+ Required fields: `taskKey`, `taskType`, `workCategory`, `currentStatus`, `latestRunStatus`, `workflow.{currentPhase, currentPhaseState, phaseStates, lastCompletedPhase, nextRecommendedPhase, awaitingApproval, routingStatus, lastSafeCheckpoint}`, `workStatus`, `workStatusUpdatedAt`, `workStatusNote`, `latestReportPath`, `latestResumeCommandPath`, `historyTimelinePath`.
56
+
57
+ ```markdown
58
+ ## okstra Task Status — <task-key>
59
+
60
+ - Work category: `<category>`
61
+ - Current phase: `<phase>`
62
+ - Current phase state: `<phase-state>`
63
+ - Last completed phase: `<phase-or-->`
64
+ - Next recommended phase: `<phase>`
65
+ - Awaiting approval: `<yes|no>`
66
+ - Routing status: `<routing-status>`
67
+ - Task status: `<task-status>`
68
+ - Latest run status: `<run-status>`
69
+ - Latest report: `<relative-path-or-->`
70
+ - Resume command: `<relative-path-or-->`
71
+ - workStatus: `<todo|in-progress|blocked|done>` (updated `<workStatusUpdatedAt-or-->`)
72
+ - workStatus note: `<workStatusNote-or-->`
73
+
74
+ ### Phase States
75
+
76
+ - `requirements-discovery`: `<state>`
77
+ - `error-analysis`: `<state>`
78
+ - `implementation-planning`: `<state>`
79
+ - `implementation`: `<state>`
80
+ - `final-verification`: `<state>`
81
+ - `release-handoff`: `<state>`
82
+
83
+ ### Safe Resume Checkpoint
84
+
85
+ - Label: `<checkpoint-label>`
86
+ - Run manifest: `<relative-path-or-->`
87
+ - Team state: `<relative-path-or-->`
88
+ - Report: `<relative-path-or-->`
89
+ - Resume command: `<relative-path-or-->`
90
+ ```
91
+
92
+ ### status.3 — Resume / next-step guidance
93
+
94
+ The status response always includes one of:
95
+
96
+ 1. **Resume current run** — if `latestResumeCommandPath` exists, display that path.
97
+ 2. **Restart current phase** — task can be re-run with the same `task-key` and current `taskType`.
98
+ 3. **Start next phase** — if `workflow.nextRecommendedPhase` is one of `error-analysis`, `implementation-planning`, `implementation`, `final-verification`, `release-handoff`, that phase is proposed. If `nextRecommendedPhase` is `pending-release-handoff`, surface as verdict-gated and propose `release-handoff` only when the cited verdict is `accepted`.
99
+ 4. **Need more information** — if `nextRecommendedPhase` is `pending-routing-decision` or `routingStatus` is `pending`.
100
+ 5. **Task complete (terminal)** — if `nextRecommendedPhase` is `done-or-follow-up`, the task lifecycle has reached its terminal signal. This is **not** a "next phase" — do not propose a new okstra run. Surface the latest report and ask the user whether any follow-up task should be opened separately.
101
+
102
+ ### status.4 — Update workStatus (write)
103
+
104
+ Recognize requests to change a task's `workStatus` and update the corresponding `task-manifest.json`.
105
+
106
+ **Trigger patterns** (recognize both):
107
+
108
+ Natural language: "change DEV-6827 to done", "mark PROD-1623 as blocked", "set DEV-9047 in progress", "Mark DEV-6827 as done".
109
+
110
+ Explicit phrasing (recognized user utterances — normalize each to a `okstra set-work-status` call below):
111
+ - `okstra status set <task-id> <status>`
112
+ - `okstra status set <task-group> <task-id> <status>` (disambiguation)
113
+ - `okstra mark <task-id> <status>`
114
+ - `okstra status set <task-id> <status> --note "<note>"`
115
+
116
+ Accepted `<status>` values: `todo`, `in-progress`, `blocked`, `done`.
117
+
118
+ **Procedure:** run the update through the CLI (one Bash call, literal `okstra` token) — never edit `task-manifest.json` by hand:
119
+
120
+ ```bash
121
+ okstra set-work-status <token> <status> --project-root <projectRoot> --json
122
+ ```
123
+
124
+ - `<token>` is a full task-key or a bare task-id. Add `--task-group <group>` to scope a duplicated id, `--note "<note>"` to set `workStatusNote` (flag omitted → any existing note is left untouched).
125
+ - Branch on the stdout JSON: `ok: true` → confirm below. `stage: "ambiguous"` → list `matches[]` (with `_matchedVia`) via a 3-option picker and retry with the chosen full task-key. `stage: "not-found"` → `<TASK-ID> cannot be found.` An invalid `<status>` makes the CLI exit 2 with the allowed-values list — surface it verbatim; nothing was modified.
126
+
127
+ Confirm in Korean (the block below shows the message shape only — render the actual confirmation text in Korean):
128
+ ```
129
+ ✓ <TASK-ID> workStatus: <previousWorkStatus> → <workStatus>
130
+ ✓ task-manifest.json updated
131
+ ```
132
+ `<previousWorkStatus>` = `(none)` when the JSON's `previousWorkStatus` is empty.
133
+
134
+ **Default value convention:** if `workStatus` is missing or empty, infer the display value from lifecycle state (DO NOT default to a static `in-progress`):
135
+
136
+ | Manifest state | Inferred display |
137
+ |---|---|
138
+ | `currentStatus == "completed"` AND `workflow.nextRecommendedPhase == "done-or-follow-up"` | `done` (inferred) |
139
+ | `currentStatus == "completed"` AND `workflow.currentPhaseState == "completed"` | `phase-done` (inferred) |
140
+ | `currentStatus == "contract-violated"` OR `workflow.currentPhaseState == "blocked"` | `blocked` (inferred) |
141
+ | anything else | `in-progress` (default) |
142
+
143
+ Annotate inferred values with `(inferred)` or `(default)`. Do not back-fill on read; only write when the user explicitly issues an update.
144
+
145
+ **Catalog sync note:** the CLI updates `task-manifest.json` only. `discovery/task-catalog.json` may be stale until the next run regenerates it; downstream consumers (e.g. `okstra-schedule-gen`) re-read each manifest directly.
@@ -0,0 +1,56 @@
1
+ # okstra-inspect facet — time
2
+
3
+ Loaded lazily by the dispatch table in `SKILL.md` (core). Shared rules — Step 0 preflight, the standard task-key resolution rule (0/1/N), the no-task fallback, and Output Rules — live in the core file and still apply here.
4
+
5
+ ## time
6
+
7
+ Trigger phrases: "work time", "elapsed time", "time summary", "duration", "elapsed", "how long did it take", "time analysis".
8
+
9
+ Aggregate elapsed work time for a task, grouped by **task type** and broken down by **worker** (lead + each worker). The `time-report` CLI reads both data sources (`history/timeline.json` runs + each run's `team-state-*.json` usage blocks) and does **all** aggregation — cross-run sums, CPU-sum vs wall-clock, timestamp parsing, unavailable detection. You only resolve the task-key, call it, and render. **Never recompute durations by hand.**
10
+
11
+ ### time.1 — Resolve the task-key
12
+
13
+ Apply the standard task-key resolution rule from `SKILL.md` (core): full task-key → use directly; bare token → the resolver CLI and the 0/1/N branch. If no okstra history exists, say `No okstra history found. Run /okstra-run first.`
14
+
15
+ ### time.2 — Fetch aggregated data
16
+
17
+ ```bash
18
+ okstra time-report <task-key> --project-root <projectRoot> --json
19
+ ```
20
+
21
+ Returns (all durations are **raw milliseconds**):
22
+ - `byTaskType[]` — `{taskType, runs, leadMs, workersMs, cpuSumMs}`, plus `grandTotal`
23
+ - `perWorker` — `{<taskType>: [{workerId, agents[], runs, totalMs, avgMs}]}`; only workers with a nonzero run appear, and `agents[]` lists agent labels that differ from `workerId`
24
+ - `perRunWallClock[]` — `{runTimestamp, taskType, wallClockMs}` (max `endedAt` − min `startedAt` per run)
25
+ - `phaseTimelines[]` — `{runTimestamp, taskType, phases:[{phase, firstAt, wallMsToNext}]}`
26
+ - `unavailable[]` — `{runTimestamp, taskType, reason}` for runs with no Phase-7 durations (never summed into totals)
27
+
28
+ ### time.3 — Render
29
+
30
+ Convert every `*Ms` to `HH:MM:SS` (zero-pad; never show raw ms). Task types in `byTaskType` are already in chronological (first-appearance) order.
31
+
32
+ - **By task type** — `| Task type | Runs | CPU sum | Lead | Workers |` from `byTaskType`, plus a `grandTotal` row. `CPU sum` (= Lead + Workers) overlaps because workers run inside the lead's window — it is *not* wall-clock. Surface wall-clock only when the user explicitly asks, from `perRunWallClock`.
33
+ - **Per worker** (per task type) — `| Worker | Runs | Total | Avg/run |` from `perWorker`. Render the worker as bare `workerId` when `agents` is empty, else `workerId (agent1, agent2)`.
34
+ - **Phase breakdown** — "by stage"/"per stage"/"which stage took longest" in okstra most often means the **lifecycle stage (task-type)** view, which the *By task type* table above already answers — lead with that table, do not treat the request as unanswerable. Render the intra-run phase timeline only when the user clearly means within-a-run phases ("which phase", "Phase 1~7", "phase timeline"): one table per run from `phaseTimelines`: `| Phase | Start | Wall to next |` using `firstAt`/`wallMsToNext` (`null` → `--`). When `phaseTimelines` is empty, do **not** headline "not measurable" — the By-task-type table is the stage answer; mention the missing intra-run markers only as a trailing footnote.
35
+ - If `unavailable[]` is non-empty, append a trailing note listing each run with its reason. Never fold them into totals.
36
+ - Show the resolved `<task-key>` in the heading.
37
+
38
+ ```markdown
39
+ ## Time summary — <task-key>
40
+
41
+ ### By task type
42
+
43
+ | Task type | Runs | CPU sum | Lead | Workers |
44
+ |------------------------|------|-----------|----------|----------|
45
+ | requirements-discovery | 2 | 00:33:12 | 00:12:08 | 00:21:04 |
46
+ | **Grand total** | 6 | **03:03:06** | 01:05:49 | 01:57:17 |
47
+
48
+ ### Per worker — requirements-discovery
49
+
50
+ | Worker | Runs | Total | Avg/run |
51
+ |----------------------|------|----------|----------|
52
+ | lead | 2 | 00:12:08 | 00:06:04 |
53
+ | claude (sonnet-eval) | 2 | 00:09:12 | 00:04:36 |
54
+
55
+ > Unavailable: 1 run (implementation / 2026-04-30_03-03-48) — Phase 7 not reached
56
+ ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: okstra-manager
3
- description: Use when the user wants to manage okstra work across multiple project roots, register or discover projects under a manager, create or update a shared manager task, sync project child-task status into manager state, or launch a child task from manager context. Trigger words include "okstra manager", "okstra-manager", "여러 프로젝트", "cross-project", "프로젝트 묶어서", "manager task".
3
+ description: Use when the user wants to manage okstra work across multiple project roots, register or discover projects under a manager, create or update a shared manager task, sync project child-task status into manager state, or launch a child task from manager context. Trigger words include "okstra manager", "okstra-manager", "multiple projects", "cross-project", "group projects together", "manager task".
4
4
  ---
5
5
 
6
6
  # OKSTRA Manager
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: okstra-memory
3
- description: Use when the user wants to preserve, remember, store, recall, search, or archive AI/human conversation notes in okstra's global Memory Book. Trigger words include "okstra 정리해서 보관해", "memory-book", "기억해둬", "대화 저장", "정리해서 저장", "remember this", "store this conversation", "save this decision", "memory-book 검색", "저장한 메모 찾아줘", "recall a saved decision".
3
+ description: Use when the user wants to preserve, remember, store, recall, search, or archive AI/human conversation notes in okstra's global Memory Book. Trigger words include "organize and store this in okstra", "memory-book", "remember this for me", "save the conversation", "summarize and save", "remember this", "store this conversation", "save this decision", "search the memory-book", "find the note I saved", "recall a saved decision".
4
4
  ---
5
5
 
6
6
  # okstra-memory
@@ -14,7 +14,7 @@ explicitly cites a memory entry later.
14
14
 
15
15
  ## When to use
16
16
 
17
- - The user says "okstra 정리해서 보관해", "기억해둬", "대화 저장",
17
+ - The user says "organize and store this in okstra", "remember this for me", "save the conversation",
18
18
  "remember this", or similar.
19
19
  - The user asks to search, list, show, or archive stored conversation memory.
20
20
  - The user wants decisions, preferences, requirements, people/context notes,
@@ -58,7 +58,7 @@ searching so the rest of the skill can scope to it.
58
58
  ```
59
59
 
60
60
  2. Present a 3-option picker (most-used existing group, next existing group,
61
- then always `직접 입력`). For a personal note, recommend `private` as the
61
+ then always `Enter directly`). For a personal note, recommend `private` as the
62
62
  first option. If `groups` is empty or the user makes no selection, the
63
63
  default group is `global` (the CLI default in `memory.mjs`).
64
64
  3. Carry the chosen group name into every `add` (`--project-group <name>`) and
@@ -33,7 +33,7 @@ Present a 3-option picker (`AskUserQuestion`):
33
33
 
34
34
  1. `Generate PR` — generate a PR body from a branch diff.
35
35
  2. `Register template` — save a new PR body template.
36
- 3. `Enter manually` — always the last option (okstra picker convention).
36
+ 3. `Enter directly` — always the last option (okstra picker convention).
37
37
 
38
38
  ## Mode A — Generate PR
39
39
 
@@ -44,7 +44,7 @@ okstra pr template list --json
44
44
  ```
45
45
 
46
46
  - If `templates` is non-empty, present a picker: 1–2 recommended templates from
47
- the list, plus `Default template` (the bundled default), plus `Enter manually`
47
+ the list, plus `Default template` (the bundled default), plus `Enter directly`
48
48
  last.
49
49
  - If empty, tell the user the bundled default template will be used.
50
50
 
@@ -56,7 +56,7 @@ Carry the chosen template name as `<template>` (`default` for the bundled one).
56
56
  okstra pr branches --json
57
57
  ```
58
58
 
59
- Present a 3-option base picker from `recommended` (top entries) plus `Enter manually`
59
+ Present a 3-option base picker from `recommended` (top entries) plus `Enter directly`
60
60
  last. Carry the choice as `<base>`.
61
61
 
62
62
  ### A3. Build the generation bundle and fill the template
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: okstra-rollup
3
3
  description: |
4
- Use when the user wants run results from MULTIPLE okstra tasks collected and summarized at once — a task-group digest or a whole-project roll-up, not a single task. Aggregates per-task run count, elapsed time, error count, and latest report path, plus group-level totals and status/category/phase tallies, then synthesizes a cross-task prose summary from the report files. Make sure to use this skill whenever the user mentions "okstra rollup", "롤업", "task-group 요약", "그룹 단위 리포트", "여러 task 결과 모아", "전체 task 현황 요약", "cross-task summary", "그룹 종합 리포트", "모든 task 정리", "run 결과 한꺼번에", even if they don't say "rollup". For a SINGLE task's report/time/errors/recap use okstra-inspect instead; for a forward-looking work plan over non-done tasks use okstra-schedule-gen.
4
+ Use when the user wants run results from MULTIPLE okstra tasks collected and summarized at once — a task-group digest or a whole-project roll-up, not a single task. Aggregates per-task run count, elapsed time, error count, and latest report path, plus group-level totals and status/category/phase tallies, then synthesizes a cross-task prose summary from the report files. Make sure to use this skill whenever the user mentions "okstra rollup", "rollup", "task-group summary", "group-level report", "collect multiple task results", "whole-project task status summary", "cross-task summary", "consolidated group report", "organize all tasks", "run results all at once", even if they don't say "rollup". For a SINGLE task's report/time/errors/recap use okstra-inspect instead; for a forward-looking work plan over non-done tasks use okstra-schedule-gen.
5
5
  ---
6
6
 
7
7
  # OKSTRA Rollup
@@ -12,18 +12,24 @@ This skill is read-only. It never mutates task artifacts.
12
12
 
13
13
  ## Step 0: Preflight
14
14
 
15
- Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
15
+ <!-- BEGIN FRAGMENT: bash-invocation-rule -->
16
+ Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
17
+ <!-- END FRAGMENT: bash-invocation-rule -->
16
18
 
17
19
  ```bash
18
20
  okstra preflight --runtime claude-code --json
19
21
  ```
20
22
 
21
- Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string. `ok: false` → tell the user to run `/okstra-setup` first, then stop. If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
23
+ Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string. `ok: false` → tell the user to run `/okstra-setup` first, then stop.
24
+
25
+ <!-- BEGIN FRAGMENT: preflight-outdated-cli -->
26
+ If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
27
+ <!-- END FRAGMENT: preflight-outdated-cli -->
22
28
 
23
29
  ## Step 1: Resolve scope
24
30
 
25
- - User named a task-group (e.g. "alpha 그룹 요약") → use it as `--task-group <group>`.
26
- - User asked for the whole project ("전체 task", "프로젝트 전체") or named no scope → omit `--task-group` (whole catalog).
31
+ - User named a task-group (e.g. "summarize the alpha group") → use it as `--task-group <group>`.
32
+ - User asked for the whole project ("all tasks", "the whole project") or named no scope → omit `--task-group` (whole catalog).
27
33
  - If genuinely ambiguous, ask once: one task-group, or the whole project? Do not silently guess a specific group.
28
34
 
29
35
  ## Step 2: Fetch the roll-up
@@ -62,7 +68,7 @@ Render `Report` as `✓` when `reportPath` is non-empty, else `—`. Build the s
62
68
 
63
69
  ## Step 4: Synthesize the digest (the summary)
64
70
 
65
- This is the skill's value-add over a bare table. When the user asked to "요약"/"summarize"/"digest"/"정리" (the common case), produce a short cross-task narrative:
71
+ This is the skill's value-add over a bare table. When the user asked to "summarize"/"digest"/"organize" (the common case), produce a short cross-task narrative:
66
72
 
67
73
  1. For each task with a non-empty `reportPath` whose file exists under `<projectRoot>/<reportPath>`, read it and write a 1–2 line summary of what it accomplished and its recommended next step.
68
74
  2. Above the per-task lines, write a 2–4 sentence group-level synthesis: what was delivered across the group, where the open work sits (use `byWorkStatus`/`byCurrentPhase`), and any error hot-spots (tasks with high `errorCount`).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: okstra-run
3
- description: Use when the user wants to start an okstra task (cross-verification run) directly from the current Claude Code session — without spawning a new claude process. Equivalent in effect to `okstra.sh --task-type ...` but driven through interactive prompts. Trigger words include "okstra run", "okstra start", "start okstra", "begin okstra task", "run okstra in this session", "okstra here", "이어서 진행", "다음 단계 실행", " 세션에서 okstra 시작".
3
+ description: Use when the user wants to start an okstra task (cross-verification run) directly from the current Claude Code session — without spawning a new claude process. Equivalent in effect to `okstra.sh --task-type ...` but driven through interactive prompts. Trigger words include "okstra run", "okstra start", "start okstra", "begin okstra task", "run okstra in this session", "okstra here", "continue on", "run the next phase", "start okstra in this session".
4
4
  ---
5
5
 
6
6
  # OKSTRA Run (in-session)
@@ -32,7 +32,7 @@ Every wizard call returns JSON. The two shapes you'll see:
32
32
  "progress": { "index": 5, "total": 11, "remaining": 6 } } }
33
33
  ```
34
34
 
35
- Every non-terminal `next` carries a `progress` object (`done` / `aborted` omit it). It holds `index` (1-based number of the **current screen**; pick_group counts as one screen), `total` (the wizard's forward estimate of the full screen count — may grow by a few when the user opens a branch, e.g. choosing *Customize* adds the model screen), `remaining` (`total − index`), and **`label`** — the ready-to-render Korean marker the wizard already composed (e.g. `Step 10/11 · 앞으로 1 스텝 남음`, or `Step 11/11 · 마지막 단계` on the final screen). **Always suffix the rendered prompt with `progress.label` verbatim** — see Step 3. Do not recompute the marker or decide "마지막 단계" yourself; only the wizard knows whether more screens follow.
35
+ Every non-terminal `next` carries a `progress` object (`done` / `aborted` omit it). It holds `index` (1-based number of the **current screen**; pick_group counts as one screen), `total` (the wizard's forward estimate of the full screen count — may grow by a few when the user opens a branch, e.g. choosing *Customize* adds the model screen), `remaining` (`total − index`), and **`label`** — the ready-to-render marker the wizard already composed (e.g. `Step 10/11 · 1 step remaining`, or `Step 11/11 · final step` on the final screen). **Always suffix the rendered prompt with `progress.label` verbatim** — see Step 3. Do not recompute the marker or decide "final step" yourself; only the wizard knows whether more screens follow.
36
36
 
37
37
  ```json
38
38
  { "ok": false, "error": "approved plan has no APPROVED marker: ...",
@@ -48,11 +48,11 @@ The wizard tells you *which UI to use* via `kind` (and the optional `multi` flag
48
48
  - `kind: "pick_group"` → render a SINGLE `AskUserQuestion` whose questions array maps 1:1 to the wizard's `questions[]`. For each entry use `questions[].label`, `questions[].options[].label`, and `multiSelect: questions[].multi`. Collect the user's chosen `options[].value` per tab, build a JSON object keyed by each `questions[].step`, and submit it as a single literal `--answer '{"lead_model":"opus","claude_model":"default",...}'`. A tab the user leaves at its default still gets its `"default"`/`""` value in the JSON. Never split a `pick_group` into multiple `AskUserQuestion` calls — the wizard already capped it at 4 tabs and emits any remainder as the next prompt.
49
49
  - `kind: "text"` → write `label` as a plain text message and consume the user's NEXT message as the answer.
50
50
  - `kind: "done"` → input collection finished; move to Step 5.
51
- - `kind: "aborted"` → the user picked 중단; the wizard is terminally cancelled. Tell the user on one short line that the run setup was aborted, delete the state file (`rm` with the literal path), and stop this skill — do NOT call `render-args` or `render-bundle` (the wizard rejects `render-args` on an aborted state).
51
+ - `kind: "aborted"` → the user picked abort; the wizard is terminally cancelled. Tell the user on one short line that the run setup was aborted, delete the state file (`rm` with the literal path), and stop this skill — do NOT call `render-args` or `render-bundle` (the wizard rejects `render-args` on an aborted state).
52
52
 
53
- The final `confirm` step is a normal `pick` step with three options — `Proceed` / `Edit` / `중단`(abort) — and is rendered the same way (no special handling). `Edit` rewinds to any earlier step (including `base-ref`); `중단` terminally cancels the wizard. The branch/worktree decision the run will actually use (for `implementation`, the **stage worktree** — not the task-key directory) is folded into the Step 4 confirmation summary block as a `worktree` line, so there is no separate branch-confirm prompt.
53
+ The final `confirm` step is a normal `pick` step with three options — `Proceed` / `Edit` / `Abort`(abort) — and is rendered the same way (no special handling). `Edit` rewinds to any earlier step (including `base-ref`); `Abort` terminally cancels the wizard. The branch/worktree decision the run will actually use (for `implementation`, the **stage worktree** — not the task-key directory) is folded into the Step 4 confirmation summary block as a `worktree` line, so there is no separate branch-confirm prompt.
54
54
 
55
- Never invent additional questions. Never reorder. **Never drop, hide, or merge a `pick` / `pick_group` option** — render every `options[]` entry as its own selectable `AskUserQuestion` choice, including entries that carry a `(default)` / `(recommended)` suffix. Do NOT collapse a multi-option pick into a "recommended + 직접 입력 / Other" shortlist: the wizard's `options[]` array IS the complete, authoritative choice set. Example: if a pick's `options[]` carries N entries, render all N as selectable choices — never abbreviate a multi-option step down to one recommended value. The run-prompt recommendation rule (1–2 추천 + 직접 입력) applies ONLY to prompts this skill authors itself (e.g. the conformance-waiver picker), never to wizard-provided `options[]`. Never use `AskUserQuestion` for `text` prompts — the wizard explicitly chose `text` to avoid the picker-Other re-render lag.
55
+ Never invent additional questions. Never reorder. **Never drop, hide, or merge a `pick` / `pick_group` option** — render every `options[]` entry as its own selectable `AskUserQuestion` choice, including entries that carry a `(default)` / `(recommended)` suffix. Do NOT collapse a multi-option pick into a "recommended + Enter directly / Other" shortlist: the wizard's `options[]` array IS the complete, authoritative choice set. Example: if a pick's `options[]` carries N entries, render all N as selectable choices — never abbreviate a multi-option step down to one recommended value. The run-prompt recommendation rule (1–2 recommendations + Enter directly) applies ONLY to prompts this skill authors itself (e.g. the conformance-waiver picker), never to wizard-provided `options[]`. Never use `AskUserQuestion` for `text` prompts — the wizard explicitly chose `text` to avoid the picker-Other re-render lag.
56
56
 
57
57
  ## Step 1: Preflight
58
58
 
@@ -89,7 +89,7 @@ Output: the same `{ok, next}` JSON described above. The first `next` is always `
89
89
 
90
90
  Repeat until `next.kind == "done"` (or `"aborted"` — terminal cancel, see "How the wizard talks to you"):
91
91
 
92
- 1. **Render** the prompt according to `kind` (and `multi` for pick). **Always append the progress marker to the rendered question label** (the `AskUserQuestion` question text, or the `text`-prompt message): suffix it with ` (<next.progress.label>)` — render `progress.label` exactly as the wizard sent it, never recompute it. Example: label `Step 8/11 · 앞으로 3 스텝 남음``모델을 선택하세요 (Step 8/11 · 앞으로 3 스텝 남음)`. Re-prompts after `ok: false` reuse `current.progress.label` the same way. The progress marker is presentation-only — never send it back to the wizard as part of an answer.
92
+ 1. **Render** the prompt according to `kind` (and `multi` for pick). **Always append the progress marker to the rendered question label** (the `AskUserQuestion` question text, or the `text`-prompt message): suffix it with ` (<next.progress.label>)` — render `progress.label` exactly as the wizard sent it, never recompute it. Example: label `Step 8/11 · 3 steps remaining``Select a model (Step 8/11 · 3 steps remaining)`. Re-prompts after `ok: false` reuse `current.progress.label` the same way. The progress marker is presentation-only — never send it back to the wizard as part of an answer.
93
93
  - `pick` + `multi: false` → `AskUserQuestion` with `multiSelect: false`, `label`, and `options`. The user's chosen option's `value` is the answer string.
94
94
  - `pick` + `multi: true` → `AskUserQuestion` with `multiSelect: true`, `label`, and `options`. Join the selected `value`s with `,` into a single literal CSV string (e.g. `"claude,codex,antigravity"`) and submit it as a single `--answer "claude,codex,antigravity"`. Empty selection submits `--answer ""` and the wizard re-prompts.
95
95
  - `pick_group` → one `AskUserQuestion` with one question per `questions[]` entry (tab). Map each tab's selected `value` back by `questions[].step`, assemble a JSON object, and submit it as a single literal `--answer '<json>'`.
@@ -113,14 +113,14 @@ Repeat until `next.kind == "done"` (or `"aborted"` — terminal cancel, see "How
113
113
 
114
114
  That is the entire interactive flow. The wizard handles:
115
115
 
116
- - new-vs-existing task split (남은 작업 — `workStatus != done` — 최신순 3 추천 + 직접 입력), task-group / task-id slug validation (task-group 최근 task 사용 + 최근 `.okstra/briefs/<group>/` 생성 활동을 합산한 최신 후보 3개 추천 + 직접 입력, task-id 같은 group 최근 후보 3개 추천 + 직접 입력),
117
- - task-type pick (추천 3 — `nextRecommendedPhase` recommended / 현재 phase 재실행 / 라이프사이클 다음 단계 — + 직접 입력; 직접 입력은 후속 `text` 단계에서 전체 task-type 화이트리스트로 검증),
118
- - brief path — **entry task-type(requirements-discovery / error-analysis / improvement-discovery)에서만 질문** (same-group `.okstra/briefs/<task-group>/**/*.md` candidates first, sorted by the newer of file-created/modified time and latest task-catalog use; direct input last; `유지 / 변경` for existing entry tasks). downstream task-type manifest brief 자동 carry-in 하고, 등록 brief 없으면 `brief_carry` 3-옵션(entry 전환 추천 / 직접 입력 / 중단) 뜬다. `release-handoff` brief 단계가 아예 없다 — prepare 검증 보고서 인용 input 문서를 생성한다,
116
+ - new-vs-existing task split (remaining work — `workStatus != done` — top-3 newest recommendations + Enter directly), task-group / task-id slug validation (task-group offers the top-3 newest candidates combining recent task use + recent `.okstra/briefs/<group>/` creation activity + Enter directly; task-id offers the top-3 recent candidates from the same group + Enter directly),
117
+ - task-type pick (3 recommendations — `nextRecommendedPhase` recommended / re-run the current phase / the lifecycle's next step — + Enter directly; Enter directly is validated against the full task-type whitelist in a follow-up `text` step),
118
+ - brief path — **asked only for entry task-types (requirements-discovery / error-analysis / improvement-discovery)** (same-group `.okstra/briefs/<task-group>/**/*.md` candidates first, sorted by the newer of file-created/modified time and latest task-catalog use; direct input last; `Keep / Change` for existing entry tasks). A downstream task-type auto carries in the manifest's brief, and when no registered brief exists a `brief_carry` 3-option prompt appears (recommend switching to entry / Enter directly / Abort). `release-handoff` has no brief step at all — prepare generates the input document that cites the verification report,
119
119
  - base-ref pick + git rev-parse validation (skipped when reusing an active worktree),
120
- - `implementation`-only sub-flow: approved-plan path (frontmatter `approved: true` check) + stage pick (`auto` = 의존성 충족된 가장 빠른 미완료 stage, 또는 특정 stage 번호) + executor pick. approved-plan 선택 run sibling `user-responses/` 에서 plan source-report·seq 일치하는, 보고서에서 내보낸 `## APPROVAL` sidecar 감지하면 approve-confirm 단계가 3-옵션(`yes_apply` 내보낸 기록대로 승인+옵션 적용 추천 / `yes` 승인만 / `no` 중단)으로 확장된다 — `yes_apply` 옵션을 plan `optionCandidates` 대해 검증한 기존 승인·옵션 경로로 적용한다,
121
- - `release-handoff`-only sub-flow: approved plan 자동 해소 `handoff_stage_pick` 멀티선택 — eligible stage 묶음(stage-group) 또는 전체 task(accepted whole-task 검증 보고서 존재 시) 선택; 결과는 render-args `stages` (csv, whole-task 면 빈 값)로 나간다,
120
+ - `implementation`-only sub-flow: approved-plan path (frontmatter `approved: true` check) + stage pick (`auto` = the earliest incomplete stage whose dependencies are satisfied, or a specific stage number) + executor pick. When an approved plan is selected and a `## APPROVAL` sidecar exported from the report — matching the plan on source-report·seq is detected in that run's sibling `user-responses/`, the approve-confirm step expands to 3 options (`yes_apply` recommended: approve + apply the option as exported / `yes` approve only / `no` abort) — `yes_apply` validates the option against the plan's `optionCandidates` before applying it via the existing approval·option path,
121
+ - `release-handoff`-only sub-flow: after the approved plan auto-resolves, a `handoff_stage_pick` multi-selectchoose an eligible stage bundle (stage-group) or the whole task (when an accepted whole-task verification report exists); the result goes out as render-args' `stages` key (csv, empty when whole-task),
122
122
  - `Use defaults / Customize` branch with profile-aware worker/model questions,
123
- - **resume-clarification (in-session 등가)** — 셸의 `okstra.sh --resume-clarification` 대응하는 별도 모드나 플래그는 없고, 표준 흐름의 단계가 그 실질을 수행한다. (1) `reuse_previous` (직전 run 설정 재사용 예/아니오 — `requirements-discovery` / `error-analysis` / `implementation-planning` 에서, 직전 run-inputs 가 있을 때만): YES 워커·모델·directive·related-tasks 번에 prefill 한다. (2) `clarification_pick`: 재실행하는 **task-type 자신의** 직전 `final-report` 있으면 그것을 carry-in 입력으로 자동 추천하고(없으면 전체 phase mtime 최신으로 폴백), 같은 run `user-responses/` 사이드카(사용자가 채운 답변) 함께 첨부한다. 선택된 경로는 prepare `--clarification-response` 전달된다 사용자는 보고서의 `Export user response` 사이드카를 만들어 `runs/<task-type>/user-responses/` 같은 phase 를 다시 실행하면 된다,
123
+ - **resume-clarification (in-session equivalent)** — there is no separate mode or flag matching the shell's `okstra.sh --resume-clarification`; two steps of the standard flow carry out its substance. (1) `reuse_previous` (yes/no to reuse the previous run's settings in `requirements-discovery` / `error-analysis` / `implementation-planning`, only when prior run-inputs exist): YES prefills workers·model·directive·related-tasks at once. (2) `clarification_pick`: if the **task-type's own** previous `final-report` exists it is auto-recommended as the carry-in input (falling back to the newest by mtime across all phases when absent), and the same run's `user-responses/` sidecar (answers the user filled in) is attached alongside. The chosen path is passed to prepare as `--clarification-response` the user makes the sidecar via the report's `Export user response`, places it in `runs/<task-type>/user-responses/`, and re-runs the same phase,
124
124
  - `release-handoff` PR template override + persist scope,
125
125
  - final `Proceed / Edit` confirmation; on `Edit` the wizard asks which step to rewind to and clears every later answer.
126
126
 
@@ -134,7 +134,7 @@ When `next.step == "confirm"`, before relaying the picker, fetch the human-reada
134
134
  okstra wizard confirmation --state-file /var/folders/.../okstra-wizard.AbCd.json
135
135
  ```
136
136
 
137
- Output: `{ok: true, text: "선택 확인:\n task-type : ...\n ..."}`. Print `text` to the user, then render the `confirm` picker (Proceed / Edit).
137
+ Output: `{ok: true, text: "Selection summary:\n task-type : ...\n ..."}`. Print `text` to the user, then render the `confirm` picker (Proceed / Edit).
138
138
 
139
139
  ## Step 5: Render the task bundle
140
140
 
@@ -195,7 +195,7 @@ okstra render-bundle \
195
195
  --fix-cycle "<args.fix-cycle>"
196
196
  ```
197
197
 
198
- `render-bundle` auto-supplies `--workspace-root` and forces `--render-only`. Stdout prints `okstra task root:`, `okstra instruction-set:`, and the full rendered lead prompt. Parse the labelled lines for `TASK_ROOT` and `INSTRUCTION_SET_PATH`. Also watch for an optional `okstra concurrent-run stages:` label line — present only when a concurrent run is detected (see "동시-run 감지 분기" below).
198
+ `render-bundle` auto-supplies `--workspace-root` and forces `--render-only`. Stdout prints `okstra task root:`, `okstra instruction-set:`, and the full rendered lead prompt. Parse the labelled lines for `TASK_ROOT` and `INSTRUCTION_SET_PATH`. Also watch for an optional `okstra concurrent-run stages:` label line — present only when a concurrent run is detected (see "Concurrent-run detection branch" below).
199
199
 
200
200
  The python function underneath is mutex-protected (`~/.okstra/.locks/<task-key>.lock`), writes `run-context-*.json` + `run-inputs-*.json` + all manifests + discovery files, and registers the run in `~/.okstra/recent.jsonl` with status `prepared`.
201
201
 
@@ -209,48 +209,30 @@ This is **never** a lead/worker self-exemption — only the user may waive. Offe
209
209
 
210
210
  1. (recommended) Run the conformance script — no waiver.
211
211
  2. Waive this stage — ask the user for the exact `<stageKey>` and reason, then pass `--qa-waiver "<stageKey>:<reason>"` to `render-bundle` (reason = the user's words, unedited).
212
- 3. 직접 입력 — the user types the full `<stageKey>:<reason>` value.
212
+ 3. Enter directly — the user types the full `<stageKey>:<reason>` value.
213
213
 
214
214
  When the user picks a waiver, append `--qa-waiver "<stageKey>:<reason>"` to the `render-bundle` invocation above. Omit the flag entirely otherwise (do **not** pass `--qa-waiver ""`). A malformed value or unknown `<stageKey>` aborts `render-bundle` with a `PrepareError`.
215
215
 
216
- ### 동시-run 감지 분기 (concurrent-run)
216
+ ### Concurrent-run detection branch (concurrent-run)
217
217
 
218
- `render-bundle` stdout `okstra concurrent-run stages: <stages>` 라벨 라인이
219
- 있으면(같은 task-key 의 다른 implementation run 이 `<stages>` 를 점유 중), launch
220
- 프롬프트는 이미 "Concurrent-run marker" 게이트로 렌더돼 있다. 이 라인이
221
- 없으면 동시-run 이 아니므로 이 분기를 건너뛴다. 라인이 있으면 dispatch 전에
222
- 사용자에게 3-옵션 recommendation picker 를 제시한다 (run-prompt recommendation 규칙:
223
- 1–2 추천 + 직접 입력; 이 picker 는 스킬이 author 하는 것이라 wizard `options[]`
224
- 제약과 무관):
218
+ If `render-bundle` stdout carries an `okstra concurrent-run stages: <stages>` label line (another implementation run on the same task-key is occupying `<stages>`), the launch prompt has already been rendered with the "Concurrent-run marker" gate. If this line is absent it is not a concurrent run, so skip this branch. If present, before dispatch present a 3-option recommendation picker to the user (run-prompt recommendation rule: 1–2 recommendations + Enter directly; this picker is authored by the skill, so it is unconstrained by the wizard `options[]` rule):
225
219
 
226
- 1. (추천) 이대로 진행이미 렌더된 bundle 그대로 사용한다. 세션은 자기
227
- implicit team 쓰므로 동시 run 끼리 team 충돌이 없고, split-pane 정상 동작한다.
228
- 2. 대기 — 지금 dispatch 를 보류한다. stage worktree·run-context 는 보존되므로,
229
- 점유 중인 다른 run 종료 후 같은 stage 를 resume 으로 재개하면 그때는 정상 team
230
- 경로다. resume 명령(`okstra-inspect` history → resume)을 사용자에게 출력한다.
231
- 3. 직접 입력.
220
+ 1. (recommended) Proceed as-isuse the already-rendered bundle. Each session uses its own implicit team, so concurrent runs have no team conflict and split-pane works fine.
221
+ 2. Wait hold the dispatch for now. The stage worktree·run-context are preserved, so after the other occupying run finishes, resuming the same stage takes the normal team path. Print the resume command (`okstra-inspect` history resume) to the user.
222
+ 3. Enter directly.
232
223
 
233
224
  ### Stale git SHA recovery (git-reconcile gate)
234
225
 
235
- `render-bundle` `Recorded stage SHAs no longer match the git history` 포함한
236
- `PrepareError` 로 실패하면, okstra 밖에서 git 히스토리가 바뀐 것이다(rebase /
237
- squash / 리뷰 반영 amend / branch 삭제). 절대 registry/consumers 손으로
238
- 고치지 말고 다음 순서로 회복한다:
239
-
240
- 1. 에러 메시지에 인쇄된 `okstra git-reconcile --check --json` 명령을 그대로 실행해
241
- stale 리포트를 얻는다. (patch-id 내용 동일성이 증명되는 항목은 prepare
242
- 이미 자동 화해했으므로, 여기 남는 것은 confirm 항목뿐이다.)
243
- 2. confirm 항목별로 사용자에게 3-옵션 picker 를 제시한다:
244
- - **`stage-<N>` branch 현재 tip 으로 재기록 (추천)**리뷰 반영
245
- 의도된 수정이 그 branch 에 있을 때.
246
- - **다른 ref 직접 입력** — 사용자가 commit/branch/tag 를 직접 지정.
247
- - **중단** — 회복하지 않고 run 을 멈춘다.
248
- 3. 선택된 ref 로 `okstra git-reconcile … --apply --stage <N> --use-ref <ref>`
249
- 를 실행한 뒤, 실패했던 `render-bundle` 을 동일 인자로 재시도한다.
250
-
251
- anchor(`implementation_base_commit`)가 unresolvable 로 보고되면 같은 명령의
252
- `--reset-anchor <ref>` 를 사용자 확인 후 실행한다. picker 없이 confirm 항목을
253
- 보정하는 것은 금지 — 런타임도 `--use-ref` 없는 confirm 보정을 거부한다.
226
+ If `render-bundle` fails with a `PrepareError` containing `Recorded stage SHAs no longer match the git history`, the git history changed outside okstra (rebase / squash / review-feedback amend / branch deletion). Never fix the registry/consumers by hand; recover in this order:
227
+
228
+ 1. Run the `okstra git-reconcile --check --json` command printed in the error message verbatim to get the stale report. (Items whose content-identity is proven by patch-id were already auto-reconciled by prepare, so only confirm items remain here.)
229
+ 2. For each confirm item, present a 3-option picker to the user:
230
+ - **Re-record to the `stage-<N>` branch's current tip (recommended)** — when an intended change such as review feedback lives on that branch.
231
+ - **Enter a different ref directly** the user names a commit/branch/tag.
232
+ - **Abort** stop the run without recovering.
233
+ 3. Run `okstra git-reconcile --apply --stage <N> --use-ref <ref>` with the chosen ref, then retry the failed `render-bundle` with the same arguments.
234
+
235
+ If the anchor (`implementation_base_commit`) is reported unresolvable, run the same command's `--reset-anchor <ref>` after user confirmation. Correcting a confirm item without the picker is forbidden the runtime also rejects a confirm correction without `--use-ref`.
254
236
 
255
237
  ## Step 6: Take over as Claude lead
256
238
 
@@ -261,45 +243,24 @@ Then proceed through the phases exactly as the lead prompt directs (Phase 1 cont
261
243
  Inform the user with one short line:
262
244
  > Took over as Claude lead for `<taskKey>` (`<task-type>`). Run dir: `<RUN_DIR_RELATIVE_PATH>`. Beginning Phase 1 (context loading).
263
245
 
264
- ## Step 7: implementation 무인 연쇄 (chain-stages)
265
-
266
- `task-type == implementation` 이고 Step 5 render-args `chain-stages` CSV 원소 2개
267
- 이상이면, 현재 세션이 오케스트레이터로서 stage 를 의존성 순서대로 무인 연쇄
268
- 실행한다(단일 원소면 기존 단일 run 동일하므로 절은 건너뛴다 Step 6 종료가
269
- run 종료다).
270
-
271
- = `chain-stages` `,` 분해한 위상정렬 stage 리스트(Task 5 의존성
272
- closure 위상정렬해 내보낸 순서). 큐의 stage `N` 대해 순서대로:
273
-
274
- 1. Step 5 의 `render-bundle` 을 동일 인자로, 단 `--stage N` 으로 호출한다(base
275
- commit prepare predecessor done `head_commit` 으로 자동 계산하므로 손으로
276
- 넘기지 않는다). Step 5 의 conformance waiver offer·동시-run 감지·git-reconcile
277
- 게이트는 stage `render-bundle` 마다 동일하게 적용된다.
278
- 2. Step 6 대로 Claude lead 되어 stage Phase 1~7 인라인 실행한다. Phase 6
279
- 의 lead post-stage persistence 가 `runs/<plan-task-key>/consumers.jsonl` 에 그
280
- stage `status:"done"` 행을 append 한다(implementation 프로파일 지시).
281
- 3. `done` 행이 기록됐는지 확인한 다음 stage 넘어간다. stage 경계에서
282
- 컨텍스트를 정리한다(이전 배치의 잔여 pane·완료 teammate).
283
- 4. 각 stage 시작/완료마다 한 줄 보고: `stage N/<총개수> 시작` / `stage N done → 다음 K`.
284
-
285
- 큐를 모두 소화하면 연쇄를 종료하고 사용자에게 완료를 보고한다.
286
-
287
- ### 다음 stage 가 아직 ready 아님 — 정상 종료 (예외 게이트 아님)
288
- 연쇄 큐에는 의존성 closure 때문에 **다른 implementation run 이 started/reserved 로
289
- 점유한 stage 가 포함될 수 있다.** 그 stage 의 `render-bundle` 은
290
- `--stage N already in progress or reserved by another run`(StageTargetError)으로
291
- 거부된다. 이건 사람 판단이 필요한 예외 게이트가 **아니라** "다음 stage 가 아직
292
- ready 아님" 상황이다. 이 거부를 만나면 연쇄를 **정상 종료**하고 남은 큐를
293
- 사용자에게 보고한다(예: `남은 큐: stage 4, 5 — 점유 해제 후 okstra-run 으로 재개`).
294
- 아래 예외 게이트(데이터 손상·동시 점유 충돌 확인)와는 다른 분기다.
295
-
296
- ### 연쇄 중 예외 게이트
297
- `render-bundle` 이 Step 5 의 동시-run 충돌 감지(concurrent-run 분기)나 git
298
- stale-SHA 재조정(git-reconcile 분기)을 띄우면, **그 stage 에서 연쇄를 멈추고**
299
- 게이트를 Step 5 의 절차대로 사용자에게 그대로 제시한다. 사용자가 게이트를
300
- 해소하면 그 자리에서 연쇄를 재개한다(남은 큐를 이어서 처리). 데이터 손상·동시
301
- 점유 충돌은 사람이 확인한다 — 이것이 무인 연쇄의 안전 경계다. (위 "ready 아님"
302
- 거부와 달리, 이 두 분기는 큐를 버리지 않고 사용자 해소를 기다린다.)
246
+ ## Step 7: implementation unattended chaining (chain-stages)
247
+
248
+ When `task-type == implementation` and Step 5 render-args' `chain-stages` CSV has 2+ elements, the current session acts as the orchestrator and runs the stages in dependency order as an unattended chain (a single element behaves like the existing single run, so skip this section — the end of Step 6 is the end of the run).
249
+
250
+ Queue = the topologically-sorted stage list from splitting `chain-stages` on `,` (the order Task 5 emitted by topologically sorting the dependency closure). For each stage `N` in the queue, in order:
251
+
252
+ 1. Call Step 5's `render-bundle` with the same arguments but `--stage N` (the base commit is auto-computed by prepare from the predecessor's done `head_commit`, so do not pass it by hand). Step 5's conformance waiver offer·concurrent-run detection·git-reconcile gates apply identically to each stage's `render-bundle`.
253
+ 2. As in Step 6, become Claude lead and run that stage's Phase 1–7 inline. Phase 6's lead post-stage persistence appends that stage's `status:"done"` row to `runs/<plan-task-key>/consumers.jsonl` (per the implementation profile directive).
254
+ 3. After confirming that `done` row was written, move to the next stage. Clean up context at each stage boundary (leftover panes·finished teammates from the previous batch).
255
+ 4. One-line report at each stage start/finish: `stage N/<total> start` / `stage N done → next K`.
256
+
257
+ Once the whole queue is consumed, end the chain and report completion to the user.
258
+
259
+ ### Next stage not yet ready normal termination (not an exception gate)
260
+ Because of the dependency closure, the chain queue **may include a stage that another implementation run has occupied as started/reserved.** That stage's `render-bundle` is rejected with `--stage N already in progress or reserved by another run` (StageTargetError). This is **not** an exception gate needing human judgment but a "next stage not yet ready" situation. On this rejection, **terminate the chain normally** and report the remaining queue to the user (e.g. `remaining queue: stage 4, 5 — resume with okstra-run after occupancy is released`). This is a different branch from the exception gate below (data corruption·concurrent-occupancy conflict confirmation).
261
+
262
+ ### Exception gate during chaining
263
+ If `render-bundle` raises Step 5's concurrent-run conflict detection (concurrent-run branch) or git stale-SHA reconciliation (git-reconcile branch), **stop the chain at that stage** and present the gate to the user exactly as Step 5 prescribes. Once the user resolves the gate, resume the chain in place (continue with the remaining queue). Data corruption·concurrent-occupancy conflicts are confirmed by a human — this is the safety boundary of unattended chaining. (Unlike the "not ready" rejection above, these two branches do not discard the queue; they wait for user resolution.)
303
264
 
304
265
  ## Persisting the PR template scope (release-handoff)
305
266
 
@@ -325,4 +286,4 @@ Do not read the wizard state file directly. `okstra wizard outcome` exposes any
325
286
 
326
287
  - Echo each captured answer (`result.echo`) on one short line so the user sees what was registered.
327
288
  - Never invent identity; if a `text` prompt returns an empty answer where the wizard rejects it, the user must retry.
328
- - After Step 6, begin the lead workflow without re-summarizing the skill itself. 단일 run Step 6 종료가 run 종료다 단, `chain-stages` 원소 2 이상인 무인 연쇄에서는 Step 7 큐가 때까지(또는 "ready 아님"/예외 게이트로 멈출 때까지) Step 6 stage 마다 반복한 뒤 종료한다.
289
+ - After Step 6, begin the lead workflow without re-summarizing the skill itself. For a single run, the end of Step 6 is the end of the run — but in an unattended chain where `chain-stages` has 2+ elements, repeat Step 6 per stage until Step 7's queue is empty (or it stops at a "not ready" / exception gate), then finish.