okstra 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.kr.md +20 -3
- package/README.md +20 -3
- package/docs/kr/architecture.md +8 -3
- package/docs/kr/cli.md +55 -1
- package/docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md +638 -0
- package/docs/superpowers/specs/2026-05-12-ticket-id-in-reports-design.md +131 -0
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/SKILL.md +13 -0
- package/runtime/agents/workers/claude-worker.md +2 -0
- package/runtime/agents/workers/codex-worker.md +2 -0
- package/runtime/agents/workers/gemini-worker.md +2 -0
- package/runtime/agents/workers/report-writer-worker.md +1 -0
- package/runtime/bin/okstra.sh +3 -0
- package/runtime/prompts/launch.template.md +11 -0
- package/runtime/prompts/profiles/implementation-planning.md +2 -2
- package/runtime/prompts/profiles/implementation.md +15 -1
- package/runtime/prompts/profiles/release-handoff.md +97 -0
- package/runtime/python/lib/okstra/cli.sh +13 -2
- package/runtime/python/lib/okstra/globals.sh +2 -0
- package/runtime/python/lib/okstra/usage.sh +11 -0
- package/runtime/python/okstra_ctl/render.py +21 -5
- package/runtime/python/okstra_ctl/run.py +135 -8
- package/runtime/python/okstra_ctl/workflow.py +34 -3
- package/runtime/python/okstra_ctl/worktree.py +235 -0
- package/runtime/skills/okstra-context-loader/SKILL.md +1 -1
- package/runtime/skills/okstra-convergence/SKILL.md +11 -5
- package/runtime/skills/okstra-report-finder/SKILL.md +1 -0
- package/runtime/skills/okstra-report-writer/SKILL.md +6 -0
- package/runtime/skills/okstra-run/SKILL.md +2 -1
- package/runtime/skills/okstra-status/SKILL.md +14 -3
- package/runtime/skills/okstra-team-contract/SKILL.md +19 -0
- package/runtime/skills/okstra-time-summary/SKILL.md +1 -0
- package/runtime/templates/reports/error-analysis-input.template.md +1 -0
- package/runtime/templates/reports/final-report.template.md +144 -21
- package/runtime/templates/reports/implementation-input.template.md +1 -0
- package/runtime/templates/reports/implementation-planning-input.template.md +1 -0
- package/runtime/templates/reports/quick-input.template.md +1 -0
- package/runtime/templates/reports/release-handoff-input.template.md +73 -0
- package/runtime/templates/reports/task-brief.template.md +5 -0
- package/runtime/validators/validate-run.py +136 -4
- package/src/install.mjs +133 -2
- package/src/uninstall.mjs +46 -9
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Ticket ID in Worker / Lead / Report Outputs — Design
|
|
2
|
+
|
|
3
|
+
- Date: 2026-05-12
|
|
4
|
+
- Scope: okstra phases `requirements-discovery`, `error-analysis`, `implementation-planning`, `implementation`
|
|
5
|
+
- Status: Implemented
|
|
6
|
+
- Implementation plan: `docs/superpowers/plans/2026-05-12-ticket-id-in-reports.md`
|
|
7
|
+
|
|
8
|
+
## 1. 목적
|
|
9
|
+
|
|
10
|
+
okstra의 작업 단위는 보통 외부 트래커의 ticket과 1:1로 묶이지만, 현재 워커·lead·report-writer 산출물은 보고서 헤더의 `Task Key` 한 곳에서만 ticket을 식별한다. 항목별로 어떤 ticket을 다루고 있는지 추적할 수 없어, 한 run이 여러 ticket을 동시에 다룰 때 항목·ticket 매핑이 누락된다.
|
|
11
|
+
|
|
12
|
+
본 변경은 워커가 작성하는 모든 항목과 final report의 본문 섹션에 ticket 식별자를 박아 trace를 ticket 단위로 동기화한다.
|
|
13
|
+
|
|
14
|
+
## 2. Ticket ID 채움 규칙 (모든 산출물 공통)
|
|
15
|
+
|
|
16
|
+
1. 입력 템플릿의 `Issue / Ticket` 값을 우선 사용한다.
|
|
17
|
+
2. 비어 있으면 `Task ID`로 폴백한다. 폴백 표기에는 prefix를 붙이지 않는다 (예: `8852`).
|
|
18
|
+
3. `Issue / Ticket`도 비고 `Task ID`도 사용할 수 없는 예외 상황에 한해 `unknown` 표기를 허용한다.
|
|
19
|
+
4. 한 항목이 여러 ticket을 동시에 다루면 쉼표로 구분한다 (예: `TICKET-123, TICKET-456`).
|
|
20
|
+
|
|
21
|
+
## 3. 표기 규칙
|
|
22
|
+
|
|
23
|
+
### 3.1 표 형식 섹션
|
|
24
|
+
표 형식 섹션은 `Ticket ID` 컬럼을 추가한다. 컬럼은 표의 가장 왼쪽 ID 컬럼 바로 다음에 위치한다.
|
|
25
|
+
|
|
26
|
+
### 3.2 비-표 섹션 (bullet / 번호 목록 / 섹션 헤더)
|
|
27
|
+
항목 또는 섹션 헤더의 타이틀에 `[TICKETID: <id>]` 태그를 강제한다.
|
|
28
|
+
|
|
29
|
+
- 항목 예: `- F-001 [TICKETID: TICKET-123] — <summary> (path:line)`
|
|
30
|
+
- 헤더 예: `### 4.5.3 Recommended Option [TICKETID: TICKET-123]`
|
|
31
|
+
|
|
32
|
+
태그는 ID 직후, 본문 텍스트 앞에 위치한다. 한 줄 안에서 태그가 보이지 않으면 contract violation이다.
|
|
33
|
+
|
|
34
|
+
## 4. 변경 파일
|
|
35
|
+
|
|
36
|
+
### 4.1 `skills/okstra-team-contract/SKILL.md`
|
|
37
|
+
- Worker Output Contract 섹션에 "Ticket Tagging" 항목 신설.
|
|
38
|
+
- 섹션 1 Findings, 2 Missing Information / Assumptions, 3 Safe or Reasonable Areas, 4 Uncertain Points, 5 Recommended Next Actions 모두에 적용된다는 점을 명시.
|
|
39
|
+
- bullet 항목은 `[TICKETID: ...]` 태그 강제, 표 항목은 `Ticket ID` 컬럼 강제.
|
|
40
|
+
- 폴백/다중 ticket/`unknown` 규칙을 본 spec과 동일한 문구로 인용.
|
|
41
|
+
|
|
42
|
+
### 4.2 `skills/okstra-convergence/SKILL.md`
|
|
43
|
+
- Round 0 (Parse worker results)에 ticket 추출 절차 추가.
|
|
44
|
+
- finding 그룹핑 시 ticket이 다르면 의미가 유사해도 별도 그룹으로 처리해 과병합을 방지한다는 규칙 추가.
|
|
45
|
+
- 컨버전스 상태 아티팩트에 각 finding의 `ticketId` 필드를 함께 기록.
|
|
46
|
+
|
|
47
|
+
### 4.3 `templates/reports/final-report.template.md`
|
|
48
|
+
- 보고서 상단(`## Summary of the Problem or Verification Target` 직후)에 `## Ticket Coverage` 표 신규 추가.
|
|
49
|
+
|
|
50
|
+
| Ticket ID | 등장 섹션 | 관련 항목 IDs |
|
|
51
|
+
|-----------|-----------|---------------|
|
|
52
|
+
|
|
53
|
+
- 한 run에 ticket이 0~1개면 단일 행으로 채우거나 `- Single ticket run: <id>` 한 줄로 대체 가능.
|
|
54
|
+
- 다중 ticket이면 ticket마다 한 행씩 작성하고, `등장 섹션` 컬럼에는 본문에서 해당 ticket이 나타나는 섹션 번호를 콤마 구분으로, `관련 항목 IDs` 컬럼에는 `F-001`, `A1`, `Q1` 등 항목 ID를 콤마 구분으로 적는다.
|
|
55
|
+
|
|
56
|
+
- `1.1 Consensus`, `1.2 Differences` → bullet에서 표로 전환.
|
|
57
|
+
|
|
58
|
+
| ID | Ticket ID | Statement | Supporting workers | Evidence |
|
|
59
|
+
|----|-----------|-----------|--------------------|----------|
|
|
60
|
+
|
|
61
|
+
- `3.1 Primary Evidence`, `3.2 Secondary Evidence or Alternate Interpretations` → 표로 전환.
|
|
62
|
+
|
|
63
|
+
| ID | Ticket ID | Evidence | Source (path:line / log / worker) |
|
|
64
|
+
|----|-----------|----------|------------------------------------|
|
|
65
|
+
|
|
66
|
+
- `4. Missing Information and Risks` → 표로 전환.
|
|
67
|
+
|
|
68
|
+
| ID | Ticket ID | Item | Risk if ignored |
|
|
69
|
+
|----|-----------|------|-----------------|
|
|
70
|
+
|
|
71
|
+
- `4.5.1 Option Candidates`: 옵션별 File Structure 표에 `Ticket ID` 컬럼 추가.
|
|
72
|
+
- `4.5.2 Trade-off Matrix`: 컬럼 변경 없음 (옵션 단위 매트릭스이며 옵션 자체가 ticket scope를 가로지를 수 있다).
|
|
73
|
+
- `4.5.4 Stepwise Execution Order`: 각 step 행에 `Ticket ID` 컬럼 추가 (현재 번호 목록이라면 표로 전환).
|
|
74
|
+
- `4.5.6 Validation Checklist`: pre/mid/post 각 체크 행에 `Ticket ID` 컬럼 추가.
|
|
75
|
+
- `5.1 추가 자료 요청`, `5.2 사용자 확인 질문`: 기존 표에 `Ticket ID` 컬럼을 두 번째 위치로 삽입 (`자료 ID` / `질문 ID` 다음).
|
|
76
|
+
|
|
77
|
+
### 4.4 입력 템플릿
|
|
78
|
+
대상 파일:
|
|
79
|
+
- `templates/reports/error-analysis-input.template.md`
|
|
80
|
+
- `templates/reports/implementation-planning-input.template.md`
|
|
81
|
+
- `templates/reports/implementation-input.template.md`
|
|
82
|
+
- `templates/reports/quick-input.template.md`
|
|
83
|
+
|
|
84
|
+
변경:
|
|
85
|
+
- `Identity` 섹션의 `Issue / Ticket:` 줄 바로 아래에 한 줄 가이드 추가.
|
|
86
|
+
> `Issue / Ticket` 값이 비면 워커는 `Task ID`로 폴백한다 (예: `8852`). 한 run에서 여러 ticket을 동시에 다루는 경우 쉼표로 구분한다 (`TICKET-123, TICKET-456`).
|
|
87
|
+
|
|
88
|
+
### 4.5 `templates/reports/task-brief.template.md`
|
|
89
|
+
- `Identity` 섹션에 동일한 폴백/다중 ticket 가이드 한 줄 추가.
|
|
90
|
+
- `Questions for Workers > Standing Scope-Discipline Questions` 직전에 한 줄 추가: "모든 항목 및 표 행에 ticket을 명시해야 한다. 표 형식은 `Ticket ID` 컬럼, bullet/번호목록·섹션 헤더는 `[TICKETID: ...]` 태그를 사용한다. 자세한 규칙은 `okstra-team-contract` SKILL을 참조."
|
|
91
|
+
|
|
92
|
+
### 4.6 워커 프롬프트
|
|
93
|
+
대상 파일:
|
|
94
|
+
- `agents/workers/claude-worker.md`
|
|
95
|
+
- `agents/workers/codex-worker.md`
|
|
96
|
+
- `agents/workers/gemini-worker.md`
|
|
97
|
+
|
|
98
|
+
변경:
|
|
99
|
+
- `Worker Output Structure` 절 끝에 한 단락 추가. 표기 규칙은 team-contract가 authoritative source임을 명시하고, 표/비-표 두 가지 형식과 폴백·다중 ticket·`unknown` 규칙을 한 번에 인용.
|
|
100
|
+
|
|
101
|
+
### 4.7 `agents/workers/report-writer-worker.md`
|
|
102
|
+
- final-report 작성 의무 절에 한 줄 추가: "워커 산출물의 `Ticket ID` 컬럼 및 `[TICKETID: ...]` 태그를 보존하고, 상단 `## Ticket Coverage` 표를 본 spec 규칙대로 채울 것."
|
|
103
|
+
|
|
104
|
+
## 5. 손대지 않는 곳
|
|
105
|
+
|
|
106
|
+
- 기존 `F-001`, `A1`, `Q1` 등 ID 카운터 체계 (전역 유일성 그대로 유지).
|
|
107
|
+
- `User Approval Request` 체크박스, validator의 영문 키워드 매칭(`Option Candidates`, `Trade-off`, `Recommended Option`, `Stepwise Execution Order`, `Dependency`, `Validation Checklist`, `Rollback`, `User Approval Request`).
|
|
108
|
+
- `release-handoff`, `final-verification` 산출물 및 그 phase의 워커/lead 출력.
|
|
109
|
+
- 토큰 사용량 표, Execution Status 표 등 ticket scope와 무관한 메타 표.
|
|
110
|
+
|
|
111
|
+
## 6. 영향과 위험
|
|
112
|
+
|
|
113
|
+
- **convergence 파서**: bullet 한 줄 안에 ticket 태그가 함께 들어가 정규식 변경이 필요. ticket이 finding의 그룹핑 키 일부가 되므로 동일 root cause라도 ticket이 다르면 별도 그룹으로 처리된다. 의도된 동작.
|
|
114
|
+
- **기존 보고서 호환성**: 본 변경은 신규 run에만 적용. 과거 보고서는 마이그레이션하지 않는다.
|
|
115
|
+
- **워커가 ticket을 못 채우는 경우**: `unknown` 표기를 허용하지만, 이는 입력 템플릿이 잘못 채워졌다는 신호이므로 lead가 `Missing Information` 항목으로 함께 기록한다.
|
|
116
|
+
- **다중 ticket 콤마 구분 vs 정규식**: ticket ID 자체에 콤마가 들어가는 경우는 없다고 가정한다. JIRA/GitHub/Linear 모두 콤마 미사용. 만약 향후 콤마를 포함한 ticket ID가 나오면 별도 escape 룰을 추가한다 (현재 spec에는 포함하지 않음).
|
|
117
|
+
|
|
118
|
+
## 7. 검증
|
|
119
|
+
|
|
120
|
+
- 신규 run 1건씩 phase별로 실행해 다음을 수동 확인:
|
|
121
|
+
- 입력 템플릿 가이드가 노출되는지.
|
|
122
|
+
- 워커 출력의 bullet 항목 전부에 `[TICKETID: ...]` 태그가 붙는지.
|
|
123
|
+
- 표 섹션에 `Ticket ID` 컬럼이 채워지는지.
|
|
124
|
+
- final report 상단 `## Ticket Coverage` 표가 본문 항목과 정합한지 (수동 cross-check).
|
|
125
|
+
- `validators/` 디렉토리에 ticket 태그/컬럼 누락을 잡는 정적 체크를 추가하는 것은 후속 작업(이번 spec 범위 밖).
|
|
126
|
+
|
|
127
|
+
## 8. 후속 작업 (이번 spec 범위 밖)
|
|
128
|
+
|
|
129
|
+
- `validators/`에 ticket 표기 강제용 정적 검증기 추가.
|
|
130
|
+
- `final-verification`, `release-handoff` phase에도 동일 규칙 확장 여부 결정.
|
|
131
|
+
- `okstra-convergence` 상태 아티팩트 스키마에 `ticketId` 정식 필드화 (현재는 분류 키로만 사용).
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
package/runtime/agents/SKILL.md
CHANGED
|
@@ -107,6 +107,19 @@ Lead MUST dispatch Edit/Write-bearing work only through the `workerAgent` declar
|
|
|
107
107
|
|
|
108
108
|
Executor is chosen at run-prep time via `--executor <claude|codex|gemini>` (or `OKSTRA_DEFAULT_EXECUTOR`, fallback `claude`); the model used by the executor is taken from the corresponding worker model flag (`--claude-model` / `--codex-model` / `--gemini-model`). For Codex/Gemini executors, the underlying file mutation happens inside the executor CLI's own auto-edit mode (e.g. `codex exec --full-auto`), not through Claude-side Edit/Write tools.
|
|
109
109
|
|
|
110
|
+
#### Executor worktree (BLOCKING for `implementation`)
|
|
111
|
+
|
|
112
|
+
For `--task-type implementation` runs, `okstra-ctl` provisions a dedicated `git worktree` at run-prep time. Lead, the Executor, and every verifier MUST treat the provisioned worktree as the canonical working directory.
|
|
113
|
+
|
|
114
|
+
- Location: `~/.okstra/worktrees/<project-id>/<task-group-segment>/<task-id-segment>-<run-seq>` (override `OKSTRA_HOME` only for tests).
|
|
115
|
+
- Branch: `<work-category-prefix>-<task-id-segment>-<run-seq>` (e.g. `feat-dev-9436-001`, `fix-dev-7311-002`). Branched from `HEAD` of `project_root` at prep time; base SHA is recorded in `EXECUTOR_WORKTREE_BASE_REF`.
|
|
116
|
+
- The worktree path, branch, base ref, and provisioning status (`created` | `skipped-in-worktree` | `skipped-not-git`) are exposed through the launch prompt's `## Executor Worktree` section and the implementation profile's worktree block.
|
|
117
|
+
- **Skip conditions** (worktree provisioning is a no-op; executor uses `project_root` directly):
|
|
118
|
+
- `project_root` is already inside a non-main worktree (the run reuses the caller's worktree to avoid nesting).
|
|
119
|
+
- `project_root` is not inside a git repository at all.
|
|
120
|
+
- **Failure mode**: any other error during `git worktree add` (path collision, branch collision, detached-HEAD with no SHA) raises `PrepareError`. Re-run after manually removing the stale path/branch — the worktree is intentionally not garbage-collected.
|
|
121
|
+
- **Lifecycle**: kept after the run for manual PR authoring, rollback verification, and follow-up `final-verification` runs. Manual cleanup: `git -C <project_root> worktree remove <path>` then `git -C <project_root> branch -D <branch>`.
|
|
122
|
+
|
|
110
123
|
## Phase 1: Task-bundle intake and required reading order
|
|
111
124
|
|
|
112
125
|
**REQUIRED SUB-SKILL:** Invoke [okstra-context-loader](./skills/okstra-context-loader/SKILL.md) first to discover task bundle paths.
|
|
@@ -69,6 +69,8 @@ When returning results, organize into the following sections in this exact order
|
|
|
69
69
|
|
|
70
70
|
Include file paths and line numbers when discussing code evidence.
|
|
71
71
|
|
|
72
|
+
**Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
|
|
73
|
+
|
|
72
74
|
This contract mirrors the `okstra-team-contract` skill's Worker Output Contract — that skill is the authoritative source if the two ever diverge.
|
|
73
75
|
|
|
74
76
|
## Stop Condition (BLOCKING)
|
|
@@ -123,6 +123,8 @@ When returning results, organize into the following sections in this exact order
|
|
|
123
123
|
|
|
124
124
|
Include file paths and line numbers when discussing code evidence.
|
|
125
125
|
|
|
126
|
+
**Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
|
|
127
|
+
|
|
126
128
|
This contract mirrors the `okstra-team-contract` skill's Worker Output Contract — that skill is the authoritative source if the two ever diverge.
|
|
127
129
|
|
|
128
130
|
## Error reporting
|
|
@@ -123,6 +123,8 @@ When returning results, organize into the following sections in this exact order
|
|
|
123
123
|
|
|
124
124
|
Include file paths and line numbers when discussing code evidence.
|
|
125
125
|
|
|
126
|
+
**Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
|
|
127
|
+
|
|
126
128
|
This contract mirrors the `okstra-team-contract` skill's Worker Output Contract — that skill is the authoritative source if the two ever diverge.
|
|
127
129
|
|
|
128
130
|
## Error reporting
|
|
@@ -62,6 +62,7 @@ Hard rules:
|
|
|
62
62
|
- If only one analysis worker produced a usable result, perform a reduced-confidence write-up and say so explicitly.
|
|
63
63
|
- If evidence is missing, write `I don't know` rather than fabricating confidence.
|
|
64
64
|
- Cite file paths and line numbers for every code-evidence claim.
|
|
65
|
+
- Preserve every analysis worker's ticket tagging (`Ticket ID` columns and `[TICKETID: <id>]` prefixes) when carrying findings into the final report. Populate the final report's top-level `## Ticket Coverage` table per the rules in `templates/reports/final-report.template.md`. For runs that do not require ticket tagging (e.g. `release-handoff`, `final-verification`), omit the `Ticket Coverage` table and do not invent ticket IDs.
|
|
65
66
|
|
|
66
67
|
Write the file with your `Write` tool against the absolute `Result Path`. Do not return the report inline as your subagent response — the file on disk is the canonical artifact. Your subagent response should be a short status line: `Final report written to <abs path>. Worker-results pointer written to <pointer path>. Sections: <count>. Convergence categories represented: full=<n>, partial=<n>, contested=<n>, unique=<n>.`
|
|
67
68
|
|
package/runtime/bin/okstra.sh
CHANGED
|
@@ -79,6 +79,7 @@ okstra execution summary:
|
|
|
79
79
|
workers override: ${WORKERS_OVERRIDE:-None}
|
|
80
80
|
executor (implementation only): ${EXECUTOR_OVERRIDE:-default(claude)}
|
|
81
81
|
approved plan: ${APPROVED_PLAN_PATH:-None}
|
|
82
|
+
approve ack (CLI 승인 의사): ${APPROVE_PLAN_ACK}
|
|
82
83
|
related tasks: ${RELATED_TASKS_RAW:-None}
|
|
83
84
|
CONFIRM_EOF
|
|
84
85
|
printf 'Continue? [y/yes]: ' >&2
|
|
@@ -115,7 +116,9 @@ PY_ARGS=(
|
|
|
115
116
|
[[ -n "${EXECUTOR_OVERRIDE-}" ]] && PY_ARGS+=(--executor "$EXECUTOR_OVERRIDE")
|
|
116
117
|
[[ -n "${RELATED_TASKS_RAW-}" ]] && PY_ARGS+=(--related-tasks "$RELATED_TASKS_RAW")
|
|
117
118
|
[[ -n "${APPROVED_PLAN_PATH-}" ]] && PY_ARGS+=(--approved-plan "$APPROVED_PLAN_PATH")
|
|
119
|
+
[[ "$APPROVE_PLAN_ACK" == "true" ]] && PY_ARGS+=(--approve)
|
|
118
120
|
[[ -n "${CLARIFICATION_RESPONSE_PATH-}" ]] && PY_ARGS+=(--clarification-response "$CLARIFICATION_RESPONSE_PATH")
|
|
121
|
+
[[ -n "${WORK_CATEGORY-}" ]] && PY_ARGS+=(--work-category "$WORK_CATEGORY")
|
|
119
122
|
[[ "$RENDER_ONLY" == "true" ]] && PY_ARGS+=(--render-only)
|
|
120
123
|
[[ "$REFRESH_OKSTRA_ASSETS" == "true" ]] && PY_ARGS+=(--refresh-assets)
|
|
121
124
|
|
|
@@ -37,6 +37,17 @@ Invoke the `okstra` skill now. Read the manifests below for all task metadata, p
|
|
|
37
37
|
- Final status: `{{FINAL_STATUS_RELATIVE_PATH}}`
|
|
38
38
|
- Validator: `{{RUN_VALIDATOR_RELATIVE_PATH}}`
|
|
39
39
|
|
|
40
|
+
## Executor Worktree
|
|
41
|
+
|
|
42
|
+
- Status: `{{EXECUTOR_WORKTREE_STATUS}}`
|
|
43
|
+
- Working tree path: `{{EXECUTOR_WORKTREE_PATH}}`
|
|
44
|
+
- Branch: `{{EXECUTOR_WORKTREE_BRANCH}}`
|
|
45
|
+
- Base ref: `{{EXECUTOR_WORKTREE_BASE_REF}}`
|
|
46
|
+
- Note: `{{EXECUTOR_WORKTREE_NOTE}}`
|
|
47
|
+
- For `implementation` runs with status `created`, the Executor MUST perform every Edit / Write / build / test command inside the working tree path above. Verifiers (Claude / Codex / Gemini) read from the SAME path so they observe the exact diff produced by the Executor.
|
|
48
|
+
- The worktree is preserved after the run (no automatic cleanup). PR authoring, manual review, and rollback verification happen from the worktree branch.
|
|
49
|
+
- For any other status (`skipped-non-implementation`, `skipped-in-worktree`, `skipped-not-git`), the run operates directly in `{{PROJECT_ROOT}}` and this section is informational only.
|
|
50
|
+
|
|
40
51
|
## Available MCP Servers
|
|
41
52
|
|
|
42
53
|
{{AVAILABLE_MCP_SERVERS}}
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
- Authority & permissions assumption (HARD RULE — applies to every okstra task-type):
|
|
41
41
|
- **Assume the user (and their team) holds full authority and every permission required for the anticipated work.** Treat external approvals, third-party access grants, role/IAM permissions, organisational sign-off, legal/compliance review, vendor coordination, and "verify access exists" steps as already satisfied unless the user explicitly states otherwise in the task brief.
|
|
42
42
|
- Do NOT add such items to option trade-offs, dependency/migration risk, validation checklists, rollout plans, `Open Questions`, or day/effort estimates. They are not legitimate sources of schedule extension; effort sizing must reflect engineering work only.
|
|
43
|
-
- The `User Approval Request` block at the
|
|
43
|
+
- The `User Approval Request (사용자 승인 게이트)` block at the **top of the final report** (immediately under the metadata header, before `Section 0`) is the only authorised approval gate — that gate is the user themselves, who clears it either by (a) editing the single checkbox `- [ ] Approved` to `- [x] Approved` directly, or (b) invoking the next phase with `--approve` so the CLI invocation itself is treated as the approval signal and the runtime flips the checkbox on the user's behalf. No external coordination is expected.
|
|
44
44
|
- Non-goals:
|
|
45
45
|
- code-level micro-optimization unless it changes the implementation approach
|
|
46
46
|
- **source code edits of any kind** — this run produces a plan document only; Edit/Write on project source files is forbidden until the plan is approved and a separate `implementation` run starts
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
- dependency / migration risk assessment (ordering constraints, data backfills, feature-flag prerequisites, cross-team coordination)
|
|
67
67
|
- validation checklist (pre / mid / post) — each item is an exact command or observable outcome
|
|
68
68
|
- rollback strategy — exact revert path (commits, flags, migrations) and the signal that triggers rollback
|
|
69
|
-
- explicit `User Approval Request` block
|
|
69
|
+
- explicit `User Approval Request (사용자 승인 게이트)` block placed at the **top of the report** with a single canonical checkbox marker `- [ ] Approved` (user toggles to `- [x] Approved` to authorise the next `implementation` run). Section `4.5.8` is retained only as a back-pointer to this top block for validator/key-substring compatibility — it must NOT carry an independent marker.
|
|
70
70
|
- `Open Questions` block listing every ambiguity flagged during pre-planning that the user must resolve before approval
|
|
71
71
|
- No-placeholder rule (plan failures — reject any option or step that contains these):
|
|
72
72
|
- "TBD", "TODO", "implement later", "fill in details", "add appropriate error handling", "handle edge cases", "write tests for the above" without actual test code
|
|
@@ -26,8 +26,22 @@
|
|
|
26
26
|
- the read-only MCP servers declared in the task brief's `## Available MCP Servers` section may be queried by both executor and verifiers as a read-only cross-check (sanity-checking row counts after a migration script's dry-run, comparing observed schema against the plan's expectations, etc.); that section is the canonical source of which servers and tools exist for this run, and any MCP-derived evidence MUST cite server, table, and the SELECT used. MCP MUST NEVER be used as a write path — schema/data mutations go through repository migration files, never through this MCP.
|
|
27
27
|
- Pre-implementation gate (mandatory — refuse to start if any item fails):
|
|
28
28
|
- the run brief MUST cite `--approved-plan <path>` pointing to a `final-report.md` produced by a prior `implementation-planning` run located under `runs/implementation-planning/.../reports/final-report.md`
|
|
29
|
-
- that file MUST contain a `User Approval Request` block AND a recorded user approval marker
|
|
29
|
+
- that file MUST contain a `User Approval Request` block (canonically placed at the **top of the report**, immediately under the metadata header) AND a recorded user approval marker. The canonical, recommended form is the single markdown checkbox line `- [x] Approved`. The runtime regex in `okstra_ctl.run._validate_approved_plan` also accepts (case-insensitive, line-anchored, optional leading `-`/`*`/`+` bullet): `APPROVED` (alone, followed by `:`, or end-of-line), `[x] Approved`, or `User Approval: APPROVED|granted|yes`. Free-form approvals such as "lgtm", "go ahead", or paraphrased confirmations are intentionally NOT accepted; if the user's approval is informal, re-edit the plan file to flip the top checkbox to `- [x] Approved` before invoking the implementation run.
|
|
30
|
+
- Two equally-valid approval paths exist (both end up satisfying the same regex gate):
|
|
31
|
+
- **Manual edit** — the user opens the report, flips `- [ ] Approved` to `- [x] Approved`, saves, then runs `okstra ... --task-type implementation --approved-plan <path>`.
|
|
32
|
+
- **CLI ack** — the user runs `okstra ... --task-type implementation --approved-plan <path> --approve`. The CLI invocation itself is modelled as the user's act of approval; the runtime (`okstra_ctl.run._apply_cli_approval`) flips the checkbox in the report file and appends an audit line `- 승인 일시 (CLI ack): <ISO8601> — recorded by \`okstra --approve\`` before the standard regex validation runs. Use this when running unattended or when you want a single command to both approve and launch the next phase.
|
|
33
|
+
- The `--approve` flag is **only meaningful with `--task-type implementation` and `--approved-plan <path>`**. Passing it with any other task-type causes `PrepareError` (the runtime refuses to silently ignore approval signals). It is also a no-op if the file already carries a valid approval marker (idempotent — only an audit line is appended, the marker is not re-toggled).
|
|
30
34
|
- the file's `Recommended option` and its bite-sized step list become the authoritative scope for this run; any deviation must be justified in the final report and routed back to a new `implementation-planning` run instead of being silently expanded.
|
|
35
|
+
- Executor worktree (provisioned by `okstra-ctl` at run-prep time, fixed for this run):
|
|
36
|
+
- Status: `{{EXECUTOR_WORKTREE_STATUS}}` (one of: `created` | `skipped-in-worktree` | `skipped-not-git`)
|
|
37
|
+
- Working tree path: `{{EXECUTOR_WORKTREE_PATH}}` — when status is `created`, this is a fresh `git worktree` rooted under `~/.okstra/worktrees/<project>/<task-group>/<task-id>-<seq>`; when skipped, this is the caller's `project_root`.
|
|
38
|
+
- Branch: `{{EXECUTOR_WORKTREE_BRANCH}}` — empty when status is `skipped-*`. The branch name encodes `<work-category-prefix>-<task-id-segment>-<seq>`.
|
|
39
|
+
- Base ref: `{{EXECUTOR_WORKTREE_BASE_REF}}` — commit SHA the worktree was branched from; canonical `<base>` for every `git diff` / `git log` in this run.
|
|
40
|
+
- Provisioning note: `{{EXECUTOR_WORKTREE_NOTE}}`
|
|
41
|
+
- **Executor behaviour**: when status is `created`, the Executor MUST run every Edit / Write / build / test / commit command with the working tree path above as cwd. Treat it as `project_root` for the duration of this run. Do NOT mutate the caller's original checkout. Do NOT `cd` out of the worktree to reach files; if a file outside the worktree is needed, the dependency is a planning gap — record it in `Out-of-plan edits` and continue.
|
|
42
|
+
- **Verifier behaviour**: all three verifier roles read from the SAME working tree path so they observe the exact diff the Executor produced. Verifiers remain strictly read-only there.
|
|
43
|
+
- **Lifecycle**: the worktree is kept after the run completes (no automatic cleanup). It is the canonical artefact for manual PR authoring, rollback verification, and follow-up `final-verification` runs. Cleanup, when desired, is manual: `git -C <project_root> worktree remove <path>` followed by `git -C <project_root> branch -D <branch>`.
|
|
44
|
+
- **Skipped paths**: when status is `skipped-in-worktree` or `skipped-not-git`, the executor operates in `project_root` as before. Cite the status in the final report's metadata header so reviewers know which path was taken.
|
|
31
45
|
- Pre-implementation context exploration (executor before first edit):
|
|
32
46
|
- re-read the approved plan end-to-end and extract: file list, step order, validation commands, rollback path
|
|
33
47
|
- inspect the current state of every file the plan names; if any file has changed materially since the plan was written, stop and route to a new `implementation-planning` run instead of editing speculatively
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Release Handoff Profile
|
|
2
|
+
|
|
3
|
+
- Purpose: take an `accepted` final-verification verdict and turn it into a delivered commit and/or pull request, with explicit user selection at every mutating step
|
|
4
|
+
- Required workers:
|
|
5
|
+
- claude
|
|
6
|
+
- report-writer
|
|
7
|
+
- Workers:
|
|
8
|
+
- claude
|
|
9
|
+
- report-writer
|
|
10
|
+
- Team contract:
|
|
11
|
+
- `Claude lead` is the **executor of every git / gh command** in this phase. Workers never call mutating git commands themselves.
|
|
12
|
+
- `Claude worker` (drafter) is read-only and produces **commit message candidate(s) and a PR body candidate** in markdown; the lead presents these to the user, accepts edits, and only then runs git.
|
|
13
|
+
- `Report writer worker` authors the final-report file documenting what was executed (commit SHA list, PR URL, user selections, skipped actions). `Claude lead` reviews and approves the draft and does NOT write the file itself (see `okstra-team-contract` and `okstra-report-writer`).
|
|
14
|
+
- default model assignments are resolved from centralised defaults; the fallback values are `Claude lead`/`Report writer worker`=`opus`, `Claude worker`=`sonnet`.
|
|
15
|
+
- unnamed generic parallel workers must not replace the required role roster, and no additional sub-agent dispatch is allowed beyond this roster.
|
|
16
|
+
- Pre-handoff entry gate (mandatory — refuse to start if any item fails):
|
|
17
|
+
- the task brief MUST cite the originating `final-verification` final-report path under `## Source Verification Report`. The lead opens that file and confirms section `## 2. Final Verdict` contains exactly the token `accepted`.
|
|
18
|
+
- if the verdict is `conditional-accept`, `blocked`, or any other token (including ambiguous phrasing like "looks good"), the run MUST end immediately with status `blocked` and a routing recommendation back to `error-analysis` or `implementation-planning`. Do NOT prompt the user; do NOT run any git command.
|
|
19
|
+
- the lead MUST capture `git status --short` and confirm the working tree is clean OR contains only the files listed in the prior `implementation` run's `Out-of-plan edits` block. Unexpected dirty state aborts the run.
|
|
20
|
+
- the lead MUST capture `git rev-parse --abbrev-ref HEAD` and record it as the **feature branch**. If the current branch is itself `main`, `master`, `prod`, `preprod`, `staging`, or `dev`, the run MUST end immediately — release-handoff never operates on a base branch.
|
|
21
|
+
- User interaction protocol (Claude lead — performed in order, using `AskUserQuestion` or the equivalent interactive prompt):
|
|
22
|
+
1. **Action selection** — present three choices and capture exactly one:
|
|
23
|
+
- `commit only` — stage and commit the working-tree changes locally; no push, no PR.
|
|
24
|
+
- `commit + PR` — commit, push the feature branch, then open a pull request.
|
|
25
|
+
- `skip` — record the verified state and end the run without any git command.
|
|
26
|
+
If the user picks `skip`, route directly to the final-report self-review pass.
|
|
27
|
+
2. **PR base branch** (only when the user picked `commit + PR`) — present six options and capture exactly one:
|
|
28
|
+
- `staging`
|
|
29
|
+
- `preprod`
|
|
30
|
+
- `prod`
|
|
31
|
+
- `main`
|
|
32
|
+
- `dev`
|
|
33
|
+
- `직접 입력` (free-form branch name; lead validates the name exists on origin via `git ls-remote --heads origin <name>` and re-asks on failure)
|
|
34
|
+
The chosen base MUST NOT equal the feature branch. If it does, re-ask.
|
|
35
|
+
3. **Commit message + PR body confirmation** — show the `Claude worker` drafter's output verbatim and capture one of:
|
|
36
|
+
- `use as-is` — proceed with the drafter's text.
|
|
37
|
+
- `edit then proceed` — accept inline edits from the user, then proceed with the edited text.
|
|
38
|
+
- `cancel` — end the run without executing any git command; record the cancellation in the final report.
|
|
39
|
+
- Drafter worker contract (`Claude worker`):
|
|
40
|
+
- reads the run brief, the cited final-verification report, and `git diff <base>..HEAD --stat` to ground its output in actual changes.
|
|
41
|
+
- produces **two artifacts** in its worker result:
|
|
42
|
+
1. **Commit message candidate** — a single message in Conventional Commits style (`<type>(<scope>): <subject>` + optional body + optional footer). When `commit + PR` will be opened against a `release-please`-managed repo, the type MUST match a configured changelog section (`feat` / `fix` / `perf` / `revert` / `deps` / `docs` / `refactor` / `build` / `ci` / `chore` / `test`).
|
|
43
|
+
2. **PR body candidate** — markdown with sections `## Summary`, `## Changes`, `## Test plan`, `## Linked issues` (omit a section only if it is genuinely empty).
|
|
44
|
+
- is strictly **read-only**: MUST NOT run any git mutating command, MUST NOT call `gh pr create`, MUST NOT call `git push`.
|
|
45
|
+
- if the drafter cannot produce output (no diff exists, repo is bare, etc.), it returns terminal status `not-run` with a reason; the lead falls back to a manually-authored message captured directly from the user.
|
|
46
|
+
- Allowed actions during the run (Claude lead only — workers stay read-only):
|
|
47
|
+
- read-only inspection: `git status`, `git status --short`, `git diff`, `git log`, `git rev-parse`, `git ls-remote --heads origin <name>`, `gh pr list --head <branch>`, `gh pr view <url>`.
|
|
48
|
+
- local commit: `git add -- <path>...` (prefer explicit file paths over `git add -A` / `git add .`), `git commit -m "<message>"`. Re-use the user-confirmed message exactly.
|
|
49
|
+
- feature-branch push (only when the user picked `commit + PR`): `git push -u origin <current-branch>`. The pushed ref MUST be the feature branch — never the chosen base branch.
|
|
50
|
+
- PR creation (only when the user picked `commit + PR` AND no PR with the same head already exists on origin): `gh pr create --base <chosen-base> --head <current-branch> --title "<title>" --body "<body>"`. The title is the commit message subject by default; the body is the user-confirmed PR body.
|
|
51
|
+
- PR reuse: if `gh pr list --head <branch> --state open --json url --jq '.[0].url'` returns a URL, treat that PR as already existing — record the URL in the final report and SKIP `gh pr create`.
|
|
52
|
+
- Idempotency: if `git diff --cached` and `git diff` are both empty (nothing to commit), record "no staged changes; commit skipped" in the final report and skip `git commit` while still proceeding to the PR step if requested.
|
|
53
|
+
- Authority & permissions assumption (HARD RULE — applies to every okstra task-type):
|
|
54
|
+
- **Assume the user (and their team) holds full authority and every permission required for the delivered and follow-up work.** Treat external approvals, third-party access grants, role/IAM permissions, organisational sign-off, legal/compliance review, vendor coordination, and "verify access exists" steps as already satisfied unless the task brief explicitly states otherwise.
|
|
55
|
+
- Do NOT raise such items as blockers, residual risks, or release recommendations.
|
|
56
|
+
- This rule does NOT relax the forbidden-action list below; the safety rules below remain in force regardless of the user's authority.
|
|
57
|
+
- Forbidden actions (any occurrence → terminal status `contract-violated`):
|
|
58
|
+
- any of the following git push variants, regardless of intent or whether the user said "force it":
|
|
59
|
+
- `git push --force`
|
|
60
|
+
- `git push --force-with-lease`
|
|
61
|
+
- `git push -f`
|
|
62
|
+
- `git push +<refspec>`
|
|
63
|
+
- any other invocation that rewrites remote history
|
|
64
|
+
- pushing directly to a base branch — i.e. `git push origin <branch>` where `<branch>` is `main`, `master`, `prod`, `preprod`, `staging`, `dev`, or the branch the user chose as the PR base in this run. The only permitted push target is the current feature branch.
|
|
65
|
+
- bypassing repo safeguards: `--no-verify` / `-n` on `git commit` or `git push`, disabling GPG signing via `-c commit.gpgsign=false` / `--no-gpg-sign`, or any equivalent flag-based hook bypass.
|
|
66
|
+
- release-publishing commands: `gh release create`, `gh release edit`, `npm publish`, `cargo publish`, `pip publish`, `twine upload`, `docker push`, `terraform apply`, `kubectl apply` against any non-local cluster.
|
|
67
|
+
- source-code edits, refactors, or any modification to files outside the run's own artifact directories (`reports/`, `prompts/`, `state/`, `manifests/`, `worker-results/`, `status/`, `sessions/`). The diff being shipped MUST be exactly what the prior `implementation` run produced; release-handoff packages it, it does not re-author it.
|
|
68
|
+
- executing any mutating command the user did NOT select. Examples: opening a PR when the user picked `commit only`; running `git commit` when the user picked `skip`; switching the PR base branch silently after the user already chose one.
|
|
69
|
+
- retrying a failed git / gh command with weaker safety flags. If `git push` fails with non-fast-forward, the lead MUST stop, explain the failure to the user, and ask for instructions — it MUST NOT add `--force`.
|
|
70
|
+
- dispatching parallel sub-agents beyond the required worker roster.
|
|
71
|
+
- silently treating an unrecognised user reply as one of the menu options. If the user's answer does not match a presented choice, re-ask the question verbatim.
|
|
72
|
+
- Required deliverable shape (final report, in addition to the standard sections):
|
|
73
|
+
- **Source Verification Report**: relative path of the originating `final-verification` final-report file plus the literal quoted `## 2. Final Verdict` line that read `accepted`.
|
|
74
|
+
- **Feature Branch & Working-Tree State**: branch name from `git rev-parse --abbrev-ref HEAD`, output of `git status --short` at run start.
|
|
75
|
+
- **User Selections**: a block recording each prompt and the user's verbatim answer.
|
|
76
|
+
- Q1 action: `commit only` | `commit + PR` | `skip`.
|
|
77
|
+
- Q2 PR base (if applicable): the chosen branch and how it was selected (menu pick vs free-form input).
|
|
78
|
+
- Q3 message/body: `use as-is` | `edit then proceed` (with a diff between the drafter's text and the final text) | `cancel`.
|
|
79
|
+
- **Executed Commands**: every git / gh command the lead actually ran, with its exit code and a one-line stdout/stderr summary. Read-only inspection commands MAY be summarised; mutating commands MUST be listed verbatim.
|
|
80
|
+
- **Commit List**: each commit SHA (short and full), its subject line, and the files it touched. If no commit was produced (idempotent no-op), state `- No commit was produced (working tree had no staged changes).`
|
|
81
|
+
- **Pull Request Outcome**: one of
|
|
82
|
+
- `- No PR action requested.` (user picked `commit only` or `skip`)
|
|
83
|
+
- `- PR created: <url>` with title and base branch
|
|
84
|
+
- `- PR reused: <url>` when an existing PR was found via `gh pr list`
|
|
85
|
+
- `- PR creation skipped: <reason>` for any user-driven cancellation
|
|
86
|
+
- **Routing recommendation**: explicit `done` token, since release-handoff is the terminal lifecycle phase. If the run ended in `skip` or `cancel`, the recommendation MUST also state whether re-entry into release-handoff is appropriate.
|
|
87
|
+
- Self-review pass before finalising the report (`Claude lead` runs this; do not delegate to a generic subagent):
|
|
88
|
+
1. **Entry-gate audit** — section 2 cites the originating final-verification report path and the literal `accepted` verdict line. If either is missing, the run is invalid and MUST be re-routed to `final-verification`.
|
|
89
|
+
2. **User-selection traceability** — every executed mutating command maps to a user selection captured in the report. Any mutating command without a corresponding user answer is a contract violation.
|
|
90
|
+
3. **Forbidden-action audit** — scan the run's session transcripts (`git`, `gh` invocations) for every entry in the Forbidden actions list above. Any occurrence means the run has crossed into unsafe territory and MUST be flagged as `contract-violated`.
|
|
91
|
+
4. **Push-target audit** — for every `git push` recorded, confirm the refspec resolves to the feature branch, not the base branch.
|
|
92
|
+
5. **Idempotency check** — if a PR with the same head already existed at run start, confirm the report records `PR reused` rather than a fresh `gh pr create` invocation.
|
|
93
|
+
- Non-goals:
|
|
94
|
+
- re-litigating the final-verification verdict — release-handoff trusts the cited `accepted` verdict and does not reopen acceptance checks.
|
|
95
|
+
- opening additional PRs, releases, or deployments beyond the single PR the user chose to create.
|
|
96
|
+
- merging the PR. Merging is a separate, manual step performed by the user (or by repo automation) after release-handoff ends; the lead MUST NOT call `gh pr merge`.
|
|
97
|
+
- treating "다음 단계 진행해" or equivalent user phrases as authorisation to escalate beyond the menu choices — every mutating action requires an explicit menu selection.
|
|
@@ -140,6 +140,10 @@ while [[ $# -gt 0 ]]; do
|
|
|
140
140
|
RELATED_TASKS_RAW="$(require_option_value --related-tasks "${2-}")"
|
|
141
141
|
shift 2
|
|
142
142
|
;;
|
|
143
|
+
--work-category)
|
|
144
|
+
WORK_CATEGORY="$(require_option_value --work-category "${2-}")"
|
|
145
|
+
shift 2
|
|
146
|
+
;;
|
|
143
147
|
--task-type)
|
|
144
148
|
ANALYSIS_TYPE="$(require_option_value --task-type "${2-}")"
|
|
145
149
|
shift 2
|
|
@@ -180,6 +184,13 @@ while [[ $# -gt 0 ]]; do
|
|
|
180
184
|
APPROVED_PLAN_PATH="$(require_option_value --approved-plan "${2-}")"
|
|
181
185
|
shift 2
|
|
182
186
|
;;
|
|
187
|
+
--approve)
|
|
188
|
+
# 사용자가 CLI 명령을 입력한 행위 자체를 plan 승인 의사로 간주한다.
|
|
189
|
+
# 런타임에서 approved-plan 파일의 승인 체크박스를 [x] 로 갱신하고
|
|
190
|
+
# 승인 시각/방식을 함께 기록한다 (scripts/okstra_ctl/run.py 참조).
|
|
191
|
+
APPROVE_PLAN_ACK="true"
|
|
192
|
+
shift
|
|
193
|
+
;;
|
|
183
194
|
-h|--help)
|
|
184
195
|
usage
|
|
185
196
|
exit 0
|
|
@@ -190,7 +201,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
190
201
|
printf 'unknown option: %s\n' "$__unknown_opt" >&2
|
|
191
202
|
case "$__opt_name" in
|
|
192
203
|
--phase|--phases|--lifecycle-phase)
|
|
193
|
-
printf ' hint: --phase is not a valid flag. Use --task-type <requirements-discovery|error-analysis|implementation-planning|implementation|final-verification>.\n' >&2
|
|
204
|
+
printf ' hint: --phase is not a valid flag. Use --task-type <requirements-discovery|error-analysis|implementation-planning|implementation|final-verification|release-handoff>.\n' >&2
|
|
194
205
|
printf ' "phase" is a manifest lifecycle field name, not a CLI option.\n' >&2
|
|
195
206
|
;;
|
|
196
207
|
--brief|--task-brief)
|
|
@@ -209,7 +220,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
209
220
|
printf ' hint: did you mean --task-id?\n' >&2
|
|
210
221
|
;;
|
|
211
222
|
esac
|
|
212
|
-
printf ' valid options: --render-only --resume-clarification --yes --refresh-assets --workers --lead-model --claude-model --codex-model --gemini-model --report-writer-model --
|
|
223
|
+
printf ' valid options: --render-only --resume-clarification --yes --refresh-assets --workers --lead-model --claude-model --codex-model --gemini-model --report-writer-model --related-tasks --task-type --project-id --project-root --task-group --task-id --task-brief --directive --clarification-response --approved-plan --approve -h|--help\n' >&2
|
|
213
224
|
usage
|
|
214
225
|
exit 1
|
|
215
226
|
;;
|
|
@@ -25,6 +25,7 @@ CODEX_MODEL_OVERRIDE=""
|
|
|
25
25
|
GEMINI_MODEL_OVERRIDE=""
|
|
26
26
|
REPORT_WRITER_MODEL_OVERRIDE=""
|
|
27
27
|
EXECUTOR_OVERRIDE=""
|
|
28
|
+
WORK_CATEGORY=""
|
|
28
29
|
RELATED_TASKS_RAW=""
|
|
29
30
|
ANALYSIS_TYPE=""
|
|
30
31
|
BRIEF_PATH=""
|
|
@@ -37,6 +38,7 @@ REVIEW_PROFILE=""
|
|
|
37
38
|
DIRECTIVE=""
|
|
38
39
|
CLARIFICATION_RESPONSE_PATH=""
|
|
39
40
|
APPROVED_PLAN_PATH=""
|
|
41
|
+
APPROVE_PLAN_ACK="false"
|
|
40
42
|
CLARIFICATION_RESPONSE_FILE=""
|
|
41
43
|
CLARIFICATION_RESPONSE_RELATIVE_PATH=""
|
|
42
44
|
PROJECT_ROOT=""
|
|
@@ -39,6 +39,12 @@ optional arguments:
|
|
|
39
39
|
should prefer --resume-clarification, which wraps this flag.
|
|
40
40
|
--approved-plan Path to the approved final-report.md from a prior implementation-planning run.
|
|
41
41
|
Required when --task-type=implementation; the file MUST contain a recorded user approval marker.
|
|
42
|
+
--approve Treat the user's CLI invocation itself as the plan-approval signal. Only meaningful
|
|
43
|
+
together with --approved-plan and --task-type=implementation. The runtime updates the
|
|
44
|
+
top "User Approval Request" block of the approved-plan file: flips
|
|
45
|
+
\`- [ ] Approved\` to \`- [x] Approved\` and appends an approval audit line
|
|
46
|
+
(timestamp + "CLI --approve"). Use this for scripted/CI flows or when you want a
|
|
47
|
+
single command to both approve and launch the next phase.
|
|
42
48
|
--task-key <project-id:task-group:task-id>
|
|
43
49
|
Shorthand for --project-id/--task-group/--task-id. When the matching task-manifest.json
|
|
44
50
|
exists, brief-path and task-type are auto-filled from it (taskBriefPath and
|
|
@@ -72,6 +78,11 @@ options:
|
|
|
72
78
|
providers are dispatched as read-only verifiers regardless of this selection.
|
|
73
79
|
Has no effect on other task types.
|
|
74
80
|
--related-tasks Optional comma-separated related task identifiers. Example: auth-token-refresh,frontend-login-ui
|
|
81
|
+
--work-category Work-category classification for this task. One of:
|
|
82
|
+
bugfix | feature | refactor | ops | improvement | unknown.
|
|
83
|
+
Defaults to 'unknown' when omitted. Use this when the
|
|
84
|
+
lifecycle skipped --task-type=requirements-discovery
|
|
85
|
+
(where work-category would otherwise be inferred).
|
|
75
86
|
--task-type Set the task purpose for this run and select the matching profile file.
|
|
76
87
|
-h, --help Show this help.
|
|
77
88
|
|
|
@@ -415,14 +415,15 @@ def render_task_manifest(manifest_path: str, ctx: dict) -> None:
|
|
|
415
415
|
catalog = _worker_catalog(ctx)
|
|
416
416
|
phase_sequence = [
|
|
417
417
|
"requirements-discovery", "error-analysis", "implementation-planning",
|
|
418
|
-
"implementation", "final-verification",
|
|
418
|
+
"implementation", "final-verification", "release-handoff",
|
|
419
419
|
]
|
|
420
420
|
default_next_phase = {
|
|
421
421
|
"requirements-discovery": "pending-routing-decision",
|
|
422
422
|
"error-analysis": "implementation-planning",
|
|
423
423
|
"implementation-planning": "implementation",
|
|
424
424
|
"implementation": "final-verification",
|
|
425
|
-
"final-verification": "
|
|
425
|
+
"final-verification": "pending-release-handoff",
|
|
426
|
+
"release-handoff": "done-or-follow-up",
|
|
426
427
|
}
|
|
427
428
|
required_worker_roles = _required_worker_roles(ctx, reviewers)
|
|
428
429
|
worker_prompt_paths = {item: catalog[item]["promptPath"] for item in reviewers}
|
|
@@ -438,10 +439,19 @@ def render_task_manifest(manifest_path: str, ctx: dict) -> None:
|
|
|
438
439
|
if current_phase:
|
|
439
440
|
phase_states[current_phase] = current_phase_state
|
|
440
441
|
work_category = existing.get("workCategory") or ctx.get("WORKFLOW_WORK_CATEGORY", "unknown")
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
442
|
+
# Compute the canonical next phase from current_phase deterministically.
|
|
443
|
+
# Only preserve `existing.workflow.nextRecommendedPhase` when it is a
|
|
444
|
+
# legitimate forward pointer — i.e. NOT equal to `current_phase` itself
|
|
445
|
+
# (which would mean the lifecycle pointer has stalled on the current
|
|
446
|
+
# phase and would loop forever).
|
|
447
|
+
canonical_next = default_next_phase.get(
|
|
448
|
+
current_phase, ctx.get("WORKFLOW_NEXT_RECOMMENDED_PHASE", "unknown")
|
|
444
449
|
)
|
|
450
|
+
existing_next = workflow.get("nextRecommendedPhase") or ""
|
|
451
|
+
if existing_next and existing_next != current_phase:
|
|
452
|
+
next_recommended_phase = existing_next
|
|
453
|
+
else:
|
|
454
|
+
next_recommended_phase = canonical_next
|
|
445
455
|
last_completed_phase = workflow.get("lastCompletedPhase") or ctx.get("WORKFLOW_LAST_COMPLETED_PHASE", "")
|
|
446
456
|
routing_status = workflow.get("routingStatus") or ctx.get("WORKFLOW_ROUTING_STATUS", "not-applicable")
|
|
447
457
|
awaiting_approval = workflow.get("awaitingApproval")
|
|
@@ -800,6 +810,7 @@ def render_task_index(template_path: str, output_path: str, ctx: dict) -> None:
|
|
|
800
810
|
phase_order = [
|
|
801
811
|
"requirements-discovery", "error-analysis",
|
|
802
812
|
"implementation-planning", "implementation", "final-verification",
|
|
813
|
+
"release-handoff",
|
|
803
814
|
]
|
|
804
815
|
phase_state_lines = [
|
|
805
816
|
f"- `{phase}`: `{phase_states.get(phase, 'not-started')}`"
|
|
@@ -1068,6 +1079,11 @@ def render_template_file(template_path: str, output_path: str, ctx: dict) -> Non
|
|
|
1068
1079
|
"AVAILABLE_MCP_SERVERS",
|
|
1069
1080
|
build_available_mcp_servers_block(Path(ctx.get("PROJECT_ROOT", "."))),
|
|
1070
1081
|
),
|
|
1082
|
+
"{{EXECUTOR_WORKTREE_PATH}}": ctx.get("EXECUTOR_WORKTREE_PATH", ""),
|
|
1083
|
+
"{{EXECUTOR_WORKTREE_BRANCH}}": ctx.get("EXECUTOR_WORKTREE_BRANCH", ""),
|
|
1084
|
+
"{{EXECUTOR_WORKTREE_BASE_REF}}": ctx.get("EXECUTOR_WORKTREE_BASE_REF", ""),
|
|
1085
|
+
"{{EXECUTOR_WORKTREE_STATUS}}": ctx.get("EXECUTOR_WORKTREE_STATUS", ""),
|
|
1086
|
+
"{{EXECUTOR_WORKTREE_NOTE}}": ctx.get("EXECUTOR_WORKTREE_NOTE", ""),
|
|
1071
1087
|
}
|
|
1072
1088
|
rendered = template
|
|
1073
1089
|
for k, v in mapping.items():
|