okstra 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1281 -18
- package/package.json +5 -7
- package/runtime/BUILD.json +3 -3
- package/runtime/skills/okstra-context-loader/SKILL.md +140 -0
- package/runtime/skills/okstra-convergence/SKILL.md +289 -0
- package/runtime/skills/okstra-history/SKILL.md +118 -0
- package/runtime/skills/okstra-report-finder/SKILL.md +68 -0
- package/runtime/skills/okstra-report-writer/SKILL.md +256 -0
- package/runtime/skills/okstra-run/SKILL.md +223 -0
- package/runtime/skills/okstra-schedule/SKILL.md +605 -0
- package/runtime/skills/okstra-status/SKILL.md +208 -0
- package/runtime/skills/okstra-team-contract/SKILL.md +402 -0
- package/runtime/skills/okstra-time-summary/SKILL.md +119 -0
- package/runtime/skills/setup-okstra/SKILL.md +138 -0
- package/src/doctor.mjs +15 -0
- package/src/install.mjs +91 -2
- package/src/paths.mjs +2 -2
- package/src/uninstall.mjs +59 -6
package/README.md
CHANGED
|
@@ -1,36 +1,1299 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OKSTRA Usage Manual
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## At a glance
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`okstra`는 Claude Code의 cross-verify 워크플로를 위한 **task bundle 준비 도구**입니다. 단일 파일 리뷰 도구가 아니라, stable task key를 중심으로 task brief · profile · prompt · run history · project-level discovery metadata를 정형화해 Claude가 안정적으로 lead/worker orchestration을 수행할 수 있도록 돕는 보조 러너입니다.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
핵심 기능을 한눈에 정리하면 다음과 같습니다.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- **Task identity**: `<project-id>/<task-group>/<task-id>` 기반 stable task key로 task root를 생성하거나 재사용하고, manifest · index · timeline을 일관되게 갱신합니다.
|
|
10
|
+
- **Task type별 profile**: `requirements-discovery`, `error-analysis`, `implementation-planning`, `implementation`, `final-verification` 등 표준 task type 프로파일을 로드해 instruction-set을 렌더링합니다.
|
|
11
|
+
- **Run lifecycle**: 매 실행마다 per-run 디렉터리(`runs/<timestamp>/`)에 prompt snapshot, sessions/, expected-state, final report 템플릿, run manifest, timeline 이벤트를 저장합니다.
|
|
12
|
+
- **Single python authority**: 모든 prepare wiring(profile/workers/model 해소, path 계산, 9개 render, central record_start)이 [`okstra_ctl.run.prepare_task_bundle()`](scripts/okstra_ctl/run.py) 한 함수에 모여 있습니다. `okstra.sh` 와 `okstra-run` skill 은 같은 함수를 호출하는 thin caller 이며, 환경 변수로 상태를 전달하지 않습니다 — task 정체성·경로·workflow 상태는 모두 디스크 권위 파일에서 매번 계산됩니다.
|
|
13
|
+
- **Claude handoff (두 모드)**: (a) `okstra.sh` 가 새 `claude` 프로세스를 띄우는 전통 방식, (b) `okstra-run` skill 이 현재 claude 세션 안에서 prepare 후 lead 역할을 그대로 인계받는 in-session 모드. 둘 다 `prepare_task_bundle` 의 산출물(instruction-set 등)을 그대로 사용합니다.
|
|
14
|
+
- **Required team contract**: `Claude lead` + `Claude worker` · `Codex worker` · `Gemini worker` · `Report writer worker`의 필수 구성과 Agent Teams 우선 시도를 강제합니다.
|
|
15
|
+
- **User-home install + project-local task bundles**: `npx okstra@latest install` 한 명령이 런타임(`~/.okstra/{lib/python, bin}`) + 스킬 마크다운(`~/.claude/skills/<name>/SKILL.md`) 을 모두 깐다. 대상 프로젝트에는 task bundle 과 discovery metadata 만 `.project-docs/okstra/` 아래 저장됩니다 — 사용자의 `~/.claude/settings.json` 이나 프로젝트 `.claude/settings.local.json` 은 건드리지 않으며, per-session permission 은 `claude --settings` 로 런타임 주입합니다. (개발용으로는 `okstra-install.sh` 가 `--link` 모드 symlink 설치를 제공합니다.)
|
|
16
|
+
- **Resume and clarification**: `--task-key`, `--resume-clarification`, `--clarification-response`로 같은 task 재개와 lead의 추가 질문 응답 흐름을 지원합니다.
|
|
17
|
+
- **Optional integrations**: worker error sidecar, token usage / cost accounting을 옵션으로 제공합니다.
|
|
18
|
+
|
|
19
|
+
판단 정책과 worker orchestration은 Claude lead가 담당하고, `okstra`는 Claude가 잘 일할 수 있는 정형화된 입력 묶음과 출력 골격을 준비하는 역할에 집중합니다.
|
|
20
|
+
|
|
21
|
+
## Table of contents
|
|
22
|
+
|
|
23
|
+
- [Purpose](#purpose)
|
|
24
|
+
- [What okstra does](#what-okstra-does)
|
|
25
|
+
- [Runtime assets vs support assets](#runtime-assets-vs-support-assets)
|
|
26
|
+
- [Architecture: python authority + thin callers](#architecture-python-authority--thin-callers)
|
|
27
|
+
- [Claude execution behavior](#claude-execution-behavior)
|
|
28
|
+
- [Claude prompt contract](#claude-prompt-contract)
|
|
29
|
+
- [Required team contract](#required-team-contract)
|
|
30
|
+
- [Stable task identity](#stable-task-identity)
|
|
31
|
+
- [Project self-registration](#project-self-registration)
|
|
32
|
+
- [Task type](#task-type)
|
|
33
|
+
- [표준 task type](#표준-task-type)
|
|
34
|
+
- [Phase 간 정보 전달](#phase-간-정보-전달)
|
|
35
|
+
- [Command forms](#command-forms)
|
|
36
|
+
- [Required arguments](#required-arguments)
|
|
37
|
+
- [`--project-id`](#--project-id)
|
|
38
|
+
- [`--task-group`](#--task-group)
|
|
39
|
+
- [`--task-id`](#--task-id)
|
|
40
|
+
- [`--task-type`](#--task-type)
|
|
41
|
+
- [`--task-brief`](#--task-brief)
|
|
42
|
+
- [`--yes`](#--yes)
|
|
43
|
+
- [Optional arguments and options](#optional-arguments-and-options)
|
|
44
|
+
- [`--task-key`](#--task-key)
|
|
45
|
+
- [`--clarification-response`](#--clarification-response)
|
|
46
|
+
- [`--resume-clarification`](#--resume-clarification)
|
|
47
|
+
- [`--project-root`](#--project-root)
|
|
48
|
+
- [`--directive`](#--directive)
|
|
49
|
+
- [`--workers`](#--workers)
|
|
50
|
+
- [`--claude-model`](#--claude-model)
|
|
51
|
+
- [`--lead-model`](#--lead-model)
|
|
52
|
+
- [`--codex-model`](#--codex-model)
|
|
53
|
+
- [`--gemini-model`](#--gemini-model)
|
|
54
|
+
- [`--report-writer-model`](#--report-writer-model)
|
|
55
|
+
- [`--related-tasks`](#--related-tasks)
|
|
56
|
+
- [`--render-only`](#--render-only)
|
|
57
|
+
- [`--refresh-assets`](#--refresh-assets)
|
|
58
|
+
- [Interactive input flow](#interactive-input-flow)
|
|
59
|
+
- [Confirmation flow](#confirmation-flow)
|
|
60
|
+
- [Storage model](#storage-model)
|
|
61
|
+
- [1. Stable task root](#1-stable-task-root)
|
|
62
|
+
- [2. Per-run execution artifacts](#2-per-run-execution-artifacts)
|
|
63
|
+
- [3. Project-level discovery and skill documents](#3-project-level-discovery-and-skill-documents)
|
|
64
|
+
- [Task manifest contract](#task-manifest-contract)
|
|
65
|
+
- [Task index contract](#task-index-contract)
|
|
66
|
+
- [Run manifest contract](#run-manifest-contract)
|
|
67
|
+
- [Timeline contract](#timeline-contract)
|
|
68
|
+
- [Claude operating contract](#claude-operating-contract)
|
|
69
|
+
- [Task brief usage](#task-brief-usage)
|
|
70
|
+
- [Recommended workflow](#recommended-workflow)
|
|
71
|
+
- [1. 초안 작성](#1-초안-작성)
|
|
72
|
+
- [2. 정식 brief 작성](#2-정식-brief-작성)
|
|
73
|
+
- [2.5. 필요 시 요구사항 triage](#25-필요-시-요구사항-triage)
|
|
74
|
+
- [3. Render-only 검증](#3-render-only-검증)
|
|
75
|
+
- [4. Claude 실행](#4-claude-실행)
|
|
76
|
+
- [5. 필요 시 에러 분석](#5-필요-시-에러-분석)
|
|
77
|
+
- [5.5. 답변 후 즉시 재실행](#55-답변-후-즉시-재실행)
|
|
78
|
+
- [6. 필요 시 구현 계획 검토](#6-필요-시-구현-계획-검토)
|
|
79
|
+
- [7. 승인된 plan 기반 구현](#7-승인된-plan-기반-구현)
|
|
80
|
+
- [8. 구현 후 최종 검토](#8-구현-후-최종-검토)
|
|
81
|
+
- [9. 같은 task 재개](#9-같은-task-재개)
|
|
82
|
+
- [Lifecycle status and resume](#lifecycle-status-and-resume)
|
|
83
|
+
- [Preferred final report structure](#preferred-final-report-structure)
|
|
84
|
+
- [Worker error collection (optional sidecar)](#worker-error-collection-optional-sidecar)
|
|
85
|
+
- [Token usage and cost accounting](#token-usage-and-cost-accounting)
|
|
86
|
+
- [Practical notes](#practical-notes)
|
|
87
|
+
- [Related documents](#related-documents)
|
|
88
|
+
|
|
89
|
+
## Purpose
|
|
90
|
+
|
|
91
|
+
이 문서는 `Okstra` 기준의 `okstra` 사용법을 task-key 중심으로 정리한 운영 가이드입니다.
|
|
92
|
+
`README.md`가 빠른 진입점이라면, 이 문서는 `okstra`의 실행 계약과 storage model, lifecycle, Claude handoff 규칙을 설명하는 상세 기준 문서입니다.
|
|
93
|
+
|
|
94
|
+
`okstra`는 단일 파일 리뷰 도구가 아닙니다.
|
|
95
|
+
`okstra`는 Claude Code가 cross verify를 수행할 수 있도록 안정적인 task bundle, run history, project-level discovery metadata를 준비하는 보조 도구입니다.
|
|
96
|
+
|
|
97
|
+
## What okstra does
|
|
98
|
+
|
|
99
|
+
okstra 의 prepare 책임은 단일 python 진입점 [`okstra_ctl.run.prepare_task_bundle`](scripts/okstra_ctl/run.py) 에 모여 있습니다. 이 함수가 다음을 한 트랜잭션으로 수행합니다.
|
|
100
|
+
|
|
101
|
+
- okstra 설치 자산(`~/.claude/skills/okstra/...`, `~/.claude/agents/...`, `~/.okstra/bin/...`) 존재 확인
|
|
102
|
+
- `<PROJECT_ROOT>/.project-docs/okstra/project.json` self-registration (또는 projectId 일치 검증)
|
|
103
|
+
- task type → `prompts/profiles/<task-type>.md` 로드 + 권장 workers 추출
|
|
104
|
+
- 사용자 worker/model 오버라이드 정규화 (Claude/Codex/Gemini/Report-writer 각각 display ↔ execution-value 매핑)
|
|
105
|
+
- task brief / clarification response 경로 해석 (cwd 우선 → PROJECT_ROOT fallback)
|
|
106
|
+
- per-task mutex(`~/.okstra/.locks/<task-key>.lock`) 안에서 stable task root + 모든 path/seq 계산 후 `<run-dir>/manifests/run-context-<seq>.json` 으로 영속화
|
|
107
|
+
- 사용자 입력을 `<run-dir>/manifests/run-inputs-<seq>.json` 으로 영속화
|
|
108
|
+
- instruction-set 9 파일 렌더 (`analysis-profile.md`, `analysis-material.md`, `task-brief.md`, `reference-expectations.md`, `final-report-template.md`, `clarification-response.md`, `directive.txt`, `claude-execution-prompt.md`, lead prompt snapshot)
|
|
109
|
+
- `task-manifest.json` · `task-index.md` · `run-manifest-*.json` · `history/timeline.json` · `discovery/{latest-task,task-catalog}.json` 갱신
|
|
110
|
+
- preassigned Claude session ID + `sessions/claude-resume-*.sh` 작성 (`--render-only` 가 아닐 때)
|
|
111
|
+
- 중앙 인덱스(`~/.okstra/{active,recent}.jsonl`, `projects/<id>/{index.jsonl, meta.json}`) record_start
|
|
112
|
+
|
|
113
|
+
`prepare_task_bundle` 의 두 caller:
|
|
114
|
+
|
|
115
|
+
1. **`scripts/okstra.sh`**: CLI 인자를 파싱·확인하고 → `prepare_task_bundle` 호출 → `--render-only` 가 아니면 `claude --model ... --session-id ... "$PROMPT"` 를 `exec` 으로 띄움. ~160 줄의 thin wrapper.
|
|
116
|
+
2. **`okstra-run` skill**: 같은 claude 세션 안에서 `AskUserQuestion` 으로 인자를 모은 뒤 → `prepare_task_bundle(render_only=True)` 직접 호출 → 렌더된 lead prompt 를 현재 세션이 그대로 읽어 lead 역할 수행. 새 claude 프로세스를 띄우지 않음.
|
|
117
|
+
|
|
118
|
+
판단 정책과 worker orchestration 은 lead claude 가 담당하고, okstra 의 prepare 단계는 그 lead 가 정확한 입력 묶음과 출력 골격을 받아 일을 시작할 수 있게 정형화된 자산을 준비할 뿐입니다.
|
|
119
|
+
|
|
120
|
+
## Runtime assets vs support assets
|
|
121
|
+
|
|
122
|
+
런타임 진입점은 python 패키지에 모여 있고, bash 와 skill 은 거기로 호출만 보냅니다.
|
|
123
|
+
|
|
124
|
+
### Python module 진입점 (single authority)
|
|
125
|
+
|
|
126
|
+
- [`okstra_ctl.run`](scripts/okstra_ctl/run.py) — `prepare_task_bundle()` orchestrator + argparse CLI (`python3 -m okstra_ctl.run --workspace-root ... --project-root ... ...`).
|
|
127
|
+
- [`okstra_ctl.paths`](scripts/okstra_ctl/paths.py) — `compute_run_paths()` pure path/seq 계산.
|
|
128
|
+
- [`okstra_ctl.run_context`](scripts/okstra_ctl/run_context.py) — `compute_and_write_run_context()`, `write_run_inputs()`, per-task mutex.
|
|
129
|
+
- [`okstra_ctl.render`](scripts/okstra_ctl/render.py) — task-manifest / run-manifest / timeline / task-index / team-state / launch.template / reference-expectations / discovery 9개 render 함수 + `python3 -m okstra_ctl.render <subcommand>` dispatcher.
|
|
130
|
+
- [`okstra_ctl.workers`](scripts/okstra_ctl/workers.py) · [`okstra_ctl.models`](scripts/okstra_ctl/models.py) — worker / model 해소.
|
|
131
|
+
- [`okstra_ctl.workflow`](scripts/okstra_ctl/workflow.py) — phase rules (PHASE_ALLOWED_OUTPUTS / PHASE_FORBIDDEN_ACTIONS).
|
|
132
|
+
- [`okstra_ctl.material`](scripts/okstra_ctl/material.py) — `analysis-material.md` 본문 + related-tasks 빌더.
|
|
133
|
+
- [`okstra_ctl.session`](scripts/okstra_ctl/session.py) · [`okstra_ctl.seeding`](scripts/okstra_ctl/seeding.py) — Claude session id / resume command / 설치 검증 / runtime settings.
|
|
134
|
+
- [`okstra_ctl.{ids,index,invocation,jsonl,project_meta,reconcile,resolver,sequence,batch,backfill,listing,locks,tmux}`](scripts/okstra_ctl/) — 중앙 인덱스 (`~/.okstra`) 의 기존 모듈군.
|
|
135
|
+
- [`okstra_project.{resolver,state}`](scripts/okstra_project/) — PROJECT_ROOT 해석 + project.json upsert + task-catalog/manifest reader.
|
|
136
|
+
|
|
137
|
+
### Bash entry points (thin)
|
|
138
|
+
|
|
139
|
+
- [`scripts/okstra.sh`](scripts/okstra.sh) ~160 줄. CLI 파싱 / interactive prompt / confirm-execution-plan / `prepare_task_bundle` 호출 / `exec claude`.
|
|
140
|
+
- [`scripts/lib/okstra/{cli,globals,interactive,project-resolver,usage}.sh`](scripts/lib/okstra/) — CLI/인터랙티브 보조만. 산출물 생성 로직 보유 없음.
|
|
141
|
+
- [`scripts/okstra-ctl.sh`](scripts/okstra-ctl.sh) + [`scripts/lib/okstra-ctl/`](scripts/lib/okstra-ctl/) — 중앙 컨트롤 센터 CLI (list / show / open / rerun / reconcile / 등).
|
|
142
|
+
|
|
143
|
+
### Claude assets (templates + skills)
|
|
144
|
+
|
|
145
|
+
- `prompts/launch.template.md` — lead 프롬프트 템플릿.
|
|
146
|
+
- `prompts/profiles/*.md` — 5종 task-type profile.
|
|
147
|
+
- `templates/project-docs/task-index.template.md` · `templates/reports/final-report.template.md` · `templates/reports/settings.template.json` — 런타임 렌더 입력.
|
|
148
|
+
- `<PROJECT_ROOT>/.project-docs/okstra/project.json` — 프로젝트 self-registration. okstra.sh 첫 실행 시 자동 생성/검증되며, `--project-root` 미지정 시 ancestor / `git toplevel` 로 PROJECT_ROOT 해석.
|
|
149
|
+
|
|
150
|
+
### Support assets (런타임 비참조)
|
|
151
|
+
|
|
152
|
+
- `templates/reports/*-input.template.md` — 사용자 입력 작성 보조.
|
|
153
|
+
- `validators/validate-workflow.sh`, `validators/validate-schedule.py`, `validators/validate-run.py` — 수동/CI 검증용. `validate-run.py` 의 경로는 run metadata 에 기록.
|
|
154
|
+
|
|
155
|
+
### Skills (`skills/`, `agents/`)
|
|
156
|
+
|
|
157
|
+
- [`agents/SKILL.md`](agents/SKILL.md) — main okstra skill (cross-verify 트리거).
|
|
158
|
+
- [`skills/setup-okstra/SKILL.md`](skills/setup-okstra/SKILL.md) — **첫 실행 부트스트랩**. `okstra install` + `project.json` 생성.
|
|
159
|
+
- [`skills/okstra-run/SKILL.md`](skills/okstra-run/SKILL.md) — **현재 claude 세션 안에서 okstra task 를 시작**하는 in-session 진입점. `prepare_task_bundle` 직접 호출.
|
|
160
|
+
- `skills/okstra-{status,history,convergence,schedule,context-loader,team-contract,report-finder,report-writer,time-summary}/SKILL.md` — phase 진행·status·history 보조 skill.
|
|
161
|
+
- 플러그인 매니페스트: [`.claude-plugin/plugin.json`](.claude-plugin/plugin.json) — `npx skills@latest add Devonshin/okstra` 보조 채널이 참조. 0.3.0 부터는 `npx okstra install` 한 명령이 동일 결과를 보장하므로 일반 셋업에는 이 채널이 필요 없다.
|
|
162
|
+
- 설치 위치: `~/.claude/skills/<name>/SKILL.md` (`okstra-install.sh` dev 설치, 또는 위 npx 채널).
|
|
163
|
+
- 릴리스 절차: [`RELEASING.md`](RELEASING.md) — npm publish 흐름과 GitHub Actions 워크플로(`v*.*.*` tag → 자동 publish), 자동화 토큰 셋업, 검증/롤백.
|
|
164
|
+
|
|
165
|
+
## Architecture: python authority + thin callers
|
|
166
|
+
|
|
167
|
+
okstra 의 prepare 단계는 디스크 권위 + 단일 python 진입점 모델을 따릅니다. 이 설계가 두 가지 목표를 동시에 만족합니다.
|
|
168
|
+
|
|
169
|
+
1. **Claude Code 의 병렬 실행과 호환**: 같은 claude 세션이 subagent / 병렬 Bash tool / 백그라운드 작업으로 여러 자식을 띄워도 환경 변수가 공유 변경되지 않으므로 race 가 발생하지 않습니다.
|
|
170
|
+
2. **bash CLI 와 in-session skill 의 동작 동일성**: `okstra.sh` 와 `okstra-run` skill 이 같은 `prepare_task_bundle()` 을 부르기 때문에 산출물·중앙 인덱스 등록·검증 경로가 같습니다.
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
┌────────────────────────────────────────────────────────────────┐
|
|
174
|
+
│ Two callers, one authority │
|
|
175
|
+
├────────────────────────────────────────────────────────────────┤
|
|
176
|
+
│ │
|
|
177
|
+
│ scripts/okstra.sh skills/okstra-run/SKILL.md │
|
|
178
|
+
│ (CLI: bash 인자 파싱) (current claude 세션 안 AskUserQuestion) │
|
|
179
|
+
│ │ │ │
|
|
180
|
+
│ └─────────────┬────────────────┘ │
|
|
181
|
+
│ ▼ │
|
|
182
|
+
│ okstra_ctl.run.prepare_task_bundle() │
|
|
183
|
+
│ (single python function — 산출물 전부 책임) │
|
|
184
|
+
│ │ │
|
|
185
|
+
│ ┌────────────┴────────────────┐ │
|
|
186
|
+
│ ▼ ▼ │
|
|
187
|
+
│ on-disk authority ~/.okstra (central index) │
|
|
188
|
+
│ <PROJECT_ROOT>/.project-docs/ per-task mutex + record_start │
|
|
189
|
+
└────────────────────────────────────────────────────────────────┘
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### State authority on disk
|
|
193
|
+
|
|
194
|
+
per-process 환경 변수에 task 정체성·경로·workflow 상태를 보관하지 않습니다. 모든 reader 는 다음 파일에서 매번 계산합니다.
|
|
195
|
+
|
|
196
|
+
| 데이터 | 권위 파일 |
|
|
197
|
+
|---|---|
|
|
198
|
+
| projectId, projectRoot | `<PROJECT_ROOT>/.project-docs/okstra/project.json` |
|
|
199
|
+
| task identity / workflow | `<task-root>/task-manifest.json` |
|
|
200
|
+
| task 후보 목록 | `<PROJECT_ROOT>/.project-docs/okstra/discovery/task-catalog.json` |
|
|
201
|
+
| 최신 task 포인터 | `<PROJECT_ROOT>/.project-docs/okstra/discovery/latest-task.json` |
|
|
202
|
+
| run 입력값 | `<run-dir>/manifests/run-inputs-<task-type>-<seq>.json` |
|
|
203
|
+
| run paths / seq | `<run-dir>/manifests/run-context-<task-type>-<seq>.json` |
|
|
204
|
+
| run 이력 | `<task-root>/history/timeline.json` |
|
|
205
|
+
| 글로벌 인덱스 | `~/.okstra/{active,recent}.jsonl`, `~/.okstra/projects/<id>/{index.jsonl, meta.json}` |
|
|
206
|
+
|
|
207
|
+
### Concurrency
|
|
208
|
+
|
|
209
|
+
두 종류의 파일 락이 모든 동시성을 처리합니다.
|
|
210
|
+
|
|
211
|
+
- `~/.okstra/.locks/<task-key>.lock` — per-task mutex. `compute_and_write_run_context` 가 seq 계산과 `run-context.json` 영속화를 한 트랜잭션으로 묶음. 같은 task 의 두 호출은 직렬화.
|
|
212
|
+
- `~/.okstra/.lock` — 중앙 인덱스 mutex. `record_start` / `reconcile` / `rotate_recent_if_needed` 에서 사용.
|
|
213
|
+
|
|
214
|
+
다른 (project, task-group, task-id) 사이에는 직렬화가 없습니다 — 디스크 경로가 분리되므로 충돌 자체가 없음. 환경 변수 race 가 사라졌으므로 같은 claude 세션이 여러 task 를 병렬 진행해도 안전.
|
|
215
|
+
|
|
216
|
+
### Allowed env vars (사용자 knob 한정)
|
|
217
|
+
|
|
218
|
+
상태 전달 용도가 아닌, 사용자 설정용으로만 다음 env var 를 읽습니다.
|
|
219
|
+
|
|
220
|
+
- `OKSTRA_HOME` — 중앙 디렉터리 위치 override (기본 `~/.okstra`).
|
|
221
|
+
- `OKSTRA_DEFAULT_LEAD_MODEL`, `OKSTRA_DEFAULT_CLAUDE_MODEL`, `OKSTRA_DEFAULT_CODEX_MODEL`, `OKSTRA_DEFAULT_GEMINI_MODEL`, `OKSTRA_DEFAULT_REPORT_WRITER_MODEL` — 모델 default.
|
|
222
|
+
- `OKSTRA_TOOL_NAME`, `OKSTRA_COMMAND_NAME` — usage 출력의 표시 이름.
|
|
223
|
+
- `OKSTRA_RUN_SEQ_OVERRIDE` — okstra-ctl rerun / 테스트 hook 이 강제하는 run-seq (per-process).
|
|
224
|
+
|
|
225
|
+
이 외의 `PROJECT_ID`, `TASK_GROUP`, `RUN_*`, `FINAL_*`, `CLAUDE_*` 등은 export 하지 않으며, 자식 프로세스로 leak 되지 않습니다.
|
|
226
|
+
|
|
227
|
+
## Claude execution behavior
|
|
228
|
+
|
|
229
|
+
현재 구현 기준으로 `okstra`의 Claude 실행 방식은 아래와 같습니다.
|
|
230
|
+
|
|
231
|
+
**Mode A — `okstra.sh` 가 새 claude 프로세스를 띄움**
|
|
232
|
+
- `--render-only`를 사용하면 Claude를 실행하지 않고 instruction-set 만 만든 뒤 종료합니다.
|
|
233
|
+
- `--render-only`가 없으면 prepare 단계가 Claude session ID 를 선할당하고 current run 의 `sessions/` 아래에 `claude-resume-<task-type>-<seq>.sh` 를 생성합니다.
|
|
234
|
+
- 이후 대상 프로젝트 루트에서 resolved `Claude lead` model execution value 로 `claude --model <lead> --session-id "$CLAUDE_SESSION_ID" --settings <runtime-settings> "$PROMPT"` 를 `exec` 합니다.
|
|
235
|
+
- `okstra.sh` 는 handoff 까지만 수행하고, 최종 보고서 저장과 run/task 상태 갱신은 Claude lead 가 이어서 수행합니다.
|
|
236
|
+
|
|
237
|
+
**Mode B — `okstra-run` skill 이 현재 claude 세션 안에서 인계**
|
|
238
|
+
- 사용자가 이미 claude 세션에 있고 거기서 새 okstra task 를 시작하고 싶을 때 사용합니다.
|
|
239
|
+
- skill 이 `AskUserQuestion` 으로 task 후보·task-type·brief 등을 받고 `prepare_task_bundle(render_only=True)` 를 호출해 동일한 instruction-set 을 디스크에 만듭니다.
|
|
240
|
+
- 새 claude 프로세스는 띄우지 않고, 현재 세션이 렌더된 lead prompt 를 읽어 lead 역할로 즉시 진입합니다.
|
|
241
|
+
|
|
242
|
+
두 모드 모두 동일한 산출물(task-manifest, run-manifest, timeline, instruction-set, central index 등록) 을 만들며, `okstra-ctl` 의 후속 명령(list / show / rerun / reconcile)은 산출물 차이를 알지 못한 채 일관되게 동작합니다.
|
|
243
|
+
- handoff된 메인 Claude는 `Claude lead`로 동작하며 orchestration과 final synthesis를 담당합니다.
|
|
244
|
+
- standard workflow의 required worker role은 `Claude worker`, `Codex worker`, `Gemini worker`, `Report writer worker`입니다.
|
|
245
|
+
- worker 역할 분담과 최종 판단은 Claude가 task bundle을 읽고 수행합니다.
|
|
246
|
+
- 사용자 홈에 설치된 okstra Claude assets(`~/.claude/skills`, `~/.claude/agents`) 는 Agent Teams 를 우선 시도하고, 팀 구성이 불가능할 때만 sequential/background fallback 을 사용하도록 Claude 를 유도합니다.
|
|
247
|
+
|
|
248
|
+
## Claude prompt contract
|
|
249
|
+
|
|
250
|
+
Claude launch prompt 본문은 항상 `prompts/launch.template.md` 템플릿에서만 렌더링됩니다.
|
|
251
|
+
|
|
252
|
+
- 프롬프트 치환은 task key, session ID, 절대/상대 경로 같은 scalar placeholder 값으로만 제한합니다.
|
|
253
|
+
- 선택된 profile 본문은 `instruction-set/analysis-profile.md`로 렌더링합니다.
|
|
254
|
+
- 분석 자료 본문은 `instruction-set/analysis-material.md`로 렌더링합니다.
|
|
255
|
+
- config/deployment expected-state 본문은 `instruction-set/reference-expectations.md`로 렌더링합니다.
|
|
256
|
+
- Claude는 위 artifact 파일들을 직접 읽어야 하며, 긴 task-specific 본문이 launch prompt 안에 inline으로 복제되면 안 됩니다.
|
|
257
|
+
|
|
258
|
+
## Required team contract
|
|
259
|
+
|
|
260
|
+
표준 `okstra` workflow는 아래 팀 계약을 runtime prompt, profile, manifest, skill 문서에 공통으로 반영합니다.
|
|
261
|
+
|
|
262
|
+
- 메인 Claude는 항상 `Claude lead`이며 synthesis-only로 동작합니다.
|
|
263
|
+
- required worker role은 `Claude worker`, `Codex worker`, `Gemini worker`, `Report writer worker`입니다.
|
|
264
|
+
- `Report writer worker`는 보고서 구조화와 근거 정리에 집중하지만 최종 synthesis owner는 여전히 `Claude lead`입니다.
|
|
265
|
+
- 기본 모델 계약은 중앙 기본값에서 계산합니다. 기본 fallback은 `Claude lead`=`opus`, `Claude worker`=`sonnet`, `Codex worker`=`gpt-5.5`, `Gemini worker`=`auto`이며, `Report writer worker`는 별도 override가 없으면 `Claude lead` 모델을 따릅니다(즉, 기본값에서는 `opus`).
|
|
266
|
+
- `Gemini worker`는 반드시 시도해야 합니다.
|
|
267
|
+
- 최종 판단 전에는 각 required worker role별로 결과 또는 명시적인 terminal status(`completed`, `timeout`, `error`, `not-run`)가 필요합니다.
|
|
268
|
+
- 시도된 worker(`completed`, `timeout`, `error`)는 현재 run의 `prompts/` 아래 assigned worker prompt history file을 반드시 가져야 합니다.
|
|
269
|
+
- 이름 없는 generic parallel worker는 required role 대체 수단으로 허용하지 않습니다.
|
|
270
|
+
|
|
271
|
+
## Stable task identity
|
|
272
|
+
|
|
273
|
+
`okstra`의 기본 식별자는 아래 조합입니다.
|
|
274
|
+
|
|
275
|
+
- `project-id`
|
|
276
|
+
- `task-group`
|
|
277
|
+
- `task-id`
|
|
278
|
+
|
|
279
|
+
논리적 task key는 아래 형식입니다.
|
|
280
|
+
|
|
281
|
+
```text
|
|
282
|
+
<project-id>:<task-group>:<task-id>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
같은 버그를 다시 열거나 같은 작업을 이어서 진행할 때는 같은 `task-group`과 `task-id`를 재사용합니다.
|
|
286
|
+
새로운 unrelated 작업이면 새 `task-group` 또는 새 `task-id`를 사용합니다.
|
|
287
|
+
|
|
288
|
+
## Project self-registration
|
|
289
|
+
|
|
290
|
+
`okstra.sh` 는 외부 등록 디렉토리(과거 `examples/projects/*.conf.sh` 모델은 폐기됨) 없이 동작합니다. 매 실행 시작 시 PROJECT_ROOT 를 다음 우선순위로 해석한 뒤 그 위치의 `.project-docs/okstra/project.json` 을 권위 소스로 자기 등록합니다.
|
|
291
|
+
|
|
292
|
+
해석 우선순위:
|
|
293
|
+
|
|
294
|
+
1. CLI 인자 `--project-root <path>`.
|
|
295
|
+
2. cwd 또는 그 조상 디렉토리 중 `.project-docs/okstra/project.json` 보유 위치.
|
|
296
|
+
3. cwd 의 `git rev-parse --show-toplevel`.
|
|
297
|
+
|
|
298
|
+
셋 다 실패하면 `okstra.sh` 는 즉시 에러로 종료합니다 (자동 추정 없음).
|
|
299
|
+
|
|
300
|
+
`<PROJECT_ROOT>/.project-docs/okstra/project.json` 스키마:
|
|
301
|
+
|
|
302
|
+
```json
|
|
303
|
+
{
|
|
304
|
+
"projectId": "fontradar-v2-api",
|
|
305
|
+
"projectRoot": "/Volumes/Workspaces/workspace/projects/fontradar",
|
|
306
|
+
"createdAt": "2026-05-10T00:00:00Z",
|
|
307
|
+
"updatedAt": "2026-05-10T00:00:00Z"
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
처음 실행이면 위 4-필드를 새로 작성합니다. 이미 존재하면 `--project-id` 인자값과 저장된 `projectId` 가 일치하는지 검증한 뒤 `projectRoot`/`updatedAt` 만 갱신합니다. 불일치 시 즉시 종료해 동일 디렉토리에서 두 개의 ID 가 혼용되는 것을 막습니다.
|
|
312
|
+
|
|
313
|
+
`okstra-ctl` 의 reindex/backfill 도 신규 모델에서 권위 소스를 변경했습니다. 과거에는 `examples/projects/*.conf.sh` 를 source 했지만, 지금은 `~/.okstra/projects/<projectId>/meta.json` (record_start 가 위 project.json 정보를 mirror 한 결과) 을 스캔하여 (projectId, projectRoot) 매핑을 복원합니다. `OKSTRA_PROJECT_DEFINITION_DIR_OVERRIDE` 환경변수도 함께 폐기되었습니다.
|
|
314
|
+
|
|
315
|
+
## Task type
|
|
316
|
+
|
|
317
|
+
`task-type`은 이번 run의 목적과 profile 선택, 그리고 lifecycle phase 라우팅을 동시에 결정합니다.
|
|
318
|
+
|
|
319
|
+
선택 규칙:
|
|
320
|
+
|
|
321
|
+
- `--task-type <name>`을 주면 `prompts/profiles/<name>.md`가 task bundle의 `instruction-set/analysis-profile.md`로 렌더링됩니다.
|
|
322
|
+
- 외부 인터페이스 기준 단일 선택자는 `task-type`입니다.
|
|
323
|
+
- 선택된 task type은 task-manifest.json의 `taskType`, `workflow.currentPhase`, `workflow.nextRecommendedPhase`에 그대로 반영됩니다.
|
|
324
|
+
- run directory 경로 세그먼트로도 사용됩니다(`runs/<task-type>/...`).
|
|
325
|
+
|
|
326
|
+
### 표준 task type
|
|
327
|
+
|
|
328
|
+
각 task type은 phase별 허용/금지 행동을 강제하며, 한 run은 자기 task type의 산출물만 만들고 다음 phase로 이행하지 않습니다. 다음 phase는 항상 새로운 `okstra.sh` 실행에서 시작합니다.
|
|
329
|
+
|
|
330
|
+
| task type | 목적 | 핵심 산출물 | 다음 권장 phase | 코드 변경 허용 여부 |
|
|
331
|
+
|---|---|---|---|---|
|
|
332
|
+
| `requirements-discovery` | 요청을 bugfix/feature/refactor/ops/improvement 중 하나로 분류하고 안전한 다음 phase로 라우팅 | work category, routing decision, missing-input list, clarification requests | `pending-routing-decision` (사용자 답변 후 결정) | 금지 |
|
|
333
|
+
| `error-analysis` | 보고된 에러/사고의 증상·원인·재현 갭을 증거 기반으로 분석 | symptom/trigger 정리, root-cause 가설, reproduction gap, validation 경로 | `implementation-planning` | 금지 |
|
|
334
|
+
| `implementation-planning` | 코딩 시작 전 안전한 구현 방향과 옵션을 평가 | 최소 2개 구현 옵션, 영향 파일 목록, trade-off, 단계별 실행 순서, validation/rollback, **User Approval Request** 블록 | `implementation` (사용자 승인 후) | 금지 |
|
|
335
|
+
| `implementation` | 승인된 `implementation-planning` final report의 단계대로 소스 코드를 수정 | commit list, diff summary, out-of-plan edits 블록, validation/TDD evidence, rollback 검증, verifier 결과(Gemini/Codex/Claude) | `final-verification` | 허용 (승인된 plan의 파일 목록 한정, `git push`/publish/deploy/실제 migration 금지) |
|
|
336
|
+
| `final-verification` | 완료된 작업의 잔존 결함·회귀 위험을 점검하고 release 판단 | acceptance verdict, residual risk, follow-up 라우팅(`error-analysis`/`implementation-planning`) | `done-or-follow-up` | 금지 (read-only 테스트만 허용) |
|
|
337
|
+
|
|
338
|
+
공통 제약:
|
|
339
|
+
|
|
340
|
+
- `implementation`을 제외한 모든 phase는 source code edit, build, migration, deployment, 그 밖의 state-mutating 명령을 금지합니다(`final-verification`은 read-only 테스트 명령만 허용). `implementation`은 승인된 plan의 파일 목록 안에서만 edit/commit이 허용되며, `git push`·publish·deploy·실제 migration·third-party write API는 여전히 금지됩니다.
|
|
341
|
+
- 사용자가 "다음 단계 진행해" 같은 표현을 보내도, 그 발화만으로 다음 phase가 자동 시작되지 않습니다. 다음 phase는 새 `okstra.sh` 실행으로만 시작합니다.
|
|
342
|
+
- **Authority & permissions assumption (HARD RULE — 모든 task-type 및 `okstra-schedule` 공통)**: 사용자(및 팀)는 예상되는 모든 작업에 대해 완전한 권한·승인 권한을 보유한다고 가정합니다. 외부 승인, 서드파티 액세스, 역할/IAM 권한, 조직적 sign-off, 법무·보안 검토, 벤더 협의, "권한 보유 여부 확인" 같은 항목을 routing 결정·missing inputs·clarification questions·risk·dependency·open questions·effort/day 추정에 포함하지 않습니다. okstra 내부 phase 핸드오프(`User Approval Request` 등)는 사용자 본인이 즉시 승인 가능한 내부 게이트이므로 영향 없으며, `implementation`의 forbidden actions(`git push`, prod deploy, shared-DB migration 등)도 권한 사유가 아닌 **안전 사유**로 계속 적용됩니다.
|
|
343
|
+
- Phase별 상세 규칙은 `prompts/profiles/<task-type>.md`에 정의되어 있고, 그 본문이 그대로 `instruction-set/analysis-profile.md`로 렌더링됩니다.
|
|
344
|
+
|
|
345
|
+
### Phase 간 정보 전달
|
|
346
|
+
|
|
347
|
+
- `requirements-discovery` 또는 `error-analysis`가 남긴 final report의 `## 5. Clarification Requests for the Next Run` 섹션에 사용자가 답변을 채운 뒤, 다음 run에서 `--clarification-response <previous-final-report.md>`로 그 파일을 carry-in합니다.
|
|
348
|
+
- carry-in된 파일은 현재 run의 `instruction-set/clarification-response.md`로 복사되고, lead가 Section 0에서 prior `Q*` 행의 `Status`(`resolved` / `obsolete`)를 갱신한 뒤 진행합니다.
|
|
349
|
+
- 답변 편집과 재실행을 한 번에 처리하려면 `--resume-clarification` 모드를 사용합니다. 자세한 동작은 `### --resume-clarification` 섹션을 참고합니다.
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
## Command forms
|
|
353
|
+
|
|
354
|
+
기본 명령(첫 진입 / full args):
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
scripts/okstra.sh [--render-only] [--yes] [--refresh-assets] --task-type <task-type> [--workers worker1,worker2] [--lead-model <model>] [--claude-model <model>] [--codex-model <model>] [--gemini-model <model>] [--report-writer-model <model>] [--related-tasks taskA,taskB] [--clarification-response <previous-final-report>] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>]
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
후속 phase 단축 형식(기존 task-manifest.json이 존재할 때):
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
scripts/okstra.sh --task-key <project-id>:<task-group>:<task-id> [--task-type <task-type>]
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Clarification 답변 즉시 재실행:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
scripts/okstra.sh --resume-clarification --task-key <project-id>:<task-group>:<task-id>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
interactive terminal에서 실행하면 다음 규칙이 추가로 적용됩니다.
|
|
373
|
+
|
|
374
|
+
- 필수 인자가 비어 있으면 stdin으로 직접 입력을 받습니다.
|
|
375
|
+
- 입력이 모두 준비되면 실행 전 요약을 보여줍니다.
|
|
376
|
+
- `y` 또는 `yes`를 입력했을 때만 실제 생성 또는 실행 단계로 진행합니다.
|
|
377
|
+
- interactive가 아닌 실행에서는 누락 인자를 prompt하지 않고 에러로 종료합니다.
|
|
378
|
+
- `--yes`를 사용하면 prompt와 confirmation을 모두 건너뛰지만, 이때는 모든 필수 인자가 반드시 이미 채워져 있어야 합니다.
|
|
379
|
+
- 우선순위는 `명시적 CLI 인자 > interactive prompt 또는 non-interactive 에러`입니다.
|
|
380
|
+
|
|
381
|
+
## Required arguments
|
|
382
|
+
|
|
383
|
+
### `--project-id`
|
|
384
|
+
|
|
385
|
+
전역에서 고유해야 하는 프로젝트 ID입니다. 첫 실행 시 `<PROJECT_ROOT>/.project-docs/okstra/project.json` 에 자기 등록(self-registration)되며, 동일 PROJECT_ROOT 에서 재실행할 때 인자값과 저장된 `projectId` 가 다르면 즉시 에러로 종료합니다.
|
|
386
|
+
|
|
387
|
+
예:
|
|
388
|
+
|
|
389
|
+
- `fontradar-v2-api`
|
|
390
|
+
- `jobs`
|
|
391
|
+
|
|
392
|
+
### `--task-group`
|
|
393
|
+
|
|
394
|
+
관련 task를 묶는 논리 그룹입니다.
|
|
395
|
+
|
|
396
|
+
예:
|
|
397
|
+
|
|
398
|
+
- `feature-8858`
|
|
399
|
+
- `bugfix-auth`
|
|
400
|
+
- `tasks`
|
|
401
|
+
|
|
402
|
+
### `--task-id`
|
|
403
|
+
|
|
404
|
+
같은 그룹 안에서 안정적으로 재사용할 task 식별자입니다.
|
|
405
|
+
|
|
406
|
+
예:
|
|
407
|
+
|
|
408
|
+
- `email-recipient-loss`
|
|
409
|
+
- `8852`
|
|
410
|
+
|
|
411
|
+
### `--task-type`
|
|
412
|
+
|
|
413
|
+
이번 run의 목적과 profile 선택, run directory 세그먼트, lifecycle phase 라우팅을 결정하는 단일 입력값입니다.
|
|
414
|
+
표준 값과 phase별 책임은 위 [Task type](#task-type) 섹션을 참고합니다.
|
|
415
|
+
|
|
416
|
+
### `--task-brief`
|
|
417
|
+
|
|
418
|
+
분석의 기준이 되는 task brief 문서 경로입니다.
|
|
419
|
+
상대 경로는 대상 프로젝트 루트를 기준으로 해석됩니다.
|
|
420
|
+
|
|
421
|
+
예:
|
|
422
|
+
|
|
423
|
+
- `.project-docs/linear/feature/8858/okstra-task-brief.md`
|
|
424
|
+
- `.project-docs/tasks/8852/BUG_REPORT.md`
|
|
425
|
+
|
|
426
|
+
### `--yes`
|
|
427
|
+
|
|
428
|
+
interactive prompt와 confirmation을 생략합니다.
|
|
429
|
+
|
|
430
|
+
대신 아래 조건이 강제됩니다.
|
|
431
|
+
|
|
432
|
+
- `project-id`
|
|
433
|
+
- `task-group`
|
|
434
|
+
- `task-id`
|
|
435
|
+
- `task-type`
|
|
436
|
+
- `brief-path`
|
|
437
|
+
|
|
438
|
+
즉, 필수 인자가 하나라도 비어 있으면 prompt하지 않고 즉시 종료합니다.
|
|
439
|
+
|
|
440
|
+
예:
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
scripts/okstra.sh --yes --render-only --task-type error-analysis --project-id jobs --task-group tasks --task-id 8852 --task-brief .project-docs/tasks/8852/BUG_REPORT.md
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## Optional arguments and options
|
|
447
|
+
|
|
448
|
+
### `--task-key`
|
|
449
|
+
|
|
450
|
+
기존 task에 대한 후속 phase를 시작할 때 `--project-id`/`--task-group`/`--task-id`를 한 번에 전달하는 단축 형식입니다.
|
|
451
|
+
|
|
452
|
+
- 입력 형식: `<project-id>:<task-group>:<task-id>`
|
|
453
|
+
- 동작:
|
|
454
|
+
- 세 ID로 split하여 `PROJECT_ID`/`TASK_GROUP`/`TASK_ID`에 채웁니다.
|
|
455
|
+
- 명시적으로 같은 값들이 함께 들어오면 일치할 때만 허용하고, 충돌하면 즉시 에러로 종료합니다.
|
|
456
|
+
- 해당 task의 `task-manifest.json`이 존재하면 누락된 `--task-brief`를 manifest의 `taskBriefPath` 로, 누락된 `--task-type`을 `workflow.nextRecommendedPhase` 로 자동 채웁니다.
|
|
457
|
+
- manifest가 없으면(첫 진입) 기존 누락-인자 검증이 그대로 동작합니다(=full args 강제).
|
|
458
|
+
- 명시적으로 전달된 인자가 항상 manifest 값보다 우선합니다.
|
|
459
|
+
- `nextRecommendedPhase`가 `pending-routing-decision` 또는 `done-or-follow-up`이면 자동 채움하지 않고, 사용자가 명시적으로 `--task-type`을 주거나 brief을 보강한 뒤 다시 실행해야 합니다.
|
|
460
|
+
|
|
461
|
+
예:
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
scripts/okstra.sh --task-key jobs:tasks:8852
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
scripts/okstra.sh --task-key jobs:tasks:8852 --task-type final-verification
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### `--clarification-response`
|
|
472
|
+
|
|
473
|
+
이전 run의 final report(`Section 5. Clarification Requests for the Next Run`에 사용자가 답변을 inline으로 채운 파일)를 다음 run으로 carry-in합니다.
|
|
474
|
+
|
|
475
|
+
- 입력: `<previous-run>/reports/final-report-<task-type>-<seq>.md` 경로
|
|
476
|
+
- 동작: 파일을 현재 run의 `instruction-set/clarification-response.md`로 복사하고, lead가 Section 0에서 prior `Q*` 행의 `Status`(`resolved` / `obsolete`)를 갱신한 뒤 진행합니다.
|
|
477
|
+
- 사용 시점: `requirements-discovery`, `error-analysis`처럼 미해결 질문을 남기는 phase 이후, 사용자가 답변을 채워 다음 phase로 넘길 때.
|
|
478
|
+
|
|
479
|
+
예:
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
scripts/okstra.sh \
|
|
483
|
+
--task-type implementation-planning \
|
|
484
|
+
--project-id jobs --task-group tasks --task-id 8852 \
|
|
485
|
+
--task-brief .project-docs/tasks/8852/BUG_REPORT.md \
|
|
486
|
+
--clarification-response .project-docs/okstra/tasks/tasks/8852/runs/2026-04-29/error-analysis/reports/final-report-2026-04-29_10-15-30.md
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### `--resume-clarification`
|
|
490
|
+
|
|
491
|
+
직전 `requirements-discovery` 또는 `error-analysis` run의 final report를 즉시 편집하고, 같은 phase를 자동으로 재실행합니다. `--clarification-response` 경로를 사용자가 직접 들고 다닐 필요가 없습니다.
|
|
492
|
+
|
|
493
|
+
- 입력: task identity (`--project-id` + `--task-group` + `--task-id`, 또는 `--task-key <p>:<g>:<i>`)
|
|
494
|
+
- 동작 순서:
|
|
495
|
+
1. task의 `runs/{requirements-discovery,error-analysis}/reports/final-report-*.md` 중 가장 최신 timestamp 파일을 자동 선택합니다.
|
|
496
|
+
2. `$EDITOR`(미설정 시 `vi`)로 해당 파일을 엽니다. 사용자는 Section 5의 `Q*` 행에 답변을 inline으로 채운 뒤 저장하고 종료합니다.
|
|
497
|
+
3. okstra가 같은 task-type으로 자기 자신을 `exec` 재호출하면서 편집된 파일을 `--clarification-response`로 carry-in 합니다.
|
|
498
|
+
4. 이후 confirmation, render, Claude handoff 흐름은 일반 실행과 동일합니다.
|
|
499
|
+
- 명시적 `--task-type`을 함께 주면 그 task type의 reports/ 만 검색합니다. 생략 시 `error-analysis` → `requirements-discovery` 순으로 검색하고 timestamp가 더 큰 보고서를 사용합니다.
|
|
500
|
+
- 다음 옵션과 함께 쓸 수 없습니다: `--render-only`, `--clarification-response`, `--approved-plan`.
|
|
501
|
+
- `EDITOR`를 비대화형 도구(예: `true`)로 설정하면 답변 편집을 건너뛴 채 곧바로 재실행됩니다. 디버깅용으로만 권장합니다.
|
|
502
|
+
|
|
503
|
+
예:
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
scripts/okstra.sh --resume-clarification --task-key jobs:tasks:8852
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
EDITOR=code\ -w scripts/okstra.sh --resume-clarification --project-id jobs --task-group tasks --task-id 8852
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
내부적으로는 다음과 동등합니다.
|
|
514
|
+
|
|
515
|
+
```bash
|
|
516
|
+
$EDITOR <project-root>/.project-docs/okstra/tasks/<group>/<id>/runs/<task-type>/reports/final-report-<latest>.md
|
|
517
|
+
scripts/okstra.sh --task-type <same-type> \
|
|
518
|
+
--project-id <p> --task-group <g> --task-id <i> \
|
|
519
|
+
--task-brief <from manifest> \
|
|
520
|
+
--clarification-response <edited final-report-<latest>.md>
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### `--project-root`
|
|
524
|
+
|
|
525
|
+
대상 프로젝트의 절대 경로입니다. 명시하지 않으면 `okstra.sh` 가 다음 우선순위로 자동 해석합니다.
|
|
526
|
+
|
|
527
|
+
1. cwd 또는 그 조상 디렉토리 중 `.project-docs/okstra/project.json` 보유 위치를 찾아 PROJECT_ROOT 로 채택합니다.
|
|
528
|
+
2. 위가 실패하면 `git rev-parse --show-toplevel` 결과를 사용합니다.
|
|
529
|
+
3. 모두 실패하면 즉시 에러로 종료합니다.
|
|
530
|
+
|
|
531
|
+
해석된 PROJECT_ROOT 에서 첫 실행이라면 `<PROJECT_ROOT>/.project-docs/okstra/project.json` 이 다음 스키마로 자동 생성됩니다.
|
|
532
|
+
|
|
533
|
+
```json
|
|
534
|
+
{
|
|
535
|
+
"projectId": "<--project-id 인자 값>",
|
|
536
|
+
"projectRoot": "<resolved absolute path>",
|
|
537
|
+
"createdAt": "<ISO8601 UTC>",
|
|
538
|
+
"updatedAt": "<ISO8601 UTC>"
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
이미 존재하면 `projectId` 일치 검사 후 `projectRoot`/`updatedAt` 만 갱신합니다. `projectId` 가 다르면 즉시 에러로 종료해 동일 디렉토리에서 두 개의 ID 가 혼용되는 것을 막습니다.
|
|
543
|
+
|
|
544
|
+
예:
|
|
545
|
+
|
|
546
|
+
```bash
|
|
547
|
+
scripts/okstra.sh --task-type error-analysis --project-id jobs --project-root /Volumes/Workspaces/workspace/projects/jobs ...
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### `--directive`
|
|
551
|
+
|
|
552
|
+
사용자 의도를 자유 텍스트로 lead·worker·downstream skill에 전달하는 채널입니다. 값은 `instruction-set/analysis-material.md` 끝에 `## Directive` 섹션으로 임베딩되고, 동시에 `instruction-set/directive.txt`로 백업됩니다.
|
|
553
|
+
|
|
554
|
+
용도:
|
|
555
|
+
|
|
556
|
+
- 기본 heuristic을 뒤집고 싶을 때 — 예: "단일 XL task여도 Gantt 그려줘 (Phase 2개, 총 ~10d)", "Gantt 생략 사유를 명시해줘" (참고: `## Cumulative Timeline`은 schedule contract에서 제거되었으므로 더 이상 toggle 대상이 아닙니다)
|
|
557
|
+
- 분석/계획의 강조점 지시 — 예: "rollout 리스크 우선 분석", "test 커버리지 부재를 별도 finding으로"
|
|
558
|
+
- Phase/Step 분할이나 day 추정을 미리 제시 — 예: "Part 1: 4d, measure: 0.5d, Part 2: 4d, ops: 1d"
|
|
559
|
+
|
|
560
|
+
해석 규칙:
|
|
561
|
+
|
|
562
|
+
- lead·worker는 `analysis-material.md`를 이미 end-to-end로 읽으므로 별도 작업 없이 자동 전파됩니다.
|
|
563
|
+
- skill 측은 자체 contract보다 user prompt를 **우선** 적용해야 하며 (예: `okstra-schedule` 스킬의 "Directive override (highest priority)" 절), heuristic을 뒤집은 경우 결과 문서에 그 사실을 한 줄로 표시합니다.
|
|
564
|
+
|
|
565
|
+
예:
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
scripts/okstra.sh --task-type implementation-planning ... \
|
|
569
|
+
--directive "Phase 2개(Part 1 ~4d, Part 2 ~5d, 순차)로 총 ~10d. Gantt 꼭 그려줘 (임계 경로 표시)."
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### `--workers`
|
|
573
|
+
|
|
574
|
+
이번 run에서 사용할 worker 목록을 직접 지정합니다.
|
|
575
|
+
생략하면 기본값 `claude,codex,gemini,report-writer`를 사용합니다.
|
|
576
|
+
지정하면 전달한 worker subset만 dedupe 후 기록됩니다.
|
|
577
|
+
|
|
578
|
+
예:
|
|
579
|
+
|
|
580
|
+
```bash
|
|
581
|
+
scripts/okstra.sh --task-type implementation-planning --workers claude,codex --project-id jobs --task-group tasks --task-id 8852 --task-brief .project-docs/tasks/8852/BUG_REPORT.md
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### `--claude-model`
|
|
585
|
+
|
|
586
|
+
`Claude worker`에 사용할 모델을 지정합니다.
|
|
587
|
+
지정하지 않으면 중앙 기본값 `OKSTRA_DEFAULT_CLAUDE_MODEL` 또는 fallback `sonnet`을 사용합니다.
|
|
588
|
+
|
|
589
|
+
### `--lead-model`
|
|
590
|
+
|
|
591
|
+
`Claude lead`에 사용할 모델을 지정합니다.
|
|
592
|
+
지정하지 않으면 중앙 기본값 `OKSTRA_DEFAULT_LEAD_MODEL` 또는 fallback `opus`를 사용합니다.
|
|
593
|
+
|
|
594
|
+
### `--codex-model`
|
|
595
|
+
|
|
596
|
+
`Codex worker`에 사용할 모델을 지정합니다.
|
|
597
|
+
지정하지 않으면 중앙 기본값 `OKSTRA_DEFAULT_CODEX_MODEL` 또는 fallback `gpt-5.5`를 사용합니다.
|
|
598
|
+
|
|
599
|
+
### `--gemini-model`
|
|
600
|
+
|
|
601
|
+
`Gemini worker`에 사용할 모델을 지정합니다.
|
|
602
|
+
지정하지 않으면 중앙 기본값 `OKSTRA_DEFAULT_GEMINI_MODEL` 또는 fallback `auto`를 사용합니다.
|
|
603
|
+
|
|
604
|
+
### `--report-writer-model`
|
|
605
|
+
|
|
606
|
+
`Report writer worker`에 사용할 모델을 지정합니다.
|
|
607
|
+
지정하지 않으면 중앙 기본값 `OKSTRA_DEFAULT_REPORT_WRITER_MODEL` 또는 lead 기본값을 사용합니다.
|
|
608
|
+
|
|
609
|
+
중앙 기본값 환경 변수는 아래와 같습니다.
|
|
610
|
+
|
|
611
|
+
- `OKSTRA_DEFAULT_LEAD_MODEL`
|
|
612
|
+
- `OKSTRA_DEFAULT_CLAUDE_MODEL`
|
|
613
|
+
- `OKSTRA_DEFAULT_CODEX_MODEL`
|
|
614
|
+
- `OKSTRA_DEFAULT_GEMINI_MODEL`
|
|
615
|
+
- `OKSTRA_DEFAULT_REPORT_WRITER_MODEL`
|
|
616
|
+
|
|
617
|
+
fallback 기본값은 아래와 같습니다.
|
|
618
|
+
|
|
619
|
+
- `Claude lead`: `opus`
|
|
620
|
+
- `Report writer worker`: `opus`
|
|
621
|
+
- `Claude worker`: `sonnet`
|
|
622
|
+
- `Codex worker`: `gpt-5.5`
|
|
623
|
+
- `Gemini worker`: `auto`
|
|
624
|
+
|
|
625
|
+
### `--related-tasks`
|
|
626
|
+
|
|
627
|
+
간단한 연관 task 식별자 목록을 쉼표로 전달합니다.
|
|
628
|
+
|
|
629
|
+
예:
|
|
10
630
|
|
|
11
631
|
```bash
|
|
12
|
-
|
|
632
|
+
scripts/okstra.sh --task-type error-analysis --related-tasks scanner-regression,reply-ui --project-id jobs --task-group tasks --task-id 8852 --task-brief .project-docs/tasks/8852/BUG_REPORT.md
|
|
13
633
|
```
|
|
14
634
|
|
|
15
|
-
|
|
635
|
+
연관 task는 참고용 메타데이터이며 현재 task key를 대체하지 않습니다.
|
|
636
|
+
|
|
637
|
+
### `--render-only`
|
|
638
|
+
|
|
639
|
+
실제 Claude 실행 없이 프롬프트와 task bundle만 생성합니다.
|
|
640
|
+
|
|
641
|
+
이 모드에서는 아래를 수행하지 않습니다.
|
|
642
|
+
|
|
643
|
+
- Claude 실행
|
|
644
|
+
- `final-report-<task-type>-<seq>.md` 생성
|
|
645
|
+
- `final-<task-type>-<seq>.status` 생성
|
|
646
|
+
|
|
647
|
+
하지만 아래는 수행합니다.
|
|
648
|
+
|
|
649
|
+
- stable task root 생성 또는 갱신
|
|
650
|
+
- `task-manifest.json` 생성 또는 갱신
|
|
651
|
+
- `task-index.md` 생성 또는 갱신
|
|
652
|
+
- `instruction-set/` 생성 또는 갱신
|
|
653
|
+
- `instruction-set/reference-expectations.md` 생성 또는 갱신
|
|
654
|
+
- `instruction-set/final-report-template.md` 생성 또는 갱신
|
|
655
|
+
- current `manifests/run-manifest-<task-type>-<seq>.json` 기록
|
|
656
|
+
- `history/timeline.json` 갱신
|
|
657
|
+
- project-level discovery pointer 생성 또는 갱신
|
|
658
|
+
|
|
659
|
+
### `--refresh-assets`
|
|
660
|
+
|
|
661
|
+
project-local `.claude/skills/`와 `.claude/agents/` 아래의 okstra mapped asset을 workspace source 기준으로 다시 생성합니다.
|
|
662
|
+
기본 rerun에서는 기존 project-local asset을 유지합니다.
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
## Interactive input flow
|
|
666
|
+
|
|
667
|
+
interactive terminal에서 필수 인자 일부를 생략하면 `okstra`가 아래 항목을 순서대로 물을 수 있습니다.
|
|
668
|
+
|
|
669
|
+
- `Project ID`
|
|
670
|
+
- `Task Group`
|
|
671
|
+
- `Task ID`
|
|
672
|
+
- `Task Type`
|
|
673
|
+
- `Task Brief Path`
|
|
674
|
+
|
|
675
|
+
예를 들어 아래처럼 실행할 수 있습니다.
|
|
16
676
|
|
|
17
677
|
```bash
|
|
18
|
-
|
|
678
|
+
scripts/okstra.sh --render-only --task-type error-analysis
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
그러면 누락된 필수값을 stdin으로 입력받은 뒤, 최종 요약과 confirmation을 거쳐 진행합니다.
|
|
682
|
+
|
|
683
|
+
## Confirmation flow
|
|
684
|
+
|
|
685
|
+
interactive 실행에서는 실제 파일 생성 전에 아래 성격의 요약을 보여줍니다.
|
|
686
|
+
|
|
687
|
+
- render-only 여부
|
|
688
|
+
- task type
|
|
689
|
+
- project id
|
|
690
|
+
- task group
|
|
691
|
+
- task id
|
|
692
|
+
- task brief path
|
|
693
|
+
- analysis target
|
|
694
|
+
- related tasks
|
|
695
|
+
- selected workers
|
|
696
|
+
- lead model
|
|
697
|
+
- configured worker models
|
|
698
|
+
- task key
|
|
699
|
+
- task root
|
|
700
|
+
- current run dir
|
|
701
|
+
|
|
702
|
+
이후 `Continue? [y/yes]:` 프롬프트가 표시되며, `y` 또는 `yes`가 아니면 실행하지 않고 종료합니다.
|
|
703
|
+
|
|
704
|
+
`--yes`를 사용하면 이 confirmation flow 자체를 건너뜁니다.
|
|
705
|
+
|
|
706
|
+
## Storage model
|
|
707
|
+
|
|
708
|
+
`okstra`가 만드는 파일은 용도에 따라 아래 3개 영역에 나뉘어 저장됩니다.
|
|
709
|
+
|
|
710
|
+
### 1. Stable task root
|
|
711
|
+
|
|
712
|
+
task 자체의 기준 폴더입니다.
|
|
713
|
+
task manifest, task index, instruction-set, runs, history가 이 루트 아래에 모입니다.
|
|
714
|
+
|
|
715
|
+
```text
|
|
716
|
+
<target-project>/.project-docs/okstra/tasks/<task-group>/<task-id>/
|
|
717
|
+
├── task-manifest.json
|
|
718
|
+
├── task-index.md
|
|
719
|
+
├── instruction-set/
|
|
720
|
+
│ ├── analysis-profile.md
|
|
721
|
+
│ ├── analysis-material.md
|
|
722
|
+
│ ├── reference-expectations.md
|
|
723
|
+
│ ├── task-brief.md
|
|
724
|
+
│ ├── directive.txt # optional (mirrors --directive)
|
|
725
|
+
│ ├── final-report-template.md
|
|
726
|
+
│ └── claude-execution-prompt.md
|
|
727
|
+
├── runs/
|
|
728
|
+
│ └── <task-type>/
|
|
729
|
+
│ ├── manifests/
|
|
730
|
+
│ │ └── run-manifest-<task-type>-<seq>.json
|
|
731
|
+
│ ├── state/
|
|
732
|
+
│ │ └── team-state-<task-type>-<seq>.json
|
|
733
|
+
│ ├── prompts/
|
|
734
|
+
│ │ ├── claude-execution-prompt-<task-type>-<seq>.md
|
|
735
|
+
│ │ ├── claude-worker-prompt-<task-type>-<seq>.md
|
|
736
|
+
│ │ ├── codex-worker-prompt-<task-type>-<seq>.md
|
|
737
|
+
│ │ ├── gemini-worker-prompt-<task-type>-<seq>.md
|
|
738
|
+
│ │ └── report-writer-worker-prompt-<task-type>-<seq>.md
|
|
739
|
+
│ ├── reports/
|
|
740
|
+
│ │ └── final-report-<task-type>-<seq>.md
|
|
741
|
+
│ ├── status/
|
|
742
|
+
│ │ └── final-<task-type>-<seq>.status
|
|
743
|
+
│ ├── sessions/
|
|
744
|
+
│ │ └── claude-resume-<task-type>-<seq>.sh
|
|
745
|
+
│ ├── logs/
|
|
746
|
+
│ │ └── errors-<task-type>-<seq>.jsonl # optional, lead-only writer
|
|
747
|
+
│ └── worker-results/
|
|
748
|
+
└── history/
|
|
749
|
+
└── timeline.json
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
실제 디렉터리 세그먼트는 안전한 경로 생성을 위해 slug 형태로 정규화될 수 있습니다.
|
|
753
|
+
하지만 논리 task key는 항상 원래 입력값 기준 `project-id:task-group:task-id`를 유지합니다.
|
|
754
|
+
|
|
755
|
+
### 2. Per-run execution artifacts
|
|
756
|
+
|
|
757
|
+
실행별 산출물은 아래 경로에 누적됩니다.
|
|
758
|
+
|
|
759
|
+
```text
|
|
760
|
+
<target-project>/.project-docs/okstra/tasks/<task-group>/<task-id>/runs/<task-type>/
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
여기에 저장되는 대표 파일:
|
|
764
|
+
|
|
765
|
+
- `manifests/run-manifest-<task-type>-<seq>.json`
|
|
766
|
+
- `state/team-state-<task-type>-<seq>.json`
|
|
767
|
+
- `prompts/claude-execution-prompt-<task-type>-<seq>.md`
|
|
768
|
+
- `prompts/<worker>-worker-prompt-<task-type>-<seq>.md`
|
|
769
|
+
|
|
770
|
+
그리고 `--render-only`가 아니면 handoff된 Claude session이 보통 아래 결과 파일을 현재 run에 추가합니다.
|
|
771
|
+
- `sessions/claude-resume-<task-type>-<seq>.sh`
|
|
772
|
+
- `reports/final-report-<task-type>-<seq>.md`
|
|
773
|
+
- `status/final-<task-type>-<seq>.status`
|
|
774
|
+
최종 결과 파일 둘은 `okstra`가 stdout을 저장해서 만드는 파일이 아닙니다.
|
|
775
|
+
`okstra`가 준비한 task bundle을 바탕으로 Claude가 현재 run 안에 직접 작성하는 결과물입니다.
|
|
776
|
+
반면 `sessions/claude-resume-<task-type>-<seq>.sh`는 `okstra`가 Claude launch 전에 미리 생성하는 interruption recovery helper입니다.
|
|
777
|
+
|
|
778
|
+
run directory는 task-type 단위로 task 실행 이력을 모으고, 내부를 `manifests/`, `state/`, `prompts/`, `reports/`, `status/`, `sessions/`, `worker-results/`처럼 유형별 하위 폴더로 나눈 뒤 각 run-level artifact와 result 파일을 `-<task-type>-<seq>` suffix(per-category 3-digit zero-padded counter, 예: `001`, `002`)로 구분합니다.
|
|
779
|
+
worker prompt history는 `/tmp`가 아니라 항상 현재 run의 `prompts/` 아래 canonical artifact로 남깁니다.
|
|
780
|
+
이전처럼 `analysis-profile.md`, `analysis-material.md`, `reference-expectations.md`, `task-brief.md`, skill 복사본, `final-report-template.md`를 run마다 중복 저장하지 않습니다.
|
|
781
|
+
이 자료들은 stable task root의 `instruction-set/`에 canonical copy를 유지합니다.
|
|
782
|
+
같은 task-type으로 다시 실행하면 동일한 `runs/<task-type>/` 폴더를 재사용하지만, 유형별 하위 폴더 아래에서 run-level 파일명이 `-<task-type>-<seq>` suffix로 분리되므로 기존 산출물을 덮어쓰지 않습니다. `<seq>`는 카테고리 디렉토리(`manifests/`, `prompts/`, `reports/`, `status/`, `state/`, `sessions/`, `worker-results/`)별로 독립 스캔되므로 같은 run에서도 카테고리별 값이 다를 수 있습니다.
|
|
783
|
+
이전 flat legacy artifact가 task-type run 폴더 최상위에 남아 있으면 다음 실행 시 해당 유형별 하위 폴더로 자동 정리합니다.
|
|
784
|
+
|
|
785
|
+
### 3. Project-level discovery and skill documents
|
|
786
|
+
프로젝트 공용 discovery pointer는 아래 경로에 생성합니다.
|
|
787
|
+
|
|
788
|
+
```text
|
|
789
|
+
<target-project>/.project-docs/okstra/discovery/latest-task.json
|
|
790
|
+
<target-project>/.project-docs/okstra/discovery/task-catalog.json
|
|
791
|
+
```
|
|
792
|
+
scripts/okstra.sh workflow가 사용하는 project-local Claude assets는 아래 경로들에 seed합니다.
|
|
793
|
+
|
|
794
|
+
```text
|
|
795
|
+
<target-project>/.claude/skills/okstra/SKILL.md
|
|
796
|
+
<target-project>/.claude/skills/<sub-skill>/SKILL.md
|
|
797
|
+
<target-project>/.claude/agents/<agent>.md
|
|
19
798
|
```
|
|
20
799
|
|
|
21
|
-
|
|
800
|
+
역할 구분:
|
|
801
|
+
|
|
802
|
+
- `.project-docs/okstra/discovery/latest-task.json`: 현재 프로젝트에서 가장 최근에 준비된 okstra task bundle을 가리키는 current-task convenience pointer
|
|
803
|
+
- `.project-docs/okstra/discovery/task-catalog.json`: 현재 프로젝트에 준비된 okstra task bundle 목록을 `taskKey`, `taskGroup`, `taskId` 기준으로 유지하는 canonical project-level catalog
|
|
804
|
+
- `instruction-set/reference-expectations.md`: 현재 task가 참조해야 할 config files, deployment manifests, expected values를 task-level canonical artifact로 정리한 파일
|
|
805
|
+
- `.claude/skills/...`, `.claude/agents/...`: `agents` 아래 Markdown asset을 project-local Claude asset 구조로 seed한 파일들
|
|
806
|
+
|
|
807
|
+
기본 rerun에서는 이미 존재하는 project-local asset을 유지합니다.
|
|
808
|
+
`--refresh-assets`를 주면 mapped okstra asset을 source 기준으로 다시 생성합니다.
|
|
809
|
+
|
|
810
|
+
이전의 아래 파일들은 더 이상 okstra 생성 대상이 아닙니다.
|
|
811
|
+
|
|
812
|
+
- `CLAUDE.md`
|
|
813
|
+
- `.project-docs/ai/claude-project-guide.md`
|
|
814
|
+
- `.project-docs/ai/claude-skill-index.md`
|
|
815
|
+
- `.project-docs/ai/okstra/okstra-guide.md`
|
|
816
|
+
- `.project-docs/ai/okstra/worker-catalog.md`
|
|
817
|
+
|
|
818
|
+
## Task manifest contract
|
|
819
|
+
|
|
820
|
+
`task-manifest.json`은 Claude가 task continuity를 이해할 때 기준이 되는 canonical metadata 파일입니다.
|
|
821
|
+
이 manifest는 `projectRoot` 절대경로를 한 번만 기록하고, 나머지 생성 경로들은 가능한 한 project-relative field로 정리하는 것을 기본 원칙으로 합니다.
|
|
822
|
+
|
|
823
|
+
핵심 필드 예시:
|
|
824
|
+
|
|
825
|
+
- `projectId`
|
|
826
|
+
- `taskGroup`
|
|
827
|
+
- `taskId`
|
|
828
|
+
- `taskKey`
|
|
829
|
+
- `projectRoot`
|
|
830
|
+
- `taskType`
|
|
831
|
+
- `workCategory`
|
|
832
|
+
- `taskBriefPath`
|
|
833
|
+
- `relatedTasks`
|
|
834
|
+
- `currentStatus`
|
|
835
|
+
- `taskRootPath`
|
|
836
|
+
- `instructionSetPath`
|
|
837
|
+
- `referenceExpectationsPath`
|
|
838
|
+
- `runsPath`
|
|
839
|
+
- `historyTimelinePath`
|
|
840
|
+
- `latestRunPath`
|
|
841
|
+
- `latestRunStatus`
|
|
842
|
+
- `latestRunPromptsPath`
|
|
843
|
+
- `latestReportPath`
|
|
844
|
+
- `latestResumeCommandPath`
|
|
845
|
+
- `workflow.currentPhase`
|
|
846
|
+
- `workflow.currentPhaseState`
|
|
847
|
+
- `workflow.phaseStates`
|
|
848
|
+
- `workflow.lastCompletedPhase`
|
|
849
|
+
- `workflow.nextRecommendedPhase`
|
|
850
|
+
- `workflow.awaitingApproval`
|
|
851
|
+
- `workflow.routingStatus`
|
|
852
|
+
- `workflow.lastSafeCheckpoint`
|
|
853
|
+
- `inputs`
|
|
854
|
+
- `artifacts`
|
|
855
|
+
- `resultContract`
|
|
856
|
+
- `claudeSession`
|
|
857
|
+
|
|
858
|
+
이 manifest는 아래 목적을 가집니다.
|
|
859
|
+
|
|
860
|
+
- Claude가 brief보다 먼저 task continuity를 이해하게 함
|
|
861
|
+
- 어떤 파일을 우선 읽어야 하는지 고정함
|
|
862
|
+
- 어떤 config files와 deployment manifests를 어떤 expected values로 해석해야 하는지 고정함
|
|
863
|
+
- 어떤 task key 아래 결과가 누적되는지 고정함
|
|
864
|
+
- related task와 latest run 위치를 빠르게 확인하게 함
|
|
865
|
+
|
|
866
|
+
## Task index contract
|
|
867
|
+
|
|
868
|
+
`task-index.md`는 사람이 빠르게 읽기 위한 요약 문서입니다.
|
|
869
|
+
|
|
870
|
+
주요 내용:
|
|
871
|
+
- task key
|
|
872
|
+
- current task type
|
|
873
|
+
- work category
|
|
874
|
+
- 현재 task 상태
|
|
875
|
+
- 최신 run 상태
|
|
876
|
+
- current phase
|
|
877
|
+
- current phase state
|
|
878
|
+
- next recommended phase
|
|
879
|
+
- reference expectations
|
|
880
|
+
- latest run
|
|
881
|
+
- latest report
|
|
882
|
+
- resume command
|
|
883
|
+
|
|
884
|
+
이 문서는 quick summary일 뿐이며 source of truth가 아닙니다.
|
|
885
|
+
canonical metadata는 항상 `task-manifest.json`을 기준으로 확인합니다.
|
|
886
|
+
|
|
887
|
+
## Run manifest contract
|
|
888
|
+
|
|
889
|
+
각 실행은 `runs/<task-type>/manifests/run-manifest-<task-type>-<seq>.json`에 현재 run 계약을 남깁니다.
|
|
890
|
+
|
|
891
|
+
`manifests/run-manifest-<task-type>-<seq>.json`의 path 계열 필드는 모두 대상 프로젝트 루트 기준 상대경로만 저장합니다.
|
|
892
|
+
`okstra`가 Claude handoff를 시작한 직후에는 현재 run 상태가 보통 `in-progress`로 기록됩니다.
|
|
893
|
+
이후 최종 결과 저장과 상태 갱신은 Claude가 이어서 수행합니다.
|
|
894
|
+
또한 `okstra`는 launch 전에 session ID를 선할당하고, 같은 run의 `sessions/` 아래에 `claude-resume-<task-type>-<seq>.sh`를 생성합니다.
|
|
895
|
+
|
|
896
|
+
주요 내용:
|
|
897
|
+
|
|
898
|
+
- task key
|
|
899
|
+
- task type
|
|
900
|
+
- work category
|
|
901
|
+
- run datetime segment
|
|
902
|
+
- task brief relative path
|
|
903
|
+
- analysis target
|
|
904
|
+
- related tasks
|
|
905
|
+
- selected workers
|
|
906
|
+
- worker model assignments
|
|
907
|
+
- claude session id
|
|
908
|
+
- resume command relative path
|
|
909
|
+
- expected report relative path
|
|
910
|
+
- expected status relative path
|
|
911
|
+
- prompt snapshot relative path
|
|
912
|
+
- `worker prompt directory relative path`
|
|
913
|
+
- `worker prompt relative path by worker id`
|
|
914
|
+
- current run status
|
|
915
|
+
- workflow snapshot
|
|
916
|
+
- team contract
|
|
917
|
+
|
|
918
|
+
## Timeline contract
|
|
919
|
+
|
|
920
|
+
`history/timeline.json`은 task에 속한 run 이력을 누적합니다.
|
|
921
|
+
|
|
922
|
+
이력에는 보통 아래가 포함됩니다.
|
|
923
|
+
|
|
924
|
+
- run timestamp
|
|
925
|
+
- run directory relative path
|
|
926
|
+
- run manifest relative path
|
|
927
|
+
- run time segment
|
|
928
|
+
- task type
|
|
929
|
+
- work category
|
|
930
|
+
- status
|
|
931
|
+
- worker prompt directory relative path
|
|
932
|
+
- report relative path
|
|
933
|
+
- resume command relative path
|
|
934
|
+
- related tasks
|
|
935
|
+
- workflow snapshot
|
|
936
|
+
같은 task-type을 다시 실행하면 같은 `runs/<task-type>/` 폴더를 재사용하더라도 `run-manifest-<task-type>-<seq>.json`과 관련 artifact 경로가 per-category sequence suffix(`<task-type>-<seq>`)로 분리되므로 각 실행이 별도 이력으로 누적됩니다. cross-category 식별자는 manifest의 `runDateTimeSegment` ISO timestamp 필드입니다.
|
|
22
937
|
|
|
23
|
-
##
|
|
938
|
+
## Claude operating contract
|
|
24
939
|
|
|
25
|
-
|
|
940
|
+
`okstra` 실행 후 Claude는 아래 순서로 현재 task를 읽는 것을 기본 규칙으로 삼아야 합니다.
|
|
941
|
+
|
|
942
|
+
1. task browsing 또는 task-id disambiguation이 필요하면 `.project-docs/okstra/discovery/task-catalog.json`을 먼저 읽습니다.
|
|
943
|
+
2. 현재 task key나 task path가 명시되지 않았다면 `.project-docs/okstra/discovery/latest-task.json`을 current-task pointer로 읽습니다.
|
|
944
|
+
3. `task-manifest.json`을 읽습니다.
|
|
945
|
+
4. `task-index.md`는 quick summary가 필요할 때만 선택적으로 읽습니다.
|
|
946
|
+
5. `instruction-set/analysis-profile.md`를 읽습니다.
|
|
947
|
+
6. `instruction-set/analysis-material.md`를 읽습니다.
|
|
948
|
+
7. `instruction-set/reference-expectations.md`를 읽습니다.
|
|
949
|
+
8. `instruction-set/task-brief.md`를 읽습니다.
|
|
950
|
+
9. `instruction-set/final-report-template.md`를 읽습니다.
|
|
951
|
+
10. current `manifests/run-manifest-<task-type>-<seq>.json`을 읽습니다.
|
|
952
|
+
11. 필요하면 `history/timeline.json`과 이전 run 결과를 참고합니다.
|
|
953
|
+
12. `Claude lead`로서 required worker `Claude worker`, `Codex worker`, `Gemini worker`, `Report writer worker`를 기준으로 역할을 구성합니다.
|
|
954
|
+
13. 각 selected worker prompt를 assigned worker prompt history path로 현재 run의 `prompts/` 아래에 먼저 저장한 뒤 worker를 dispatch합니다.
|
|
955
|
+
14. 각 required worker에 대해 결과 또는 terminal status를 수집합니다.
|
|
956
|
+
15. brief이 더 구체적인 형식을 강제하지 않으면 `final-report-template.md` 구조로 Markdown 최종 보고서를 작성합니다.
|
|
957
|
+
16. 결과를 현재 run의 `reports/final-report-<task-type>-<seq>.md`에 직접 저장하고, 필요하면 `status/final-<task-type>-<seq>.status`, `manifests/run-manifest-<task-type>-<seq>.json`, `task-manifest.json`, `task-index.md`도 현재 상태에 맞게 갱신합니다.
|
|
958
|
+
|
|
959
|
+
권장 worker 상태값:
|
|
960
|
+
|
|
961
|
+
- `completed`
|
|
962
|
+
- `timeout`
|
|
963
|
+
- `error`
|
|
964
|
+
- `not-run`
|
|
965
|
+
|
|
966
|
+
## Task brief usage
|
|
967
|
+
|
|
968
|
+
`okstra`는 brief-first 구조입니다. brief 가 분석의 정본 입력이며, 워커가 필요로 할 추가 자료(보고서, 코드 스니펫, 로그 등)는 brief 내부의 `Evidence and Source Materials` 섹션에 inline 또는 path 로 모두 포함시킵니다.
|
|
969
|
+
|
|
970
|
+
brief에는 보통 아래를 포함합니다.
|
|
971
|
+
|
|
972
|
+
- 문제 설명
|
|
973
|
+
- 요구사항
|
|
974
|
+
- 기존 분석
|
|
975
|
+
- raw sample 또는 log
|
|
976
|
+
- 관련 코드 경로
|
|
977
|
+
- 제약사항
|
|
978
|
+
- worker에게 줄 질문
|
|
979
|
+
- 기대 출력
|
|
980
|
+
- 이전 run 또는 연관 task 정보
|
|
981
|
+
|
|
982
|
+
기본 템플릿:
|
|
983
|
+
|
|
984
|
+
- `templates/reports/quick-input.template.md`
|
|
985
|
+
- `templates/reports/task-brief.template.md`
|
|
986
|
+
- `templates/reports/error-analysis-input.template.md`
|
|
987
|
+
- `templates/reports/implementation-planning-input.template.md`
|
|
988
|
+
- `templates/reports/implementation-input.template.md`
|
|
989
|
+
- `templates/reports/final-verification-input.template.md`
|
|
990
|
+
|
|
991
|
+
입력 템플릿에서는 최소한 아래 항목을 채우는 것을 권장합니다.
|
|
992
|
+
|
|
993
|
+
- `Project ID`
|
|
994
|
+
- `Task Group`
|
|
995
|
+
- `Task ID`
|
|
996
|
+
- `Related Tasks`
|
|
997
|
+
- `Task Type`
|
|
998
|
+
- `Requested Outcome`
|
|
999
|
+
|
|
1000
|
+
## Recommended workflow
|
|
1001
|
+
|
|
1002
|
+
### 1. 초안 작성
|
|
1003
|
+
|
|
1004
|
+
빠르게 메모를 정리할 때는 `okstra-quick-input.template.md`를 사용합니다.
|
|
1005
|
+
|
|
1006
|
+
### 2. 정식 brief 작성
|
|
1007
|
+
|
|
1008
|
+
최종 입력은 `okstra-task-brief.md`로 정리합니다.
|
|
1009
|
+
같은 task를 다시 이어갈 계획이면 같은 `task-group`과 `task-id`를 유지합니다.
|
|
1010
|
+
|
|
1011
|
+
### 2.5. 필요 시 요구사항 triage
|
|
1012
|
+
|
|
1013
|
+
요청이 버그 수정인지 신규 기능인지, 요구사항이 충분한지 먼저 분류해야 하면 같은 `okstra-task-brief.md`에 `Task Type: requirements-discovery`를 넣고 실행합니다.
|
|
1014
|
+
이 단계는 이후 phase를 자동 실행하지 않고, work category와 다음 권장 phase를 task lifecycle metadata에 남기는 역할만 합니다.
|
|
1015
|
+
|
|
1016
|
+
```bash
|
|
1017
|
+
scripts/okstra.sh --task-type requirements-discovery --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path>
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
### 3. Render-only 검증
|
|
1021
|
+
|
|
1022
|
+
```bash
|
|
1023
|
+
scripts/okstra.sh --render-only --task-type error-analysis --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path>
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
### 4. Claude 실행
|
|
1027
|
+
|
|
1028
|
+
두 가지 진입 방식이 있으며 산출물은 동일합니다.
|
|
1029
|
+
|
|
1030
|
+
**Option A — 새 claude 프로세스를 띄움 (`okstra.sh`)**
|
|
1031
|
+
|
|
1032
|
+
```bash
|
|
1033
|
+
scripts/okstra.sh --task-type error-analysis --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path>
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
이 경로로 실행하면 `okstra.sh` 가 prepare 단계를 마친 뒤 대상 프로젝트 루트에서 새 Claude interactive session 을 `exec` 합니다. handoff 까지만 수행하고 최종 보고서 저장은 Claude lead 가 이어서 수행합니다. 실행 직전에 `sessions/claude-resume-<task-type>-<seq>.sh` 가 미리 작성되므로 세션이 중간에 끊겨도 같은 run 을 재개할 수 있습니다.
|
|
1037
|
+
|
|
1038
|
+
**Option B — 현재 claude 세션 안에서 인계 (`okstra-run` skill)**
|
|
1039
|
+
|
|
1040
|
+
이미 Claude Code 세션을 사용 중이라면 새 프로세스를 띄우지 않고 같은 세션이 그대로 Claude lead 로 인계받게 할 수 있습니다. trigger 예: `"run okstra here"`, `"start error-analysis on this project"`.
|
|
1041
|
+
|
|
1042
|
+
skill 흐름:
|
|
1043
|
+
|
|
1044
|
+
1. `okstra-run` skill 이 활성화되고 `AskUserQuestion` 으로 task 후보 / task-type / brief 경로를 받습니다.
|
|
1045
|
+
2. 사용자의 입력으로 `okstra_ctl.run.prepare_task_bundle(render_only=True)` 를 호출합니다 — `okstra.sh` 를 거치지 않고 같은 python 함수를 직접 호출합니다.
|
|
1046
|
+
3. 같은 instruction-set 산출물이 디스크에 만들어지면 현재 claude 가 그 prompt 를 읽어 lead 역할로 진입합니다.
|
|
1047
|
+
|
|
1048
|
+
자세한 절차는 [`skills/okstra-run/SKILL.md`](skills/okstra-run/SKILL.md) 참조.
|
|
1049
|
+
|
|
1050
|
+
### 5. 필요 시 에러 분석
|
|
1051
|
+
|
|
1052
|
+
```bash
|
|
1053
|
+
scripts/okstra.sh --task-type error-analysis --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path>
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
첫 진입 이후 같은 task에 추가 run이 필요하면 단축 형식 사용:
|
|
1057
|
+
|
|
1058
|
+
```bash
|
|
1059
|
+
scripts/okstra.sh --task-key <project-id>:<task-group>:<task-id> --task-type error-analysis
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
### 5.5. 답변 후 즉시 재실행
|
|
1063
|
+
|
|
1064
|
+
`requirements-discovery` 또는 `error-analysis` final report의 Section 5에 답변을 채워야 한다면, 경로를 손으로 들고 다닐 필요 없이 한 번에 처리합니다.
|
|
1065
|
+
|
|
1066
|
+
```bash
|
|
1067
|
+
scripts/okstra.sh --resume-clarification --task-key <project-id>:<task-group>:<task-id>
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
`$EDITOR`로 최신 final report가 열리고, 저장 후 같은 phase가 자동으로 `--clarification-response` carry-in 으로 재실행됩니다.
|
|
1071
|
+
|
|
1072
|
+
### 6. 필요 시 구현 계획 검토
|
|
1073
|
+
|
|
1074
|
+
```bash
|
|
1075
|
+
scripts/okstra.sh --task-type implementation-planning --workers claude,codex --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path>
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
후속 phase 단축 형식 (manifest의 `workflow.nextRecommendedPhase`가 `implementation-planning`이면 `--task-type` 도 생략 가능):
|
|
1079
|
+
|
|
1080
|
+
```bash
|
|
1081
|
+
scripts/okstra.sh --task-key <project-id>:<task-group>:<task-id> --workers claude,codex
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
### 7. 승인된 plan 기반 구현
|
|
1085
|
+
|
|
1086
|
+
`implementation-planning` final report의 `User Approval Request` 블록에 사용자 승인이 기록된 뒤에만 실행합니다. 승인된 plan 경로를 `--approved-plan`으로 carry-in해야 하며, plan이 없거나 승인 마커가 없으면 run은 `contract-violated`로 거부됩니다.
|
|
1087
|
+
|
|
1088
|
+
승인 마커는 line-anchored, case-insensitive로 다음 중 하나와 일치해야 합니다(코드 진실: `scripts/okstra.sh`).
|
|
1089
|
+
|
|
1090
|
+
- `APPROVED` (라인 시작에 단독, 또는 뒤에 공백/콜론)
|
|
1091
|
+
- `[x] Approved`
|
|
1092
|
+
- `User Approval: APPROVED` / `User Approval: granted` / `User Approval: yes`
|
|
1093
|
+
|
|
1094
|
+
```bash
|
|
1095
|
+
scripts/okstra.sh --task-type implementation --workers claude,codex,gemini --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> --approved-plan <runs/implementation-planning/.../reports/final-report.md>
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
단축 형식:
|
|
1099
|
+
|
|
1100
|
+
```bash
|
|
1101
|
+
scripts/okstra.sh --task-key <project-id>:<task-group>:<task-id> --task-type implementation --workers claude,codex,gemini --approved-plan <runs/implementation-planning/.../reports/final-report.md>
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
### 8. 구현 후 최종 검토
|
|
1105
|
+
|
|
1106
|
+
```bash
|
|
1107
|
+
scripts/okstra.sh --task-type final-verification --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path>
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
단축 형식:
|
|
1111
|
+
|
|
1112
|
+
```bash
|
|
1113
|
+
scripts/okstra.sh --task-key <project-id>:<task-group>:<task-id> --task-type final-verification
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
### 9. 같은 task 재개
|
|
1117
|
+
|
|
1118
|
+
같은 bugfix나 same workstream을 다시 열면 기존과 같은 `task-group`과 `task-id`를 사용합니다.
|
|
1119
|
+
그러면 기존 task root 아래 `runs/`와 `history/timeline.json`에 이력이 계속 누적됩니다.
|
|
1120
|
+
첫 진입 이후에는 `--task-key <p>:<g>:<i>` 단축 형식이 가장 간결하며, 누락된 brief/task-type은 manifest에서 자동 채워집니다.
|
|
1121
|
+
|
|
1122
|
+
## Lifecycle status and resume
|
|
1123
|
+
|
|
1124
|
+
장기 작업에서는 `task-manifest.json`의 `workflow`가 canonical lifecycle 상태입니다.
|
|
1125
|
+
특히 아래 항목을 먼저 확인하면 현재 위치와 재개 지점을 빠르게 판단할 수 있습니다.
|
|
1126
|
+
|
|
1127
|
+
- `workflow.currentPhase`
|
|
1128
|
+
- `workflow.currentPhaseState`
|
|
1129
|
+
- `workflow.phaseStates`
|
|
1130
|
+
- `workflow.lastCompletedPhase`
|
|
1131
|
+
- `workflow.nextRecommendedPhase`
|
|
1132
|
+
- `workflow.awaitingApproval`
|
|
1133
|
+
- `workflow.routingStatus`
|
|
1134
|
+
- `workflow.lastSafeCheckpoint`
|
|
1135
|
+
|
|
1136
|
+
프로젝트 전체 상태를 훑을 때는 `.project-docs/okstra/discovery/task-catalog.json`을 사용합니다.
|
|
1137
|
+
특정 task의 최신 상태를 볼 때는 `.project-docs/okstra/discovery/latest-task.json`, `task-manifest.json`, 최신 `run-manifest`, `history/timeline.json` 순서로 확인합니다.
|
|
1138
|
+
|
|
1139
|
+
Claude에서는 seeded `okstra-status` skill을 사용해 아래 질문을 직접 처리할 수 있습니다.
|
|
1140
|
+
|
|
1141
|
+
- 전체 okstra task status 보여줘
|
|
1142
|
+
- 특정 `task-key`의 current phase와 next phase 알려줘
|
|
1143
|
+
- approval 대기 중인 task와 resume 가능한 task를 보여줘
|
|
1144
|
+
- `<task-id>`의 `workStatus`를 `todo` / `in-progress` / `blocked` / `done`으로 업데이트해줘 (예: "okstra mark <task-id> done", "<task-id> 진행중") — skill이 해당 `task-manifest.json`의 `workStatus`, `workStatusUpdatedAt`, `workStatusNote`를 갱신합니다.
|
|
1145
|
+
|
|
1146
|
+
resume 판단 기준:
|
|
1147
|
+
|
|
1148
|
+
- 현재 run 재개: `latestResumeCommandPath`가 있으면 그 경로를 우선 사용합니다.
|
|
1149
|
+
- 현재 phase 재시작: 같은 `task-key`와 현재 `task-type`으로 다시 실행합니다.
|
|
1150
|
+
- 다음 phase 시작: `workflow.nextRecommendedPhase`가 구체적인 phase면 그 값으로 다음 `okstra.sh` 실행을 준비합니다.
|
|
1151
|
+
- 추가 자료 필요: `routingStatus=pending` 또는 `nextRecommendedPhase=pending-routing-decision`이면 brief 보강이 먼저입니다.
|
|
1152
|
+
|
|
1153
|
+
## Preferred final report structure
|
|
1154
|
+
|
|
1155
|
+
기본 최종 보고서 템플릿은 `templates/reports/final-report.template.md`입니다.
|
|
1156
|
+
Claude가 작성하는 최종 보고서는 brief에 더 구체적인 형식이 없다면 아래 구조를 우선 사용합니다.
|
|
1157
|
+
|
|
1158
|
+
1. 문제 또는 검증 대상 요약
|
|
1159
|
+
2. 에이전트별 실행 현황
|
|
1160
|
+
3. Cross Verification 결과
|
|
1161
|
+
4. 최종 판단
|
|
1162
|
+
5. 근거 및 세부 분석
|
|
1163
|
+
6. 누락 정보 및 리스크
|
|
1164
|
+
7. 권장 다음 단계
|
|
1165
|
+
|
|
1166
|
+
차이점이 실질적으로 없으면 억지로 대비를 만들지 말고, 차이가 없음을 명시합니다.
|
|
1167
|
+
저장 실패나 세션 제한에 대한 메타 설명 대신 실제 Markdown 보고서 본문을 파일에 작성해야 합니다.
|
|
1168
|
+
|
|
1169
|
+
## Worker error collection (optional sidecar)
|
|
1170
|
+
|
|
1171
|
+
워커(Claude/Codex/Gemini worker, Report writer, Claude lead) 실행 중 발생한 에러를 단일 시계열 로그로 수집해 사후 회고에 사용할 수 있습니다.
|
|
1172
|
+
|
|
1173
|
+
- 저장 위치: `runs/<task-type>/logs/errors-<task-type>-<seq>.jsonl`
|
|
1174
|
+
- append-only JSON Lines, run 단위 격리이므로 별도 회전 정책은 두지 않습니다.
|
|
1175
|
+
- **Single writer**: 동시 append 충돌을 피하기 위해 `Claude lead`만 직접 이 파일에 씁니다. `<seq>`는 카테고리(`logs/`, `manifests/`, `state/` 등) 디렉토리별로 독립 스캔되는 3-digit zero-padded counter (`001`, `002`, …)이므로 같은 run에서도 카테고리별 값이 다를 수 있습니다(이전 run이 일부 카테고리만 기록한 경우). 한 run의 cross-category 식별자는 manifest의 `runDateTimeSegment` ISO timestamp 필드입니다.
|
|
1176
|
+
- 워커 내부 도구 실패는 워커 결과 매니페스트의 `errors[]`에 보고 → lead가 merge 직후 dump
|
|
1177
|
+
- Codex/Gemini CLI 실패·타임아웃·rate-limit는 lead가 wrapper에서 직접 관찰
|
|
1178
|
+
- resultContract 위반·스키마 mismatch·필수 필드 누락은 lead 검증 단계에서 직접 관찰
|
|
1179
|
+
- `source` 필드(`worker-reported` | `lead-observed`)와 `errorType`(`tool-failure` | `cli-failure` | `contract-violation`)으로 발생원과 종류를 구분합니다.
|
|
1180
|
+
- `stderrExcerpt`는 한 줄 jsonl 가독성을 위해 2KB 상한, `PIPE_BUF`(4096B) atomic append 가드를 강제합니다.
|
|
1181
|
+
- run-manifest 또는 team-state의 `errorsLogPath` 필드에 `logs/errors-<task-type>-<seq>.jsonl` 경로를 1회 기록해 발견 가능하게 합니다.
|
|
1182
|
+
- Helper CLI: `scripts/okstra-error-log.py`
|
|
1183
|
+
- 단일 진입점으로 record를 append 합니다.
|
|
1184
|
+
- 워커 sidecar dump(`append_observed`, schema version 가드)와 lead 관찰(`lead-observed`) 모두 동일 helper를 사용합니다.
|
|
1185
|
+
|
|
1186
|
+
상세 설계 및 jq 회고 레시피는 `docs/superpowers/specs/2026-04-28-worker-error-collection-design.md`를 참고합니다.
|
|
1187
|
+
|
|
1188
|
+
## Token usage and cost accounting
|
|
1189
|
+
|
|
1190
|
+
각 run에 사용된 토큰을 lead/worker 세션 트랜스크립트에서 수집해 `team-state.json`의 `leadUsage` / `workers[].usage`에 다시 기록합니다.
|
|
1191
|
+
|
|
1192
|
+
- Helper CLI: `scripts/okstra-token-usage.py`
|
|
1193
|
+
- 수집 소스:
|
|
1194
|
+
- Claude lead/workers: `~/.claude/projects/<cwd-as-dashes>/<sessionId>.jsonl`의 per-message `message.usage`
|
|
1195
|
+
- Codex CLI: `~/.codex/sessions/Y/M/D/rollout-*.jsonl`의 마지막 `total_token_usage.total_tokens`
|
|
1196
|
+
- Gemini CLI: `~/.gemini/tmp/*/chats/session-*.json`의 per-message `tokens.total`
|
|
1197
|
+
- billable-equivalent token math와 USD cost estimation을 함께 기록합니다. Anthropic billing ratio(`cache_creation=1.25x`, `cache_read=0.1x`, `output=5x`)를 반영합니다.
|
|
1198
|
+
- 가격표는 helper 상단에서 중앙 관리합니다. 모델 가격이 바뀌면 helper의 `*_PRICING` 상수를 갱신해야 합니다.
|
|
1199
|
+
|
|
1200
|
+
## Practical notes
|
|
1201
|
+
|
|
1202
|
+
- `okstra`는 brief 없이 쓰는 옛 방식이 아닙니다.
|
|
1203
|
+
- brief이 분석의 정본 입력입니다. 추가 자료는 brief 내부의 `Evidence and Source Materials` 섹션에 inline 또는 path 로 포함시키며, 별도의 추가 자료 CLI 옵션은 제공하지 않습니다.
|
|
1204
|
+
- brief의 `Configuration References and Expected Values`, `Deployment Manifests and Expected Values` 섹션은 task별 expected state의 canonical source입니다.
|
|
1205
|
+
- `task-type`가 프로필 선택까지 결정합니다.
|
|
1206
|
+
- `--render-only`는 dry-run 확인용이지만 task bundle과 run manifest는 생성합니다.
|
|
1207
|
+
- `--refresh-assets`는 `.claude/skills/`와 `.claude/agents/`의 okstra mapped asset을 source 기준으로 다시 생성합니다.
|
|
1208
|
+
- 기본 실행은 Claude print-mode 수집이 아니라 interactive handoff입니다.
|
|
1209
|
+
- 기본 최종 보고서 템플릿은 task bundle의 `instruction-set/final-report-template.md`에 렌더링됩니다.
|
|
1210
|
+
- task bundle의 `instruction-set/reference-expectations.md`는 config/deployment expected-state reference로 함께 생성됩니다.
|
|
1211
|
+
- 현재 run 세션의 resume helper는 `runs/<task-type>/sessions/claude-resume-<task-type>-<seq>.sh`에 생성됩니다.
|
|
1212
|
+
- run directory 내부는 `manifests/`, `state/`, `prompts/`, `reports/`, `status/`, `sessions/`, `worker-results/`처럼 유형별 하위 폴더로 구성되고, prompt snapshot은 `prompts/` 아래에 먼저 준비됩니다.
|
|
1213
|
+
- worker 생성과 결과 취합은 Claude가 수행합니다.
|
|
1214
|
+
- standard workflow는 `Claude lead` + required worker `Claude worker`, `Codex worker`, `Gemini worker`, `Report writer worker`를 사용합니다.
|
|
1215
|
+
- worker 모델은 `--lead-model`, `--claude-model`, `--codex-model`, `--gemini-model`, `--report-writer-model`로 override할 수 있고, 기본값은 `OKSTRA_DEFAULT_*` 환경 변수에서 중앙 관리합니다. fallback 기본값은 `Claude lead`/`Report writer worker`=`opus`, `Claude worker`=`sonnet`, `Codex worker`=`gpt-5.5`, `Gemini worker`=`auto`입니다.
|
|
1216
|
+
- project-level current-task convenience pointer는 `.project-docs/okstra/discovery/latest-task.json`입니다.
|
|
1217
|
+
- project-level canonical task inventory는 `.project-docs/okstra/discovery/task-catalog.json`입니다.
|
|
1218
|
+
- project-local okstra Claude asset은 `.claude/skills/`와 `.claude/agents/` 아래에 seed되며, 기본 rerun에서는 보존되고 `--refresh-assets`로 다시 생성할 수 있습니다.
|
|
1219
|
+
- seeded okstra Claude assets는 Agent Teams 우선, sequential/background fallback 차선 규칙을 Claude에게 제공합니다.
|
|
1220
|
+
- 최종 판단은 스크립트가 아니라 Claude가 수행합니다.
|
|
1221
|
+
- stable task key를 유지해야 이후 bug 추적, 재수정, 재검증이 가능합니다.
|
|
1222
|
+
- 워커 에러는 옵션 sidecar `runs/<task-type>/logs/errors-<task-type>-<seq>.jsonl`로 수집되며 lead가 단독 writer입니다. 진입점 helper는 `scripts/okstra-error-log.py`입니다.
|
|
1223
|
+
- 토큰 사용 및 비용 집계는 `scripts/okstra-token-usage.py`가 담당하며.
|
|
1224
|
+
- `okstra.sh`는 worker CLI 호출 anchoring을 위해 절대 projectRoot를 강제합니다.
|
|
1225
|
+
|
|
1226
|
+
## Related documents
|
|
1227
|
+
|
|
1228
|
+
- `README.md`
|
|
1229
|
+
- `templates/reports/task-brief.template.md`
|
|
1230
|
+
- `templates/reports/final-report.template.md`
|
|
1231
|
+
- `agents/SKILL.md`
|
|
1232
|
+
- `docs/superpowers/specs/2026-04-28-worker-error-collection-design.md`
|
|
1233
|
+
- `docs/superpowers/plans/2026-04-28-worker-error-collection.md`
|
|
1234
|
+
- `scripts/okstra-error-log.py`
|
|
1235
|
+
- `scripts/okstra-token-usage.py`
|
|
1236
|
+
|
|
1237
|
+
## okstra Control Center
|
|
1238
|
+
|
|
1239
|
+
`okstra-ctl` 은 사용자 홈의 `~/.okstra/` 인덱스를 사용해 모든 타깃 프로젝트의 okstra run 을 가로질러 조회·모니터링·재실행할 수 있는 CLI 다.
|
|
1240
|
+
|
|
1241
|
+
### 설치 (전역 wrapper)
|
|
1242
|
+
|
|
1243
|
+
`okstra` 와 동일하게 `~/.local/bin/` 아래에 wrapper 를 두면 어디서든 호출 가능하다.
|
|
1244
|
+
|
|
1245
|
+
```bash
|
|
1246
|
+
cat > ~/.local/bin/okstra-ctl <<'WRAPPER'
|
|
1247
|
+
#!/usr/bin/env bash
|
|
1248
|
+
exec /Volumes/Workspaces/workspace/projects/Okstra/scripts/okstra-ctl.sh "$@"
|
|
1249
|
+
WRAPPER
|
|
1250
|
+
chmod +x ~/.local/bin/okstra-ctl
|
|
1251
|
+
```
|
|
1252
|
+
|
|
1253
|
+
(`~/.local/bin` 이 `PATH` 에 포함되어 있어야 한다.)
|
|
1254
|
+
|
|
1255
|
+
### 자주 쓰는 명령
|
|
1256
|
+
|
|
1257
|
+
| 목적 | 명령 |
|
|
26
1258
|
|---|---|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
1259
|
+
| 작업한 프로젝트 목록 | `okstra-ctl projects` |
|
|
1260
|
+
| 최근 run 검색 | `okstra-ctl list --since 7d` |
|
|
1261
|
+
| 특정 프로젝트만 | `okstra-ctl list --project fontradar` |
|
|
1262
|
+
| 진행 중 run 보기 | `okstra-ctl tail active` |
|
|
1263
|
+
| 단일 run 결과 메타 | `okstra-ctl show <runId-or-prefix>` |
|
|
1264
|
+
| 결과 보고서 경로 | `okstra-ctl open <runId-or-prefix>` |
|
|
1265
|
+
| 단일 재실행 | `okstra-ctl rerun <runId-or-prefix> --yes` |
|
|
1266
|
+
| 다중 재실행 | `okstra-ctl rerun --filter --project X --status failed --yes` |
|
|
1267
|
+
| 가장 최근 재실행 | `okstra-ctl rerun last --project X --task-group Y --yes` |
|
|
1268
|
+
| 백필/재스캔 | `okstra-ctl reindex` |
|
|
1269
|
+
| 활성 run 재조정 | `okstra-ctl reconcile [--project <id|all>]` |
|
|
1270
|
+
| 배치 진행 | `okstra-ctl batch status <batch-id>` |
|
|
1271
|
+
|
|
1272
|
+
### 동작 모델
|
|
1273
|
+
|
|
1274
|
+
- `okstra.sh` 는 시작 시 1번 `record_start` hook 으로 인덱스에 메타와 invocation 을 기록한다.
|
|
1275
|
+
- 종료 처리는 `okstra-ctl` 의 모든 진입점에서 호출되는 lazy reconcile 이 수행한다(타깃 프로젝트의 `final-report-*.md` 존재로 추론).
|
|
1276
|
+
- 다중 rerun 은 대상 1건당 tmux 세션 1개를 detached 로 spawn 하고 즉시 반환한다(fire-and-forget). 사용자는 반환된 attach 명령으로 임의 세션에 접속한다.
|
|
1277
|
+
- spawn 임계 기본값은 10. `--max-spawn N` 또는 `OKSTRA_CTL_MAX_SPAWN` 으로 변경 가능.
|
|
1278
|
+
- runId 형식: `<project-id>/<task-group>/<task-id>/<task-type>/r<run-seq>` (예: `fontradar/payment/fail/error-analysis/r07`). 입력 시 prefix substring 매칭을 지원한다.
|
|
1279
|
+
|
|
1280
|
+
### 동시성 제어 (두 단계 mutex)
|
|
1281
|
+
|
|
1282
|
+
`okstra-ctl` 과 `record_start` hook 은 두 가지 서로 다른 스코프의 fcntl `LOCK_EX` 를 사용한다. 둘은 책임이 분리되어 있어 함께 들고 있어도 데드락이 발생하지 않는다.
|
|
1283
|
+
|
|
1284
|
+
| Lock | 위치 | 스코프 | 보유 시점 | 목적 |
|
|
1285
|
+
|---|---|---|---|---|
|
|
1286
|
+
| central lock | `~/.okstra/.lock` | 전역(인덱스 단위) | `record_start` 의 `active.jsonl`/`recent.jsonl`/`projects/<id>/index.jsonl` 쓰기 구간, ctl 의 reconcile / reservation 쓰기 구간 | 인덱스 jsonl 의 read-modify-write 직렬화. 동시에 일어나는 record_start append 와 reconcile rotation 이 서로 leak 하지 않게 한다. |
|
|
1287
|
+
| task lock | `~/.okstra/.locks/<projectId>-<taskGroup>-<taskId>-<taskType>.lock` | task-key + task-type 별 mutex | `okstra-ctl rerun` 의 seq 예측 + tmux spawn 구간 전체 | 동일 task 의 동시 rerun 이 같은 run-seq 를 받아 manifest/디렉토리 경합으로 깨지는 것을 막는다. central lock 보다 바깥에서 잡으므로, 다른 task 의 rerun 은 서로 블록하지 않는다. |
|
|
1288
|
+
|
|
1289
|
+
호출 순서는 항상 `task lock` → `central lock` (ctl rerun) 또는 `central lock` 단독(record_start, reconcile). 역순 보유는 발생하지 않는다.
|
|
31
1290
|
|
|
32
|
-
|
|
1291
|
+
`task_lock_filename` 은 각 세그먼트를 fs-safe 슬러그로 정규화한 뒤 `-` 를 `--` 로 escape 해 `-` 로 join 하므로, `('p','feature-8','email','x')` 와 `('p','feature','8-email','x')` 가 같은 파일명으로 충돌해 mutex 가 공유되는 문제를 방지한다 ([scripts/okstra_ctl/locks.py](scripts/okstra_ctl/locks.py)).
|
|
33
1292
|
|
|
34
|
-
|
|
1293
|
+
### 환경변수
|
|
35
1294
|
|
|
36
|
-
|
|
1295
|
+
- `OKSTRA_HOME`: 중앙 디렉터리 위치 override (기본 `~/.okstra`).
|
|
1296
|
+
- `OKSTRA_CTL_MAX_SPAWN`: rerun 동시 spawn 임계 기본값.
|
|
1297
|
+
- `OKSTRA_CTL_SKIP_BACKFILL=1`: 첫 호출 시 자동 백필 스킵.
|
|
1298
|
+
- `OKSTRA_CTL_SKIP_RECONCILE=1`: lazy reconcile 스킵(테스트/디버깅용).
|
|
1299
|
+
- `OKSTRA_RUN_SEQ_OVERRIDE`: rerun 시 okstra.sh 가 사용할 run-seq 강제값 (okstra-ctl 내부 자동 주입).
|