okstra 0.98.0 → 0.98.2
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/docs/for-ai/README.md +55 -0
- package/docs/for-ai/skills/okstra-brief.md +240 -0
- package/docs/for-ai/skills/okstra-container.md +161 -0
- package/docs/for-ai/skills/okstra-inspect.md +260 -0
- package/docs/for-ai/skills/okstra-memory.md +127 -0
- package/docs/for-ai/skills/okstra-run.md +229 -0
- package/docs/for-ai/skills/okstra-schedule.md +321 -0
- package/docs/for-ai/skills/okstra-setup.md +140 -0
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/bin/okstra-antigravity-exec.sh +6 -1
- package/runtime/bin/okstra-claude-exec.sh +6 -1
- package/runtime/bin/okstra-codex-exec.sh +6 -1
- package/runtime/skills/okstra-brief/SKILL.md +24 -13
- package/runtime/validators/validate-brief.py +36 -2
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Okstra Skills AI Manuals
|
|
2
|
+
|
|
3
|
+
이 디렉터리는 AI가 okstra 공개 스킬을 빠르게 선택하고 정확히 실행하기 위한 압축 매뉴얼이다. 원문 계약은 `skills/*/SKILL.md`이고, 이 문서는 AI용 운영 가이드다. 원문 스킬, 템플릿, validator, CLI registry가 충돌하면 원문 스킬과 실제 validator/CLI 구현을 우선한다.
|
|
4
|
+
|
|
5
|
+
## 확인한 원천
|
|
6
|
+
|
|
7
|
+
- 공개 스킬 목록: [`src/lib/skill-catalog.mjs`](../../src/lib/skill-catalog.mjs)
|
|
8
|
+
- 스킬 원문: [`skills/`](../../skills/)
|
|
9
|
+
- CLI 명령 표면: [`src/cli-registry.mjs`](../../src/cli-registry.mjs)
|
|
10
|
+
- brief 템플릿: [`templates/reports/brief.template.md`](../../templates/reports/brief.template.md)
|
|
11
|
+
- schedule 템플릿: [`templates/reports/schedule.template.md`](../../templates/reports/schedule.template.md)
|
|
12
|
+
- brief 검증기: [`validators/validate-brief.py`](../../validators/validate-brief.py)
|
|
13
|
+
- schedule 검증기: [`validators/validate-schedule.py`](../../validators/validate-schedule.py)
|
|
14
|
+
|
|
15
|
+
## 스킬 라우팅
|
|
16
|
+
|
|
17
|
+
| 사용자 의도 | 사용할 스킬 | 매뉴얼 |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| 새 프로젝트나 새 머신에서 okstra 설치/초기화 | `okstra-setup` | [`skills/okstra-setup.md`](skills/okstra-setup.md) |
|
|
20
|
+
| 요구사항, 티켓, 링크, 코드베이스 스캔, error-zip을 okstra 입력 brief로 변환 | `okstra-brief` | [`skills/okstra-brief.md`](skills/okstra-brief.md) |
|
|
21
|
+
| 현재 Claude Code 세션에서 okstra run 시작 또는 다음 phase 실행 | `okstra-run` | [`skills/okstra-run.md`](skills/okstra-run.md) |
|
|
22
|
+
| 상태, history, report, time, logs, cost, errors, error-zip, recap 확인 | `okstra-inspect` | [`skills/okstra-inspect.md`](skills/okstra-inspect.md) |
|
|
23
|
+
| task-group 전체의 클라이언트용 작업 일정 생성 | `okstra-schedule` | [`skills/okstra-schedule.md`](skills/okstra-schedule.md) |
|
|
24
|
+
| 대화/결정/선호/요구사항을 전역 Memory Book에 저장 또는 검색 | `okstra-memory` | [`skills/okstra-memory.md`](skills/okstra-memory.md) |
|
|
25
|
+
| implementation task worktree 기반 docker compose 사용자 테스트 환경 관리 | `okstra-container` | [`skills/okstra-container.md`](skills/okstra-container.md) |
|
|
26
|
+
|
|
27
|
+
## 공통 실행 규칙
|
|
28
|
+
|
|
29
|
+
1. 명령은 스킬 원문이 요구하는 경우 각각 별도의 Bash 호출로 실행한다. 특히 `okstra ensure-installed`, `okstra check-project --json`, `okstra wizard ...`, `okstra container ...` 호출을 `&&`, `||`, `$(...)`, 선행 변수 할당, `eval`, `export`로 감싸지 않는다.
|
|
30
|
+
2. `okstra <subcmd>` 호출은 자체적으로 Python path를 부트스트랩한다. 스킬에서 명시하지 않는 한 `okstra paths --shell`이나 `export PYTHONPATH=...`를 만들지 않는다.
|
|
31
|
+
3. `okstra-setup`을 제외한 대부분의 스킬은 `npx` fallback을 쓰지 않는다. runtime이 없으면 사용자에게 `/okstra-setup`을 실행하라고 알리고 멈춘다.
|
|
32
|
+
4. 프로젝트 산출물은 기본적으로 `<PROJECT_ROOT>/.okstra/` 아래에 둔다. 예외는 `okstra-memory`이며, 이 스킬은 전역 사용자 메모리 `~/.okstra/memory-book/`을 사용한다.
|
|
33
|
+
5. `runtime/`은 build output이다. 스킬 원문이나 템플릿을 고칠 때는 `skills/`, `templates/`, `validators/`, `scripts/`, `src/`의 source를 수정하고 build로 반영한다.
|
|
34
|
+
6. tracker, URL, 파일, report, log, zip, template, validator 내용을 추측하지 않는다. 도구로 읽거나 실행해서 확인한 내용만 사용한다.
|
|
35
|
+
7. read-side 스킬도 일부 산출물을 만든다. `okstra-inspect errors`는 error report Markdown을 만들고, `okstra-inspect error-zip`은 anonymized zip을 만든다. 이런 경우에도 CLI stdout JSON을 source of truth로 둔다.
|
|
36
|
+
|
|
37
|
+
## AI가 읽는 순서
|
|
38
|
+
|
|
39
|
+
1. 이 파일에서 스킬을 고른다.
|
|
40
|
+
2. 해당 `docs/for-ai/skills/<skill>.md`만 읽는다.
|
|
41
|
+
3. 스킬이 실제 실행을 요구하면 원문 [`skills/<skill>/SKILL.md`](../../skills/)에서 해당 step을 확인한다.
|
|
42
|
+
4. brief나 schedule을 쓰는 경우 템플릿과 validator도 함께 확인한다.
|
|
43
|
+
|
|
44
|
+
## 공개 스킬 목록
|
|
45
|
+
|
|
46
|
+
`src/lib/skill-catalog.mjs` 기준 공개 스킬은 다음 7개다.
|
|
47
|
+
|
|
48
|
+
- `okstra-setup`
|
|
49
|
+
- `okstra-brief`
|
|
50
|
+
- `okstra-run`
|
|
51
|
+
- `okstra-memory`
|
|
52
|
+
- `okstra-inspect`
|
|
53
|
+
- `okstra-schedule`
|
|
54
|
+
- `okstra-container`
|
|
55
|
+
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# okstra-brief AI Manual
|
|
2
|
+
|
|
3
|
+
## 원천
|
|
4
|
+
|
|
5
|
+
- 스킬 원문: [`skills/okstra-brief/SKILL.md`](../../../skills/okstra-brief/SKILL.md)
|
|
6
|
+
- brief 템플릿: [`templates/reports/brief.template.md`](../../../templates/reports/brief.template.md)
|
|
7
|
+
- brief validator: [`validators/validate-brief.py`](../../../validators/validate-brief.py)
|
|
8
|
+
- lens enum SSOT: [`scripts/okstra_ctl/improvement_lenses.py`](../../../scripts/okstra_ctl/improvement_lenses.py)
|
|
9
|
+
|
|
10
|
+
## 목적
|
|
11
|
+
|
|
12
|
+
`okstra-brief`는 okstra pipeline에 넣을 task brief를 만든다. brief는 pre-discovery 산출물이다. 요구사항을 구현 계획으로 바꾸는 문서가 아니라, reporter가 준 원문과 AI가 확인한 증거/해석을 라벨로 분리해 다음 phase가 질문 없이 출발하게 만드는 handoff 문서다.
|
|
13
|
+
|
|
14
|
+
출력 위치:
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
<PROJECT_ROOT>/.okstra/briefs/<task-group>/<brief-id>.md
|
|
18
|
+
<PROJECT_ROOT>/.okstra/briefs/<task-group>/sub/.../<brief-id>.md
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 세 가지 variant
|
|
22
|
+
|
|
23
|
+
| Variant | 입력 | Recommended next phase |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| Reporter input | 파일, 티켓, URL, 대화/자유 텍스트 | `requirements-discovery` 또는 `error-analysis` |
|
|
26
|
+
| Codebase scan | scan scope, priority lenses, candidate cap, context | `improvement-discovery` |
|
|
27
|
+
| Error feedback | `okstra error-zip`이 만든 zip의 단일 error cluster | `error-analysis` |
|
|
28
|
+
|
|
29
|
+
## 핵심 불변식
|
|
30
|
+
|
|
31
|
+
1. Source Material은 원문 보존 영역이다. paraphrase, 요약, 재정렬을 하지 않는다.
|
|
32
|
+
2. AI의 해석, 파일 링크, 용어 매핑, format 변환은 모두 `Augmentation` 또는 `> augmented:` blockquote에 둔다.
|
|
33
|
+
3. augmentation은 네 label 중 하나를 가진다: `evidence-link`, `format-conversion`, `terminology-mapping`, `intent-inference`.
|
|
34
|
+
4. `intent-inference`는 `Open Questions`의 `intent-check:`와 짝을 이룬다. 이 관계는 `validators/validate-brief.py`가 검사한다.
|
|
35
|
+
5. unresolved `terminology-mapping`은 `Open Questions`의 `terminology:`와 짝을 이룬다. 이 관계도 validator가 검사한다.
|
|
36
|
+
6. reporter만 답할 수 있는 질문은 Step 6.5에서 모아 `## Reporter Confirmations`에 verbatim으로 기록한다.
|
|
37
|
+
7. 모든 okstra-owned write는 `<PROJECT_ROOT>/.okstra/` 안에 둔다. 외부 파일은 reporter가 source로 명시한 경우에만 읽는다.
|
|
38
|
+
|
|
39
|
+
## Preflight
|
|
40
|
+
|
|
41
|
+
두 명령을 각각 별도 호출로 실행한다.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
okstra ensure-installed --runtime claude-code
|
|
45
|
+
okstra check-project --json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
runtime이나 project setup이 없으면 `/okstra-setup`을 안내하고 멈춘다. 이 스킬에서 `npx` fallback을 쓰지 않는다.
|
|
49
|
+
|
|
50
|
+
## 입력 수집
|
|
51
|
+
|
|
52
|
+
### Reporter input
|
|
53
|
+
|
|
54
|
+
소스 종류는 하나 이상 가능하지만 각 소스는 `Source Material`에 별도 block으로 저장한다.
|
|
55
|
+
|
|
56
|
+
- File: 전체 파일을 읽고 그대로 넣는다.
|
|
57
|
+
- Issue tracker ticket: Linear/Jira/GitHub/Notion을 감지하고 MCP 또는 `gh` CLI를 사용한다. 접근 도구가 없으면 사용자에게 body paste 또는 skip을 묻는다.
|
|
58
|
+
- Link URL: fetch한다. 실패/로그인 wall/본문 truncation이면 사용자에게 paste를 요청한다.
|
|
59
|
+
- User input: 대화 맥락이 충분하면 conversation synthesis, 부족하면 한 번만 free-text를 받는다.
|
|
60
|
+
|
|
61
|
+
티켓에 child/sub-task가 있으면 parent에서 한 번만 tree 처리 방식을 묻는다.
|
|
62
|
+
|
|
63
|
+
- Full tree: descendant별 brief 생성.
|
|
64
|
+
- Parent only: child key/URL만 Related Artifacts에 둔다.
|
|
65
|
+
- Selected: 선택한 direct child branch만 재귀 처리.
|
|
66
|
+
|
|
67
|
+
재귀 시 visited set은 `<tracker>:<ticket-id>`로 관리하고, 재실행에서는 기존 brief frontmatter의 `ticket-id` + `source-type`으로 reseed한다.
|
|
68
|
+
|
|
69
|
+
### Codebase scan
|
|
70
|
+
|
|
71
|
+
수집값:
|
|
72
|
+
|
|
73
|
+
- `scan_scope`: 프로젝트 내부 실제 경로 목록.
|
|
74
|
+
- `priority_lenses`: `LENSES` enum 중 1-4개.
|
|
75
|
+
- `out_of_scope`: 선택.
|
|
76
|
+
- `candidate_cap`: 1-12, 기본 8.
|
|
77
|
+
- context, desired outcome, constraints.
|
|
78
|
+
|
|
79
|
+
경로 존재, lens enum subset, candidate cap 범위는 작성 전 확인한다. 최종 검증은 `validate-brief.py`가 `scope: codebase`, `Scan Scope`, `Priority Lenses`를 검사한다.
|
|
80
|
+
|
|
81
|
+
### Error feedback
|
|
82
|
+
|
|
83
|
+
입력은 `okstra error-zip --out <path>`가 만든 zip이다.
|
|
84
|
+
|
|
85
|
+
처리:
|
|
86
|
+
|
|
87
|
+
1. zip에 `report.md`, `errors/anonymized.jsonl`이 있는지 확인한다.
|
|
88
|
+
2. 빈발 cluster 표에서 cluster 하나만 선택한다.
|
|
89
|
+
3. 선택 cluster의 anonymized records만 Source Material에 옮긴다.
|
|
90
|
+
4. 서로 다른 errorType을 한 brief에 섞지 않는다.
|
|
91
|
+
5. 다음 단계 안내는 `error-analysis`로 둔다.
|
|
92
|
+
|
|
93
|
+
## task-group과 파일명
|
|
94
|
+
|
|
95
|
+
task-group은 기존 group 추천을 먼저 보여준다. `okstra task-list`를 호출해 `tasks[]`의 distinct `taskGroup`을 최신순으로 뽑고, 최근 2개 + 직접 입력을 제공한다. tracker recursion에서는 child path를 만들기 전에 task-group을 먼저 받아야 한다.
|
|
96
|
+
|
|
97
|
+
파일 경로 규칙:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
depth 0: .okstra/briefs/<task-group>/<ticket-id>-<file-title>.md
|
|
101
|
+
depth 1: .okstra/briefs/<task-group>/sub/<ticket-id>-<file-title>.md
|
|
102
|
+
depth N: .okstra/briefs/<task-group>/<sub/ repeated N>/<ticket-id>-<file-title>.md
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
frontmatter의 `depth`는 path의 `sub/` 개수와 같아야 한다. validator가 검사한다.
|
|
106
|
+
|
|
107
|
+
충돌 시 기본은 Skip이다. Append suffix 또는 Overwrite를 제공할 수 있다. tracker multi-generation에서 bulk overwrite를 조용히 수행하지 않는다.
|
|
108
|
+
|
|
109
|
+
## Domain alignment
|
|
110
|
+
|
|
111
|
+
먼저 okstra 내부 memory를 본다.
|
|
112
|
+
|
|
113
|
+
- `<PROJECT_ROOT>/.okstra/glossary.md`
|
|
114
|
+
- `<PROJECT_ROOT>/.okstra/decisions/`
|
|
115
|
+
- 관련 task의 `history/fix-cycles.jsonl`
|
|
116
|
+
|
|
117
|
+
외부 domain docs는 reporter가 source material로 명시했을 때만 읽는다. 충돌/모호 용어는 `Augmentation > Domain alignment`에 `terminology-mapping`으로 기록하고, `Open Questions`에 `terminology:` row를 둔다.
|
|
118
|
+
|
|
119
|
+
파일 path나 symbol이 언급되면 `Read`/`Grep`으로 실제 in-repo reference를 찾고 `evidence-link`로 남긴다. 매핑할 수 없으면 추측하지 않고 `conversion-block:` row로 둔다.
|
|
120
|
+
|
|
121
|
+
## Sharpening pass
|
|
122
|
+
|
|
123
|
+
full interview를 하지 않는다. source와 codebase로 채울 수 없는 gap만 묻는다.
|
|
124
|
+
|
|
125
|
+
기본 budget:
|
|
126
|
+
|
|
127
|
+
- 원문 스킬이 채움 대상으로 지정한 section당 최대 1문항.
|
|
128
|
+
- terminology/fuzzy disambiguation 최대 2문항.
|
|
129
|
+
- 전체 최대 6문항.
|
|
130
|
+
- codebase-scan은 최대 8문항.
|
|
131
|
+
|
|
132
|
+
질문보다 codebase-first 확인을 우선한다. 남은 gap은 `_(none)_` 또는 `Open Questions`에 둔다.
|
|
133
|
+
|
|
134
|
+
## template 작성 규칙
|
|
135
|
+
|
|
136
|
+
템플릿은 `templates/reports/brief.template.md`가 SSOT다. section 순서, frontmatter key, top blockquote shape, HTML comment guidance를 따른다.
|
|
137
|
+
|
|
138
|
+
Reporter input과 Error feedback:
|
|
139
|
+
|
|
140
|
+
- `## Source Material` 유지.
|
|
141
|
+
- `## Problem / Symptom` 유지.
|
|
142
|
+
- `## Scan Scope`, `## Priority Lenses` 생략.
|
|
143
|
+
|
|
144
|
+
Codebase scan:
|
|
145
|
+
|
|
146
|
+
- frontmatter에 `scope: codebase`.
|
|
147
|
+
- `## Source Material`, `## Problem / Symptom` 생략.
|
|
148
|
+
- `## Scan Scope`, `## Priority Lenses` 유지.
|
|
149
|
+
|
|
150
|
+
빈 섹션을 날조하지 않는다. 값이 없으면 `_(none)_`를 사용한다.
|
|
151
|
+
|
|
152
|
+
## frontmatter key
|
|
153
|
+
|
|
154
|
+
모든 brief는 다음 key를 가진다. key set은 `validate-brief.py`에서 검사한다.
|
|
155
|
+
|
|
156
|
+
- `type`
|
|
157
|
+
- `brief-id`
|
|
158
|
+
- `parent-id`
|
|
159
|
+
- `ticket-id`
|
|
160
|
+
- `source-type`
|
|
161
|
+
- `task-group`
|
|
162
|
+
- `depth`
|
|
163
|
+
- `created`
|
|
164
|
+
- `generator`
|
|
165
|
+
- `reporter-confirmations`
|
|
166
|
+
|
|
167
|
+
`brief-id`는 filename stem과 같아야 한다. depth 0의 `parent-id`는 `self`, descendant의 `parent-id`는 direct parent의 `brief-id`다.
|
|
168
|
+
|
|
169
|
+
## Recommended next phase
|
|
170
|
+
|
|
171
|
+
brief 본문 top blockquote의 `Recommended next phase:`에 쓴다.
|
|
172
|
+
|
|
173
|
+
- observable error, repro, stack trace, error-zip record: `error-analysis`
|
|
174
|
+
- ambiguity나 Open Questions가 큰 요구사항: `requirements-discovery`
|
|
175
|
+
- `scope: codebase`: `improvement-discovery`
|
|
176
|
+
- 애매하면 `requirements-discovery`
|
|
177
|
+
|
|
178
|
+
`okstra-run`을 자동으로 시작하지 않는다.
|
|
179
|
+
|
|
180
|
+
## Reporter Confirmations
|
|
181
|
+
|
|
182
|
+
`Open Questions`에서 reporter만 답할 수 있는 row를 모은다.
|
|
183
|
+
|
|
184
|
+
- `intent-check:`
|
|
185
|
+
- `conversion-block:`
|
|
186
|
+
|
|
187
|
+
이미 `[CONFIRMED <date> → RC-N]` marker가 있으면 pending에서 제외한다. 사용자에게 지금 답할지 묻고, 답하면 `## Reporter Confirmations`에 verbatim으로 기록한다. row는 삭제하지 않고 marker를 붙인다.
|
|
188
|
+
|
|
189
|
+
상태값:
|
|
190
|
+
|
|
191
|
+
- `complete`: pending reporter-only row가 모두 답변됨.
|
|
192
|
+
- `partial`: 일부만 답변됨.
|
|
193
|
+
- `skipped`: 사용자가 downstream phase에 넘기기로 함.
|
|
194
|
+
- `pending`: handoff 전 상태로 보고 진행하지 않는다.
|
|
195
|
+
|
|
196
|
+
## 검증
|
|
197
|
+
|
|
198
|
+
작성 후 handoff 메시지를 내기 전에 validator를 실행한다.
|
|
199
|
+
|
|
200
|
+
설치본:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
~/.okstra/lib/validators/validate-brief.sh "<PROJECT_ROOT>/.okstra/briefs" --briefs-root "<PROJECT_ROOT>/.okstra/briefs"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
repo checkout:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
validators/validate-brief.sh "<PROJECT_ROOT>/.okstra/briefs" --briefs-root "<PROJECT_ROOT>/.okstra/briefs"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
실패하면 cited brief를 고치고 재실행한다. validator가 없을 때만 manual checklist로 대체한다.
|
|
213
|
+
|
|
214
|
+
## 완료 메시지
|
|
215
|
+
|
|
216
|
+
단일 brief:
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
brief saved: <abs-path>
|
|
220
|
+
next: /okstra-run (recommended task-type: <phase>)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
multi-brief:
|
|
224
|
+
|
|
225
|
+
```text
|
|
226
|
+
briefs saved (N):
|
|
227
|
+
- <abs>/<task-group>/<brief>.md (depth 0, parent, recommended: <phase>)
|
|
228
|
+
- <abs>/<task-group>/sub/<brief>.md (depth 1, child, recommended: <phase>)
|
|
229
|
+
next: /okstra-run
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 금지 패턴
|
|
233
|
+
|
|
234
|
+
- Source Material을 요약하거나 정리해서 넣기.
|
|
235
|
+
- tracker/URL 내용을 도구 확인 없이 추측하기.
|
|
236
|
+
- unlabelled augmentation 작성하기.
|
|
237
|
+
- `intent-inference`를 `intent-check:` 없이 남기기.
|
|
238
|
+
- 외부 docs/ADR에 decision file을 쓰기. okstra decision은 `<PROJECT_ROOT>/.okstra/decisions/`에만 해당한다.
|
|
239
|
+
- child tree 전체를 silent overwrite하기.
|
|
240
|
+
- brief 생성 직후 자동으로 `okstra-run` 시작하기.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# okstra-container AI Manual
|
|
2
|
+
|
|
3
|
+
## 원천
|
|
4
|
+
|
|
5
|
+
- 스킬 원문: [`skills/okstra-container/SKILL.md`](../../../skills/okstra-container/SKILL.md)
|
|
6
|
+
- container CLI wrapper: [`src/commands/inspect/container.mjs`](../../../src/commands/inspect/container.mjs)
|
|
7
|
+
- container runtime: [`scripts/okstra_ctl/container.py`](../../../scripts/okstra_ctl/container.py)
|
|
8
|
+
- container registry: [`scripts/okstra_ctl/container_registry.py`](../../../scripts/okstra_ctl/container_registry.py)
|
|
9
|
+
- stage integration gate: [`scripts/okstra_ctl/stage_targets.py`](../../../scripts/okstra_ctl/stage_targets.py)
|
|
10
|
+
|
|
11
|
+
## 목적
|
|
12
|
+
|
|
13
|
+
`okstra-container`는 implementation task worktree의 `docker-compose.yml`을 이용해 사용자 테스트용 container group을 관리한다. okstra는 compose group에 task/run trace label을 붙이고, tmux watcher pane으로 로그/상태를 관찰한다.
|
|
14
|
+
|
|
15
|
+
## sub-command
|
|
16
|
+
|
|
17
|
+
| Sub-command | 역할 | side effect |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `up` | implementation stages를 task worktree에 통합하고 `docker compose up -d`, healthcheck poll, watcher pane attach | container 생성/시작, watcher pane 생성 |
|
|
20
|
+
| `status` | label query 기반 running container와 watcher metadata 확인 | 읽기 |
|
|
21
|
+
| `logs` | watcher findings dir와 watcher entries 안내 | 읽기 |
|
|
22
|
+
| `stop-watcher` | watcher/tail tmux panes만 회수 | container 유지, pane 제거 |
|
|
23
|
+
| `down` | label query로 container group 제거, orphan watcher panes 회수 | container 종료/제거 |
|
|
24
|
+
|
|
25
|
+
## Preflight
|
|
26
|
+
|
|
27
|
+
각각 별도 호출:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
okstra ensure-installed --runtime claude-code
|
|
31
|
+
okstra check-project --json
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
project setup이 없으면 `/okstra-setup` 안내 후 멈춘다. Docker daemon이 필요하다. Docker connection error가 나오면 Docker Desktop/daemon을 시작하라고 안내하고, 직접 Docker를 시작하지 않는다.
|
|
35
|
+
|
|
36
|
+
## task-key 해석
|
|
37
|
+
|
|
38
|
+
대부분 sub-command는 full task-key가 필요하다.
|
|
39
|
+
|
|
40
|
+
1. full task-key가 있으면 그대로 사용.
|
|
41
|
+
2. bare task-id는 resolver 사용:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
okstra resolve-task-key <task-id> --project-root <projectRoot> --json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
3. multiple match면 후보를 보여주고 선택 받는다.
|
|
48
|
+
4. `down --all`만 task-key 없이 실행할 수 있다.
|
|
49
|
+
|
|
50
|
+
## intent routing
|
|
51
|
+
|
|
52
|
+
명확한 동사:
|
|
53
|
+
|
|
54
|
+
- "띄워", "올려", "up": `up`
|
|
55
|
+
- "상태", "status": `status`
|
|
56
|
+
- "로그", "logs": `logs`
|
|
57
|
+
- "watcher 멈춰", "stop-watcher": `stop-watcher`
|
|
58
|
+
- "내려", "down", "종료": `down`
|
|
59
|
+
|
|
60
|
+
애매하면 full facet list를 보여주고 직접 입력 option을 둔다. 여러 facet이 한 메시지에 있으면 Step 0은 한 번만 실행하고 sub-command를 순차 실행한다.
|
|
61
|
+
|
|
62
|
+
## up
|
|
63
|
+
|
|
64
|
+
실행:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
okstra container up --project-root <projectRoot> --task-key <task-key>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
전제:
|
|
71
|
+
|
|
72
|
+
- task는 implementation worktree가 registry에 있어야 한다.
|
|
73
|
+
- worktree root에 `docker-compose.yml`이 있어야 한다.
|
|
74
|
+
- approved plan의 모든 stage가 `done`이어야 한다. partial stage 상태를 완성 task처럼 deploy하지 않는다.
|
|
75
|
+
|
|
76
|
+
실패 메시지 처리:
|
|
77
|
+
|
|
78
|
+
- registry에 task worktree가 없다는 메시지: implementation phase를 먼저 실행하라고 말한다.
|
|
79
|
+
- compose file 없음: CLI 메시지를 그대로 보여준다.
|
|
80
|
+
- `final-verification(whole-task): stage N not done`: 해당 stage를 implementation으로 끝내야 한다고 말한다.
|
|
81
|
+
- healthcheck 실패: failing service와 CLI가 제공한 `docker compose ... logs` line을 그대로 전달한다.
|
|
82
|
+
|
|
83
|
+
성공하면 stdout JSON을 파싱해 services, watcher pane, published ports를 요약한다. 이후 관리는 `okstra container status <task-key>`와 `down <task-key>`로 한다고 안내한다.
|
|
84
|
+
|
|
85
|
+
## status
|
|
86
|
+
|
|
87
|
+
실행:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
okstra container status --project-root <projectRoot> --task-key <task-key>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
stdout JSON:
|
|
94
|
+
|
|
95
|
+
- `projectName`: compose project name
|
|
96
|
+
- `containers`: run-trace label로 찾은 running containers
|
|
97
|
+
- `watchers`: registry의 watcher metadata
|
|
98
|
+
|
|
99
|
+
alive 여부는 `containers` label query가 authoritative다. watcher registry는 lag할 수 있다. `containers`가 비어 있으면 group이 실행 중이 아니라고 말하고 `up`을 제안한다.
|
|
100
|
+
|
|
101
|
+
## logs
|
|
102
|
+
|
|
103
|
+
실행:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
okstra container logs --project-root <projectRoot> --task-key <task-key>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
service scope:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
okstra container logs --project-root <projectRoot> --task-key <task-key> --service <service>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
stdout JSON의 `watchersDir`, `watchers`를 보여준다. live stream은 file이 아니라 tmux watcher pane에 있다. raw compose logs가 필요하면 `status`에서 `projectName`을 확인한 뒤 사용자가 `docker compose -p <projectName> logs -f <service>`를 실행할 수 있다고 안내한다.
|
|
116
|
+
|
|
117
|
+
## stop-watcher
|
|
118
|
+
|
|
119
|
+
실행:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
okstra container stop-watcher --project-root <projectRoot> --task-key <task-key>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
watcher/tail panes만 제거하고 containers는 유지한다. stdout JSON의 `reapedPanes`, `note`를 요약한다. 사용자가 containers까지 내리려는 의도면 `down`으로 라우팅한다.
|
|
126
|
+
|
|
127
|
+
## down
|
|
128
|
+
|
|
129
|
+
단일 task:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
okstra container down --project-root <projectRoot> --task-key <task-key>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
프로젝트 전체:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
okstra container down --project-root <projectRoot> --all
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
단일 task down은 task-key 해석 후 실행해도 된다. `--all`은 프로젝트의 모든 okstra container group을 내리므로 실행 전 사용자 확인을 받는다.
|
|
142
|
+
|
|
143
|
+
stdout JSON의 `downed`, `orphanPanesReaped`를 보고한다. 각 `projectName`과 회수된 panes를 표시한다.
|
|
144
|
+
|
|
145
|
+
## 출력 규칙
|
|
146
|
+
|
|
147
|
+
- stdout JSON이 source of truth다.
|
|
148
|
+
- raw `docker` 명령으로 second-guess하지 않는다. CLI가 실패했고 사용자가 manual fallback을 요청한 경우만 예외다.
|
|
149
|
+
- resolved task-key를 heading이나 첫 줄에 표시한다.
|
|
150
|
+
- CLI failure message는 remediation line을 포함해 그대로 보여준다.
|
|
151
|
+
- container/service state는 JSON 값을 normalize하지 않고 보여준다.
|
|
152
|
+
|
|
153
|
+
## 금지 패턴
|
|
154
|
+
|
|
155
|
+
- Docker daemon을 직접 시작하려고 하기.
|
|
156
|
+
- `up` 실패 원인을 추측해서 compose를 수정하기.
|
|
157
|
+
- partial stage task를 deploy 가능한 것으로 포장하기.
|
|
158
|
+
- watcher registry만 보고 container alive라고 판단하기.
|
|
159
|
+
- `down --all`을 사용자 확인 없이 실행하기.
|
|
160
|
+
- raw docker query로 CLI 결과를 임의로 덮어쓰기.
|
|
161
|
+
|