okstra 0.92.1 → 0.93.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/docs/superpowers/plans/2026-06-19-agent-operating-standard.md +476 -0
- package/docs/superpowers/specs/2026-06-19-agent-operating-standard-design.md +120 -0
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/prompts/lead/okstra-lead-contract.md +10 -0
- package/runtime/prompts/profiles/_implementation-executor.md +3 -0
- package/runtime/prompts/profiles/_implementation-self-check.md +19 -0
- package/runtime/prompts/profiles/_implementation-verifier.md +4 -0
- package/runtime/prompts/wizard/prompts.ko.json +4 -4
- package/runtime/python/okstra_ctl/codex_dispatch.py +11 -4
- package/runtime/python/okstra_ctl/wizard.py +14 -2
- package/runtime/templates/operating-standard.md +22 -0
- package/runtime/templates/worker-prompt-preamble.md +10 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
# 에이전트 작업 자세(Operating Standard) 주입 — 구현 계획
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** 전 okstra 에이전트에 공통 "작업 자세" 행동 규약을 주입하고, 코드 작성 워커(executor)에 완료 전 자기검증 게이트를 추가한다.
|
|
6
|
+
|
|
7
|
+
**Architecture:** 공통 코어를 `templates/operating-standard.md` SSOT 한 곳에 두고, 워커 preamble·리드 contract 가 그 코어를 verbatim 인라인한다(앵커 추가-read 없음 — 토큰 절약). 단위 테스트가 인라인 사본이 SSOT 와 일치하는지 검증해 drift 를 막는다. 코드 워커 완료 전 게이트는 별도 sidecar `_implementation-self-check.md` 로 신설하고, 기존 preflight 와 동일한 전달 경로(Claude executor 직접 read / codex·antigravity executor 는 lead 가 dispatch 프롬프트에 body append)를 탄다.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Markdown 프롬프트/계약 파일, Python(`scripts/okstra_ctl/codex_dispatch.py`), pytest, `tools/build.mjs`(소스→runtime 복사).
|
|
10
|
+
|
|
11
|
+
## Global Constraints
|
|
12
|
+
|
|
13
|
+
- 공통 코어는 **영어**, 6줄 이내(헤더 1문장 + 불릿 5개). 톤은 기존 preamble 의 간결 명령형.
|
|
14
|
+
- 단일 참조점: SSOT 는 `templates/operating-standard.md`. preamble·contract 인라인은 SSOT 의 코어 블록과 **문자 그대로 일치**해야 한다(테스트로 강제).
|
|
15
|
+
- 앵커 추가-read 금지(워커가 파일을 하나 더 읽게 만들지 않는다).
|
|
16
|
+
- `runtime/` 직접 수정 금지 — `npm run build` 로만 동기화.
|
|
17
|
+
- 새/수정 함수는 50 effective lines 이하.
|
|
18
|
+
- 정체성/경력 서사형 페르소나 문구 금지(형용사를 행동 동사로만).
|
|
19
|
+
- 문서/CHANGES 산문은 한국어, 코드 식별자·경로·CLI 플래그는 영어.
|
|
20
|
+
- 테스트 repo 루트 helper: `REPO = pathlib.Path(__file__).resolve().parents[1]`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### Task 1: 공통 자세 SSOT 파일 신설
|
|
25
|
+
|
|
26
|
+
**Files:**
|
|
27
|
+
- Create: `templates/operating-standard.md`
|
|
28
|
+
- Test: `tests/test_operating_standard.py`
|
|
29
|
+
|
|
30
|
+
**Interfaces:**
|
|
31
|
+
- Produces: SSOT 파일. 이후 Task 2·3 가 이 파일의 "## Common core" 블록을 verbatim 인라인하고, Task 4 테스트가 일치를 검증한다.
|
|
32
|
+
|
|
33
|
+
- [ ] **Step 1: 실패하는 테스트 작성**
|
|
34
|
+
|
|
35
|
+
`tests/test_operating_standard.py`:
|
|
36
|
+
```python
|
|
37
|
+
import pathlib
|
|
38
|
+
|
|
39
|
+
REPO = pathlib.Path(__file__).resolve().parents[1]
|
|
40
|
+
SSOT = REPO / "templates" / "operating-standard.md"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _core_block(text: str) -> str:
|
|
44
|
+
"""## Common core 헤딩 다음부터 다음 ## 헤딩 전까지의 본문(앞뒤 공백 제거)."""
|
|
45
|
+
after = text.split("## Common core", 1)[1]
|
|
46
|
+
return after.split("\n## ", 1)[0].strip()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_ssot_exists_with_core_and_addenda():
|
|
50
|
+
text = SSOT.read_text(encoding="utf-8")
|
|
51
|
+
core = _core_block(text)
|
|
52
|
+
assert "Evidence over assertion" in core
|
|
53
|
+
assert "Shortest sound path" in core
|
|
54
|
+
assert "Fit what's here" in core
|
|
55
|
+
assert "Hold your own line" in text # 워커 독립성 addendum
|
|
56
|
+
assert "Own the synthesis" in text # 리드 종합 addendum
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- [ ] **Step 2: 테스트 실패 확인**
|
|
60
|
+
|
|
61
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_ssot_exists_with_core_and_addenda -v`
|
|
62
|
+
Expected: FAIL — `FileNotFoundError` (SSOT 파일 없음)
|
|
63
|
+
|
|
64
|
+
- [ ] **Step 3: SSOT 파일 작성**
|
|
65
|
+
|
|
66
|
+
`templates/operating-standard.md`:
|
|
67
|
+
```markdown
|
|
68
|
+
# Operating Standard (canonical)
|
|
69
|
+
|
|
70
|
+
This file is the single source of truth for the operating standard injected into
|
|
71
|
+
every okstra agent. The "## Common core" block below is inlined verbatim into
|
|
72
|
+
`templates/worker-prompt-preamble.md` (workers) and
|
|
73
|
+
`prompts/lead/okstra-lead-contract.md` (lead). A unit test asserts both inlined
|
|
74
|
+
copies match this core — update all three together.
|
|
75
|
+
|
|
76
|
+
## Common core
|
|
77
|
+
|
|
78
|
+
Work like a senior engineer who owns this result, not a commentator on it.
|
|
79
|
+
- Evidence over assertion — back every claim with a file:line, or mark it an explicit assumption. Never state the unverified as fact.
|
|
80
|
+
- Read before you reason — read each required input end to end; when you lack basis, write "insufficient evidence" instead of filling the gap plausibly.
|
|
81
|
+
- Shortest sound path — chase the most likely cause first; don't re-verify what is settled or pad with restatement.
|
|
82
|
+
- Decide, don't survey — when options exist, give the trade-off and one recommendation, not an exhaustive list.
|
|
83
|
+
- Fit what's here — match the surrounding code and prose; size the response to the request.
|
|
84
|
+
|
|
85
|
+
## Role addendum
|
|
86
|
+
|
|
87
|
+
- Analysis / verification workers add this line: `Hold your own line — reason from your independent angle; do not drift toward the other workers' likely answers or echo the user. Triangulation fails if your view isn't genuinely yours.`
|
|
88
|
+
- Lead adds this line: `Own the synthesis — weigh worker outputs on evidence, not consensus; a better-grounded dissent outranks the majority.`
|
|
89
|
+
- Report-writer worker: common core only (no independence addendum — it authors, it does not analyze).
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- [ ] **Step 4: 테스트 통과 확인**
|
|
93
|
+
|
|
94
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_ssot_exists_with_core_and_addenda -v`
|
|
95
|
+
Expected: PASS
|
|
96
|
+
|
|
97
|
+
- [ ] **Step 5: 커밋**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
git add templates/operating-standard.md tests/test_operating_standard.py
|
|
101
|
+
git commit -m "feat(agents): operating-standard SSOT 신설"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### Task 2: 워커 preamble 에 공통 코어 + 독립성 인라인
|
|
107
|
+
|
|
108
|
+
**Files:**
|
|
109
|
+
- Modify: `templates/worker-prompt-preamble.md` (헤더 직후, `## Required reading` 앞)
|
|
110
|
+
- Test: `tests/test_operating_standard.py`
|
|
111
|
+
|
|
112
|
+
**Interfaces:**
|
|
113
|
+
- Consumes: Task 1 의 `## Common core` 블록(verbatim).
|
|
114
|
+
- Produces: 워커가 출력 전 마주치는 자세 헤더. 모든 분석/검증 워커에 적용.
|
|
115
|
+
|
|
116
|
+
- [ ] **Step 1: 실패하는 테스트 추가**
|
|
117
|
+
|
|
118
|
+
`tests/test_operating_standard.py` 에 추가:
|
|
119
|
+
```python
|
|
120
|
+
PREAMBLE = REPO / "templates" / "worker-prompt-preamble.md"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_core_inlined_in_preamble():
|
|
124
|
+
core = _core_block(SSOT.read_text(encoding="utf-8"))
|
|
125
|
+
preamble = PREAMBLE.read_text(encoding="utf-8")
|
|
126
|
+
assert core in preamble # 코어 verbatim 일치(drift 차단)
|
|
127
|
+
assert "Hold your own line" in preamble # 워커 독립성 addendum
|
|
128
|
+
assert "Own the synthesis" not in preamble # 리드 전용 줄은 없어야
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- [ ] **Step 2: 테스트 실패 확인**
|
|
132
|
+
|
|
133
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_core_inlined_in_preamble -v`
|
|
134
|
+
Expected: FAIL — `assert core in preamble` (아직 인라인 안 됨)
|
|
135
|
+
|
|
136
|
+
- [ ] **Step 3: preamble 수정**
|
|
137
|
+
|
|
138
|
+
`templates/worker-prompt-preamble.md` 의 5번째 줄(`It replaces the previous practice ...` 문단) 다음, `---` 구분선 앞에 아래 섹션을 삽입한다. `## Common core` 의 본문(Step 3 Task 1 의 `Work like a senior engineer ...` ~ `... size the response to the request.` 5불릿)을 verbatim 복사한다:
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
|
|
142
|
+
## Operating standard (read before any output)
|
|
143
|
+
|
|
144
|
+
Work like a senior engineer who owns this result, not a commentator on it.
|
|
145
|
+
- Evidence over assertion — back every claim with a file:line, or mark it an explicit assumption. Never state the unverified as fact.
|
|
146
|
+
- Read before you reason — read each required input end to end; when you lack basis, write "insufficient evidence" instead of filling the gap plausibly.
|
|
147
|
+
- Shortest sound path — chase the most likely cause first; don't re-verify what is settled or pad with restatement.
|
|
148
|
+
- Decide, don't survey — when options exist, give the trade-off and one recommendation, not an exhaustive list.
|
|
149
|
+
- Fit what's here — match the surrounding code and prose; size the response to the request.
|
|
150
|
+
- Hold your own line — reason from your independent angle; do not drift toward the other workers' likely answers or echo the user. Triangulation fails if your view isn't genuinely yours.
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
> 주의: `_core_block` 비교는 SSOT 의 코어 본문(5불릿)이 substring 으로 들어있는지 보므로, 여기서 5불릿은 SSOT 와 한 글자도 다르면 안 된다. 독립성 줄은 코어 다음에 별도 불릿으로 붙인다.
|
|
154
|
+
|
|
155
|
+
- [ ] **Step 4: 테스트 통과 확인**
|
|
156
|
+
|
|
157
|
+
Run: `python3 -m pytest tests/test_operating_standard.py -v`
|
|
158
|
+
Expected: PASS (Task 1·2 테스트 모두)
|
|
159
|
+
|
|
160
|
+
- [ ] **Step 5: 커밋**
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
git add templates/worker-prompt-preamble.md tests/test_operating_standard.py
|
|
164
|
+
git commit -m "feat(agents): 워커 preamble 에 작업 자세 + 독립성 인라인"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### Task 3: 리드 contract 에 공통 코어 + 종합 인라인
|
|
170
|
+
|
|
171
|
+
**Files:**
|
|
172
|
+
- Modify: `prompts/lead/okstra-lead-contract.md` (`# Okstra Lead Contract` 직후, `## Overview` 앞)
|
|
173
|
+
- Test: `tests/test_operating_standard.py`
|
|
174
|
+
|
|
175
|
+
**Interfaces:**
|
|
176
|
+
- Consumes: Task 1 의 `## Common core` 블록(verbatim).
|
|
177
|
+
- Produces: 리드가 오케스트레이션 전 마주치는 자세 헤더.
|
|
178
|
+
|
|
179
|
+
- [ ] **Step 1: 실패하는 테스트 추가**
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
CONTRACT = REPO / "prompts" / "lead" / "okstra-lead-contract.md"
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def test_core_inlined_in_lead_contract():
|
|
186
|
+
core = _core_block(SSOT.read_text(encoding="utf-8"))
|
|
187
|
+
contract = CONTRACT.read_text(encoding="utf-8")
|
|
188
|
+
assert core in contract
|
|
189
|
+
assert "Own the synthesis" in contract # 리드 종합 addendum
|
|
190
|
+
assert "Hold your own line" not in contract # 워커 전용 줄은 없어야
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- [ ] **Step 2: 테스트 실패 확인**
|
|
194
|
+
|
|
195
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_core_inlined_in_lead_contract -v`
|
|
196
|
+
Expected: FAIL — `assert core in contract`
|
|
197
|
+
|
|
198
|
+
- [ ] **Step 3: contract 수정**
|
|
199
|
+
|
|
200
|
+
`prompts/lead/okstra-lead-contract.md` 의 `# Okstra Lead Contract` 줄 다음, `## Overview` 앞에 삽입(코어 5불릿 verbatim + 리드 종합 줄):
|
|
201
|
+
|
|
202
|
+
```markdown
|
|
203
|
+
|
|
204
|
+
## Operating standard
|
|
205
|
+
|
|
206
|
+
Work like a senior engineer who owns this result, not a commentator on it.
|
|
207
|
+
- Evidence over assertion — back every claim with a file:line, or mark it an explicit assumption. Never state the unverified as fact.
|
|
208
|
+
- Read before you reason — read each required input end to end; when you lack basis, write "insufficient evidence" instead of filling the gap plausibly.
|
|
209
|
+
- Shortest sound path — chase the most likely cause first; don't re-verify what is settled or pad with restatement.
|
|
210
|
+
- Decide, don't survey — when options exist, give the trade-off and one recommendation, not an exhaustive list.
|
|
211
|
+
- Fit what's here — match the surrounding code and prose; size the response to the request.
|
|
212
|
+
- Own the synthesis — weigh worker outputs on evidence, not consensus; a better-grounded dissent outranks the majority.
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
- [ ] **Step 4: 테스트 통과 확인**
|
|
216
|
+
|
|
217
|
+
Run: `python3 -m pytest tests/test_operating_standard.py -v`
|
|
218
|
+
Expected: PASS
|
|
219
|
+
|
|
220
|
+
- [ ] **Step 5: 커밋**
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
git add prompts/lead/okstra-lead-contract.md tests/test_operating_standard.py
|
|
224
|
+
git commit -m "feat(agents): 리드 contract 에 작업 자세 + 종합 인라인"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
### Task 4: 완료 전 자기검증 게이트 sidecar 신설
|
|
230
|
+
|
|
231
|
+
**Files:**
|
|
232
|
+
- Create: `prompts/profiles/_implementation-self-check.md`
|
|
233
|
+
- Test: `tests/test_operating_standard.py`
|
|
234
|
+
|
|
235
|
+
**Interfaces:**
|
|
236
|
+
- Produces: 완료 전 게이트 본문. Task 5(executor/verifier 참조)·Task 6(codex_dispatch append)이 이 파일을 사용한다.
|
|
237
|
+
|
|
238
|
+
- [ ] **Step 1: 실패하는 테스트 추가**
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
SELFCHECK = REPO / "prompts" / "profiles" / "_implementation-self-check.md"
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def test_self_check_gate_has_four_items():
|
|
245
|
+
text = SELFCHECK.read_text(encoding="utf-8")
|
|
246
|
+
assert "Implementation self-check" in text
|
|
247
|
+
for item in ("functions:", "conventions:", "names & comments:", "verification:"):
|
|
248
|
+
assert item in text
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
- [ ] **Step 2: 테스트 실패 확인**
|
|
252
|
+
|
|
253
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_self_check_gate_has_four_items -v`
|
|
254
|
+
Expected: FAIL — `FileNotFoundError`
|
|
255
|
+
|
|
256
|
+
- [ ] **Step 3: sidecar 작성**
|
|
257
|
+
|
|
258
|
+
`prompts/profiles/_implementation-self-check.md`:
|
|
259
|
+
```markdown
|
|
260
|
+
<!--
|
|
261
|
+
Completion-time counterpart to _coding-conventions-preflight.md. The preflight
|
|
262
|
+
gate runs BEFORE the first Edit/Write; this gate runs BEFORE the executor claims
|
|
263
|
+
done. Same delivery paths: Claude executor reads this file directly; codex /
|
|
264
|
+
antigravity executor cannot read it (outside the CLI sandbox), so the lead
|
|
265
|
+
appends this file's body into the persisted executor prompt at dispatch time
|
|
266
|
+
(see codex_dispatch.py `_implementation_executor_tail`).
|
|
267
|
+
-->
|
|
268
|
+
|
|
269
|
+
# Implementation self-check (BLOCKING — before you claim done)
|
|
270
|
+
|
|
271
|
+
Before declaring the change complete, write one confirming line per item to your
|
|
272
|
+
audit sidecar. If any item fails, fix it or surface the violation — do not claim
|
|
273
|
+
done on a failing item.
|
|
274
|
+
|
|
275
|
+
- functions: every new/edited function ≤50 effective lines, single purpose
|
|
276
|
+
- conventions: applied the routed pack + project patterns (name which ones)
|
|
277
|
+
- names & comments: names say what, comments say why; no obvious-restatement comments; no truthful-name violations
|
|
278
|
+
- verification: ran the actual build/test (paste the command + its result); no dead or commented-out code left behind
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
- [ ] **Step 4: 테스트 통과 확인**
|
|
282
|
+
|
|
283
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_self_check_gate_has_four_items -v`
|
|
284
|
+
Expected: PASS
|
|
285
|
+
|
|
286
|
+
- [ ] **Step 5: 커밋**
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
git add prompts/profiles/_implementation-self-check.md tests/test_operating_standard.py
|
|
290
|
+
git commit -m "feat(agents): 완료 전 자기검증 게이트 sidecar 신설"
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
### Task 5: executor/verifier 프로필에 self-check 참조 배선
|
|
296
|
+
|
|
297
|
+
**Files:**
|
|
298
|
+
- Modify: `prompts/profiles/_implementation-executor.md` (preflight 불릿 다음에 self-check 불릿 추가)
|
|
299
|
+
- Modify: `prompts/profiles/_implementation-verifier.md` (코드 수정 시 동일 게이트 적용 declaration)
|
|
300
|
+
- Test: `tests/test_operating_standard.py`
|
|
301
|
+
|
|
302
|
+
**Interfaces:**
|
|
303
|
+
- Consumes: Task 4 의 `_implementation-self-check.md`.
|
|
304
|
+
- Produces: executor 가 done 전 게이트를 read/append 하도록 지시하는 계약. codex/antigravity 경로는 Task 6 가 물리적으로 append.
|
|
305
|
+
|
|
306
|
+
- [ ] **Step 1: 실패하는 테스트 추가**
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
EXECUTOR = REPO / "prompts" / "profiles" / "_implementation-executor.md"
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def test_executor_references_self_check_gate():
|
|
313
|
+
text = EXECUTOR.read_text(encoding="utf-8")
|
|
314
|
+
assert "_implementation-self-check.md" in text
|
|
315
|
+
assert "before" in text.lower() and "done" in text.lower()
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
- [ ] **Step 2: 테스트 실패 확인**
|
|
319
|
+
|
|
320
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_executor_references_self_check_gate -v`
|
|
321
|
+
Expected: FAIL — `assert "_implementation-self-check.md" in text`
|
|
322
|
+
|
|
323
|
+
- [ ] **Step 3: executor 프로필 수정**
|
|
324
|
+
|
|
325
|
+
`prompts/profiles/_implementation-executor.md` 의 Coding-conventions preflight 불릿(line 22~24 블록) **다음**에 아래 불릿을 추가한다. 문구는 preflight 불릿의 전달-경로 표현을 그대로 따른다:
|
|
326
|
+
|
|
327
|
+
```markdown
|
|
328
|
+
- **Completion self-check (BLOCKING — runs BEFORE you claim the stage done).** The gate body is a single source at `prompts/profiles/_implementation-self-check.md` (sibling of this sidecar): the four-item completion gate (functions ≤50 lines, conventions applied, truthful names & why-comments, real build/test run). Do NOT re-type it from memory — deliver it by file so it cannot drift.
|
|
329
|
+
- **Claude executor:** Read `_implementation-self-check.md` end-to-end before appending the `status:"done"` row, then write one confirming line per item to your audit sidecar.
|
|
330
|
+
- **CLI executor (codex / antigravity):** the CLI process cannot Read this path (outside its sandbox). The lead appends this file's body into the persisted executor prompt at dispatch time, immediately after the preflight body (see `codex_dispatch.py` `_implementation_executor_tail`). The head-less executor honours both gates from the single prompt.
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
- [ ] **Step 4: verifier 프로필 수정**
|
|
334
|
+
|
|
335
|
+
`prompts/profiles/_implementation-verifier.md` 끝부분에 declaration 한 줄 추가(verifier 는 보통 코드를 수정하지 않으나, 수정하는 경우 동일 게이트가 바인딩됨을 명시):
|
|
336
|
+
|
|
337
|
+
```markdown
|
|
338
|
+
- **Completion self-check (declaration).** If this verifier edits project code (not just inspects it), the same completion gate at `prompts/profiles/_implementation-self-check.md` binds before claiming done — same four items, recorded in the audit sidecar.
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
- [ ] **Step 5: 테스트 통과 확인**
|
|
342
|
+
|
|
343
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_executor_references_self_check_gate -v`
|
|
344
|
+
Expected: PASS
|
|
345
|
+
|
|
346
|
+
- [ ] **Step 6: 커밋**
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
git add prompts/profiles/_implementation-executor.md prompts/profiles/_implementation-verifier.md tests/test_operating_standard.py
|
|
350
|
+
git commit -m "feat(agents): executor/verifier 에 완료 전 self-check 배선"
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
### Task 6: codex_dispatch 가 self-check body 를 CLI 프롬프트에 append
|
|
356
|
+
|
|
357
|
+
**Files:**
|
|
358
|
+
- Modify: `scripts/okstra_ctl/codex_dispatch.py:802-812` (`_implementation_executor_tail`)
|
|
359
|
+
- Test: `tests/test_operating_standard.py`
|
|
360
|
+
|
|
361
|
+
**Interfaces:**
|
|
362
|
+
- Consumes: Task 4 의 `_implementation-self-check.md`.
|
|
363
|
+
- Produces: codex/antigravity executor 의 persisted 프롬프트 tail 에 preflight body + self-check body 가 순서대로 포함.
|
|
364
|
+
|
|
365
|
+
- [ ] **Step 1: 실패하는 테스트 추가**
|
|
366
|
+
|
|
367
|
+
`_implementation_executor_tail` 은 `workspace_root` 의 `prompts/profiles/` 를 읽으므로, repo 자체를 workspace_root 로 준다. 최소 manifest 는 `taskType` 만 필요(`_require_string(manifest, "taskType")`).
|
|
368
|
+
```python
|
|
369
|
+
from scripts.okstra_ctl import codex_dispatch
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def test_executor_tail_includes_both_gates():
|
|
373
|
+
tail = codex_dispatch._implementation_executor_tail(
|
|
374
|
+
{"taskType": "implementation"}, REPO, "executor"
|
|
375
|
+
)
|
|
376
|
+
assert "Coding-conventions preflight" in tail # 기존 preflight 유지
|
|
377
|
+
assert "Implementation self-check" in tail # 신규 self-check 추가
|
|
378
|
+
```
|
|
379
|
+
> import 경로는 기존 codex_dispatch 테스트(`tests/test_*dispatch*.py`)의 import 방식을 따른다. 없으면 `importlib`로 `scripts/okstra_ctl/codex_dispatch.py`를 로드한다.
|
|
380
|
+
|
|
381
|
+
- [ ] **Step 2: 테스트 실패 확인**
|
|
382
|
+
|
|
383
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_executor_tail_includes_both_gates -v`
|
|
384
|
+
Expected: FAIL — `assert "Implementation self-check" in tail` (아직 self-check 미append)
|
|
385
|
+
|
|
386
|
+
- [ ] **Step 3: `_implementation_executor_tail` 수정**
|
|
387
|
+
|
|
388
|
+
`scripts/okstra_ctl/codex_dispatch.py` 의 함수를 아래로 교체(preflight 뒤에 self-check body 를 이어붙임, 50줄 이내 유지):
|
|
389
|
+
```python
|
|
390
|
+
def _implementation_executor_tail(
|
|
391
|
+
manifest: Mapping[str, Any],
|
|
392
|
+
workspace_root: Path,
|
|
393
|
+
role: str,
|
|
394
|
+
) -> str:
|
|
395
|
+
if role != "executor" or _require_string(manifest, "taskType") != "implementation":
|
|
396
|
+
return ""
|
|
397
|
+
profiles = workspace_root / "prompts" / "profiles"
|
|
398
|
+
parts: list[str] = []
|
|
399
|
+
preflight_path = profiles / "_coding-conventions-preflight.md"
|
|
400
|
+
if preflight_path.is_file():
|
|
401
|
+
parts.append(preflight_path.read_text(encoding="utf-8"))
|
|
402
|
+
else:
|
|
403
|
+
parts.append("# Coding-conventions preflight\n\nApply project-local conventions before editing.")
|
|
404
|
+
selfcheck_path = profiles / "_implementation-self-check.md"
|
|
405
|
+
if selfcheck_path.is_file():
|
|
406
|
+
parts.append(selfcheck_path.read_text(encoding="utf-8"))
|
|
407
|
+
return "\n\n".join(parts)
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
- [ ] **Step 4: 테스트 통과 확인**
|
|
411
|
+
|
|
412
|
+
Run: `python3 -m pytest tests/test_operating_standard.py::test_executor_tail_includes_both_gates -v`
|
|
413
|
+
Expected: PASS
|
|
414
|
+
|
|
415
|
+
- [ ] **Step 5: 커밋**
|
|
416
|
+
|
|
417
|
+
```bash
|
|
418
|
+
git add scripts/okstra_ctl/codex_dispatch.py tests/test_operating_standard.py
|
|
419
|
+
git commit -m "feat(agents): CLI executor 프롬프트에 self-check body append"
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
### Task 7: 빌드·전체 검증·CHANGES 기록
|
|
425
|
+
|
|
426
|
+
**Files:**
|
|
427
|
+
- Modify: `CHANGES.md` (최상단 날짜 섹션)
|
|
428
|
+
- (build output) `runtime/`
|
|
429
|
+
|
|
430
|
+
- [ ] **Step 1: 빌드(소스→runtime 동기화)**
|
|
431
|
+
|
|
432
|
+
Run: `npm run build`
|
|
433
|
+
Expected: `BUILD OK` 류 출력, 에러 없음. 새 파일(`operating-standard.md`, `_implementation-self-check.md`)이 `runtime/` 로 복사됨.
|
|
434
|
+
|
|
435
|
+
- [ ] **Step 2: runtime 동기화 확인**
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
grep -rl "Operating Standard (canonical)" runtime/ | head
|
|
439
|
+
grep -rl "Implementation self-check" runtime/ | head
|
|
440
|
+
```
|
|
441
|
+
Expected: 각각 runtime 하위 경로가 출력됨.
|
|
442
|
+
|
|
443
|
+
- [ ] **Step 3: 전체 테스트 + 워크플로 검증**
|
|
444
|
+
|
|
445
|
+
Run:
|
|
446
|
+
```bash
|
|
447
|
+
python3 -m pytest tests/ -q
|
|
448
|
+
bash validators/validate-workflow.sh
|
|
449
|
+
```
|
|
450
|
+
Expected: 전체 PASS, validator 통과.
|
|
451
|
+
|
|
452
|
+
- [ ] **Step 4: CHANGES.md 기록**
|
|
453
|
+
|
|
454
|
+
`CHANGES.md` 최상단에 `## 2026-06-19` 섹션이 이미 있으면 그 아래, 없으면 새로 추가하여 항목 작성:
|
|
455
|
+
```markdown
|
|
456
|
+
### feat(agents): 전 에이전트 공통 '작업 자세' + 코드 워커 완료 전 자기검증 게이트
|
|
457
|
+
|
|
458
|
+
- **배경**: 모든 okstra 에이전트의 출력 품질·태도·일관성·코드 작성 품질을 끌어올리고 싶었다. 코드 품질 규약(함수 50줄·정직한 이름·패턴 적용·증거 기반 완료)은 이미 존재했으므로, 문제는 규약 부재가 아니라 이행이었다.
|
|
459
|
+
- **해결**: 형용사를 검증 가능한 행동으로 번역한 공통 '작업 자세' 코어를 `templates/operating-standard.md` SSOT 로 두고, 워커 preamble·리드 contract 에 verbatim 인라인했다(테스트로 drift 차단). 워커는 독립성 한 줄, 리드는 근거 기반 종합 한 줄을 덧붙여 cross-verification 의 관점 다양성을 보존한다. 코드 워커에는 시작 전 preflight 의 짝인 완료 전 자기검증 게이트(`_implementation-self-check.md`)를 추가해, executor 가 done 선언 전 함수 길이·패턴·네이밍·실제 검증을 audit 사이드카에 한 줄씩 확정하게 했다(codex/antigravity 는 lead 가 프롬프트에 append).
|
|
460
|
+
- 사용자 영향: okstra-run 의 분석·구현·검증 전 단계에서 에이전트가 더 일관되게 증거 기반으로 답하고, 코드 작성 결과가 '검증 없이 완료 선언'·'함수 비대'·'패턴 무시' 없이 나오도록 자기검증을 강제한다. (설치 환경은 `okstra install` 로 런타임 갱신 후 적용.)
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
- [ ] **Step 5: 커밋**
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
git add CHANGES.md runtime/
|
|
467
|
+
git commit -m "chore(agents): operating-standard 빌드 동기화 + CHANGES 기록"
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## Self-Review (작성자 체크)
|
|
473
|
+
|
|
474
|
+
- **Spec coverage**: §4.1 공통 헤더→Task 1·2·3 / §4.2 역할 분기→Task 2(워커)·3(리드)·1(report-writer 명시) / §4.3 완료 전 게이트→Task 4·5·6 / §4.4 단일 참조점·주입 지점→Task 1(SSOT)·2·3(인라인)·6(append) / §5 검증→각 Task 테스트 + Task 7. 누락 없음.
|
|
475
|
+
- **Placeholder scan**: 모든 코드/문구 블록은 실제 내용. TBD/TODO 없음.
|
|
476
|
+
- **Type consistency**: 테스트 helper `_core_block`·상수(`SSOT`/`PREAMBLE`/`CONTRACT`/`SELFCHECK`/`EXECUTOR`)는 Task 1 에서 정의 후 재사용, 함수 시그니처 `_implementation_executor_tail(manifest, workspace_root, role)` 는 현재 코드와 일치.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# 에이전트 작업 자세(Operating Standard) 주입 설계
|
|
2
|
+
|
|
3
|
+
- 날짜: 2026-06-19
|
|
4
|
+
- 상태: 설계 승인 대기
|
|
5
|
+
- 범위: okstra 전 에이전트(분석 워커 / executor·verifier / report-writer / 리드)에 공통 "작업 자세" 행동 규약을 주입하고, 코드 작성 워커에 완료 전 자기검증 게이트를 추가한다.
|
|
6
|
+
|
|
7
|
+
## 1. 배경과 목적
|
|
8
|
+
|
|
9
|
+
사용자가 모든 okstra 에이전트에 "노련하고 효율적이고 성실하고 전문가스러운" 태도를 주입하길 원했다. 출력에서 아쉬웠던 점은 깊이·정확도, 태도·성의, 일관성, 장황함, 그리고 특히 **코드 작성 품질**(함수 길이/복잡, 프로젝트 패턴 무시, 주석·네이밍 부실, 검증 없이 완료 선언) 전반이었다.
|
|
10
|
+
|
|
11
|
+
## 2. 핵심 통찰 — "규약 부재"가 아니라 "이행 부재"
|
|
12
|
+
|
|
13
|
+
사용자가 지목한 코드 품질 4개는 **이미 규약에 전부 존재**한다:
|
|
14
|
+
|
|
15
|
+
- 함수 50줄 상한 → 글로벌 `CLAUDE.md` 4.5, [_coding-conventions-preflight.md](../../../prompts/profiles/_coding-conventions-preflight.md) "single-purpose functions ≤50 effective lines"
|
|
16
|
+
- 프로젝트 패턴 따르기 → `CLAUDE.md` 3.1, preflight 의 routed pack + project review packs
|
|
17
|
+
- 이름=무엇 / 주석=왜 → `CLAUDE.md` 4.1, preflight 의 "truthful names"
|
|
18
|
+
- 증거 기반 완료 → `CLAUDE.md` 2.6·7장, preflight 의 "lint/test green 은 필요조건일 뿐"
|
|
19
|
+
|
|
20
|
+
따라서 규약 텍스트를 늘리는 것은 역효과다(안 읽히는 글만 길어진다). 설계는 **"얼마나 자주 마주치고, 출력 전에 스스로 검증하게 만드느냐"**(이행률)로 향한다. 막연한 정체성 페르소나("당신은 20년 경력 전문가다")는 현대 모델에서 추론 능력을 끌어올리지 못하고 장황함·과신·아첨을 유발하므로 채택하지 않는다 — 형용사를 **검증 가능한 동사**로 번역한다.
|
|
21
|
+
|
|
22
|
+
## 3. 범위
|
|
23
|
+
|
|
24
|
+
### 포함
|
|
25
|
+
- 전 에이전트 공통 "작업 자세" 헤더(형용사 → 행동 규약).
|
|
26
|
+
- 역할별 한 줄 분기(워커 독립성 / 리드 종합 / report-writer 제외).
|
|
27
|
+
- 코드 작성 워커(executor·verifier)의 **완료 전 자기검증 게이트** — 기존 시작 전 preflight 의 짝.
|
|
28
|
+
|
|
29
|
+
### 비포함 (NOT)
|
|
30
|
+
- 정체성/경력 서사형 페르소나 문구.
|
|
31
|
+
- validator 기반 기계 강제(C안) — 정적으로 잡히는 항목이 제한적이라 본 작업에서 제외. 자기보고(self-check) 방식으로 간다.
|
|
32
|
+
- 워커별로 서로 다른 페르소나(관점 다양성은 독립성 조항으로 보존하되, 자세 규약 자체는 통일).
|
|
33
|
+
|
|
34
|
+
## 4. 설계
|
|
35
|
+
|
|
36
|
+
### 4.1 공통 작업 자세 헤더 (SSOT, 영어)
|
|
37
|
+
|
|
38
|
+
기존 preamble·contract 가 영어이고 워커 출력 언어와 무관하므로 영어로 둔다. 톤은 기존 preamble 의 간결 명령형을 따른다.
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
## Operating standard
|
|
42
|
+
|
|
43
|
+
Work like a senior engineer who owns this result, not a commentator on it.
|
|
44
|
+
- Evidence over assertion — back every claim with a file:line, or mark it an
|
|
45
|
+
explicit assumption. Never state the unverified as fact.
|
|
46
|
+
- Read before you reason — read each required input end to end; when you lack
|
|
47
|
+
basis, write "insufficient evidence" instead of filling the gap plausibly.
|
|
48
|
+
- Shortest sound path — chase the most likely cause first; don't re-verify what
|
|
49
|
+
is settled or pad with restatement.
|
|
50
|
+
- Decide, don't survey — when options exist, give the trade-off and one
|
|
51
|
+
recommendation, not an exhaustive list.
|
|
52
|
+
- Fit what's here — match the surrounding code and prose; size the response to
|
|
53
|
+
the request.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 4.2 역할별 한 줄 분기 (동질화 방지)
|
|
57
|
+
|
|
58
|
+
cross-verification 은 세 워커의 관점이 **독립적**이어야 triangulation 이 성립한다. 자세 규약은 통일하되 관점은 보존한다.
|
|
59
|
+
|
|
60
|
+
- **분석/검증 워커 전용** 추가 한 줄:
|
|
61
|
+
`Hold your own line — reason from your independent angle; do not drift toward the other workers' likely answers or echo the user. Triangulation fails if your view isn't genuinely yours.`
|
|
62
|
+
- **리드 전용** 추가 한 줄:
|
|
63
|
+
`Own the synthesis — weigh worker outputs on evidence, not consensus; a better-grounded dissent outranks the majority.`
|
|
64
|
+
- **report-writer**: 독립성 조항 없음(독립 분석을 하지 않는 작성자). 공통 코어만 적용.
|
|
65
|
+
|
|
66
|
+
### 4.3 코드 워커 완료 전 자기검증 게이트
|
|
67
|
+
|
|
68
|
+
[_coding-conventions-preflight.md](../../../prompts/profiles/_coding-conventions-preflight.md)(시작 전 BLOCKING)에 대응하는 **완료 전 BLOCKING** 게이트. executor·verifier 가 "done" 을 선언하기 직전, audit 사이드카에 항목별 한 줄 확정을 쓴다. 항목은 사용자가 지목한 4개에 1:1 대응한다.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
## Implementation self-check (BLOCKING — before you claim done)
|
|
72
|
+
|
|
73
|
+
Before declaring the change complete, write one confirming line per item to your
|
|
74
|
+
audit sidecar. If any fails, fix it or surface the violation — do not claim done.
|
|
75
|
+
- functions: every new/edited function ≤50 effective lines, single purpose
|
|
76
|
+
- conventions: applied the routed pack + project patterns (name them)
|
|
77
|
+
- names & comments: names say what, comments say why; no obvious-restatement
|
|
78
|
+
comments; no truthful-name violations
|
|
79
|
+
- verification: ran the actual build/test (paste command + result); no
|
|
80
|
+
dead/commented-out code left
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
이 게이트는 시작 전 preflight 와 **별개 관심사**(완료 전 검증)이므로 별도 sidecar `prompts/profiles/_implementation-self-check.md` 로 신설한다. 전달 경로는 preflight 와 동일하다: Claude executor 는 직접 read, codex/antigravity executor 는 sidecar 를 read 할 수 없으므로 lead 가 dispatch 시 프롬프트에 본문을 append 한다. [_implementation-executor.md](../../../prompts/profiles/_implementation-executor.md)·[_implementation-verifier.md](../../../prompts/profiles/_implementation-verifier.md) 가 이 sidecar 를 완료 전 단계에서 참조하도록 배선한다.
|
|
84
|
+
|
|
85
|
+
### 4.4 주입 지점과 단일 참조점
|
|
86
|
+
|
|
87
|
+
build.mjs 는 단순 복사이고(파일 include 합성 없음), 워커는 `**Worker Preamble Path:**` 앵커로 [worker-prompt-preamble.md](../../../templates/worker-prompt-preamble.md)를 통째로 read 한다. 리드는 [okstra-lead-contract.md](../../../prompts/lead/okstra-lead-contract.md)·[team-contract.md](../../../prompts/lead/team-contract.md)를 읽는다.
|
|
88
|
+
|
|
89
|
+
공통 코어(4.1)는 두 호출자(워커 preamble·리드 contract)를 가지므로 추출 대상이다. 실현 방식:
|
|
90
|
+
|
|
91
|
+
- **채택**: `templates/operating-standard.md` 를 SSOT 로 신설(4.1 코어 + 역할 분기 규칙 명시). 워커 preamble 과 리드 contract 는 코어 문장을 **인라인**한다(앵커 추가-read 없음 — okstra 는 audience-scoped enumeration 을 성능 최적화로 명시할 만큼 워커 토큰에 민감하므로, 5줄짜리 코어를 위해 매 워커 +1 파일 read 를 추가하지 않는다). 인라인 중복은 **단위 테스트로 drift 를 차단**한다(세 위치의 코어 문장이 SSOT 와 일치하는지 grep 검증).
|
|
92
|
+
- 코드 워커 게이트(4.3)는 별도 sidecar `prompts/profiles/_implementation-self-check.md` 로 신설한다(preflight 와 별개 관심사).
|
|
93
|
+
|
|
94
|
+
주입 대상 파일:
|
|
95
|
+
|
|
96
|
+
| 파일 | 추가 내용 |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `templates/operating-standard.md` (신설) | 공통 코어 + 역할 분기 규칙 (SSOT) |
|
|
99
|
+
| [templates/worker-prompt-preamble.md](../../../templates/worker-prompt-preamble.md) | 공통 코어 인라인 + 워커 독립성 한 줄 |
|
|
100
|
+
| [prompts/lead/okstra-lead-contract.md](../../../prompts/lead/okstra-lead-contract.md) | 공통 코어 인라인 + 리드 종합 한 줄 |
|
|
101
|
+
| `prompts/profiles/_implementation-self-check.md` (신설) | 완료 전 자기검증 게이트 |
|
|
102
|
+
| [_implementation-executor.md](../../../prompts/profiles/_implementation-executor.md) · [_implementation-verifier.md](../../../prompts/profiles/_implementation-verifier.md) | 완료 전 self-check sidecar 참조 배선 |
|
|
103
|
+
|
|
104
|
+
## 5. 검증 / 테스트
|
|
105
|
+
|
|
106
|
+
- **단위 테스트(신규)**: `operating-standard.md` 의 코어 문장이 worker-prompt-preamble.md 와 okstra-lead-contract.md 에 모두 존재하는지(동기화), 워커 독립성 한 줄이 preamble 에만·리드 종합 한 줄이 contract 에만 있는지 검증.
|
|
107
|
+
- **단위 테스트(신규)**: 코드 워커 자기검증 게이트의 4개 항목 헤딩이 preflight 전달 경로에 포함되는지 검증.
|
|
108
|
+
- `npm run build` 후 `runtime/` 동기화 확인.
|
|
109
|
+
- `bash validators/validate-workflow.sh` 통과.
|
|
110
|
+
- `python3 -m pytest tests/` 전체 통과.
|
|
111
|
+
|
|
112
|
+
## 6. 사용자 영향 (CHANGES.md 예정)
|
|
113
|
+
|
|
114
|
+
okstra 의 모든 에이전트가 출력 전 공통 "작업 자세"(증거 우선·끝까지 읽기·최단 경로·결정 후 추천·주변에 맞추기)를 마주치고, 코드 작성 워커는 "done" 선언 전 함수 길이·패턴·네이밍·실제 검증을 audit 사이드카에 자기보고한다. 워커 독립성 조항으로 cross-verification 의 관점 다양성은 보존된다.
|
|
115
|
+
|
|
116
|
+
## 7. 리스크 / 미해결
|
|
117
|
+
|
|
118
|
+
- 자기검증은 self-check 이므로 100% 보장이 아니다(설계상 수용 — 기계 강제는 비포함). 다만 audit 사이드카 자기보고는 "조용히 건너뛰기"를 어렵게 만든다.
|
|
119
|
+
- 공통 코어 인라인 중복은 테스트로 drift 를 막지만, 테스트가 코어 문장을 문자열로 들고 있어야 한다(SSOT 변경 시 테스트도 갱신). 수용 가능한 트레이드오프.
|
|
120
|
+
- 헤더가 기존 preamble/contract 의 분량을 늘린다(코어 ~6줄 + 분기 1줄). 토큰 영향은 미미하나, 기존 "장황함 줄이기" 목표와 상충하지 않도록 코어를 6줄 이내로 유지한다.
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Okstra Lead Contract
|
|
2
2
|
|
|
3
|
+
## Operating standard
|
|
4
|
+
|
|
5
|
+
Work like a senior engineer who owns this result, not a commentator on it.
|
|
6
|
+
- Evidence over assertion — back every claim with a file:line, or mark it an explicit assumption. Never state the unverified as fact.
|
|
7
|
+
- Read before you reason — read each required input end to end; when you lack basis, write "insufficient evidence" instead of filling the gap plausibly.
|
|
8
|
+
- Shortest sound path — chase the most likely cause first; don't re-verify what is settled or pad with restatement.
|
|
9
|
+
- Decide, don't survey — when options exist, give the trade-off and one recommendation, not an exhaustive list.
|
|
10
|
+
- Fit what's here — match the surrounding code and prose; size the response to the request.
|
|
11
|
+
- Own the synthesis — weigh worker outputs on evidence, not consensus; a better-grounded dissent outranks the majority.
|
|
12
|
+
|
|
3
13
|
## Overview
|
|
4
14
|
|
|
5
15
|
Claude lead orchestrates multiple AI workers (Claude, Codex, Antigravity) against a prepared task bundle, collects their independent outputs, supervises convergence, and ensures the final report is produced. When `Report writer worker` is in the selected roster, the final report file is **authored by the Report writer worker** — Claude lead reviews and approves but does not write the file itself. Claude lead never substitutes its own reasoning for a worker result, and never bypasses a rostered Report writer worker by writing the report directly.
|
|
@@ -22,6 +22,9 @@ until Phase 5 ends, then drop from active context for Phase 6/7.
|
|
|
22
22
|
- **Coding-conventions preflight (BLOCKING — runs before the first `Edit` / `Write`, and binds the TDD loop below).** The gate body is a single source at `prompts/profiles/_coding-conventions-preflight.md` (sibling of this sidecar): resolved `Coding preflight pack:` runtime-resource path usage, project review rule packs, the always-binding language-agnostic principles, and graceful degradation. Do NOT re-type that content from memory — deliver it by file so it cannot drift or be dropped:
|
|
23
23
|
- **Claude executor:** Read `_coding-conventions-preflight.md` end-to-end before the first `Edit` / `Write`, then state in ONE line which conventions apply (e.g. `Applying TS + hexagonal overlay; domain at src/domains/*/domain/`).
|
|
24
24
|
- **CLI executor (BLOCKING when the executor provider is `codex` or `antigravity`):** the executor CLI process does NOT share the lead's context, and it cannot Read this sidecar's directory — that path sits outside the CLI sandbox and the CLI only sees its stdin prompt, so a file reference never reaches it. The lead MUST physically append the **body** of `_coding-conventions-preflight.md` into the persisted executor prompt at dispatch time: Read the file from the same absolute directory you read this sidecar from, then `Write`/`cat` its body into the persisted prompt. Never hand-retype it. Enforcement: the CLI wrapper agents refuse an implementation-Executor dispatch whose persisted prompt lacks the literal heading `Coding-conventions preflight`, returning `<SENTINEL_PREFIX>_PREFLIGHT_MISSING` (see `agents/workers/_cli-wrapper-template.md` → Prompt Composition).
|
|
25
|
+
- **Completion self-check (BLOCKING — runs BEFORE you claim the stage done).** The gate body is a single source at `prompts/profiles/_implementation-self-check.md` (sibling of this sidecar): the four-item completion gate (functions ≤50 lines, conventions applied, truthful names & why-comments, real build/test run). Do NOT re-type it from memory — deliver it by file so it cannot drift.
|
|
26
|
+
- **Claude executor:** Read `_implementation-self-check.md` end-to-end before appending the `status:"done"` row, then write one confirming line per item to your audit sidecar.
|
|
27
|
+
- **CLI executor (codex / antigravity):** the CLI process cannot Read this path (outside its sandbox). The lead appends this file's body into the persisted executor prompt at dispatch time, immediately after the preflight body (see `codex_dispatch.py` `_implementation_executor_tail`). The head-less executor honours both gates from the single prompt.
|
|
25
28
|
- **Stage discipline transcription (when a preceding stage is `done`):** the lead MUST transcribe the `Stage discipline` rule (from this run's rendered profile — the INCLUDEd `_stage-discipline.md` body) verbatim into the dispatched CLI executor prompt, so a codex/antigravity executor honors the prior-stage behavior-freeze. Declaration-level — no wrapper sentinel.
|
|
26
29
|
- **Non-interactive auto-execution (BLOCKING when the executor provider is `codex` or `antigravity`).** A CLI executor runs head-less (`codex exec` / antigravity equivalent) — there is no human at the keyboard. Skills loaded during the run (tdd, coding-preflight, and others) contain "get user approval", "state your plan to the user and wait", or "ask before proceeding" gates written for interactive sessions; in this run those gates are **already satisfied** by the upstream `implementation-planning` approval (the plan this stage executes was human-approved). The executor MUST NOT stop to request approval, MUST NOT end its turn after only producing a plan, and MUST carry the stage through end-to-end — RED → GREEN → refactor → per-step commits → `### Stage Carry Evidence`. The ONLY skill step to skip is the interactive user-approval prompt itself; every other skill rule (TDD discipline, conventions, real-IO isolation) still binds. The lead MUST transcribe this bullet verbatim into the dispatched CLI executor prompt (same reason as the preflight transcription rule above — the CLI process does not share lead context). Stopping early for approval in a head-less run is the observed empty-exit failure (exit 0, no diff): treat it as `contract-violated`.
|
|
27
30
|
- **Mandatory TDD loop**: BEFORE the first `Edit` or `Write` call, the executor MUST apply a red-green-refactor loop for every code change in this run. This is required; skipping it is a `contract-violated` outcome. This governs HOW each step is executed (failing test first → minimal implementation → refactor); it does not override the approved plan's WHAT/file scope.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Completion-time counterpart to _coding-conventions-preflight.md. The preflight
|
|
3
|
+
gate runs BEFORE the first Edit/Write; this gate runs BEFORE the executor claims
|
|
4
|
+
done. Same delivery paths: Claude executor reads this file directly; codex /
|
|
5
|
+
antigravity executor cannot read it (outside the CLI sandbox), so the lead
|
|
6
|
+
appends this file's body into the persisted executor prompt at dispatch time
|
|
7
|
+
(see codex_dispatch.py `_implementation_executor_tail`).
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
# Implementation self-check (BLOCKING — before you claim done)
|
|
11
|
+
|
|
12
|
+
Before declaring the change complete, write one confirming line per item to your
|
|
13
|
+
audit sidecar. If any item fails, fix it or surface the violation — do not claim
|
|
14
|
+
done on a failing item.
|
|
15
|
+
|
|
16
|
+
- functions: every new/edited function ≤50 effective lines, single purpose
|
|
17
|
+
- conventions: applied the routed pack + project patterns (name which ones)
|
|
18
|
+
- names & comments: names say what, comments say why; no obvious-restatement comments; no truthful-name violations
|
|
19
|
+
- verification: ran the actual build/test (paste the command + its result); no dead or commented-out code left behind
|
|
@@ -126,3 +126,7 @@ If every verifier present in the resolved roster (`Claude verifier`, `Codex veri
|
|
|
126
126
|
- git state mutations — `git add`, `git commit`, `git stash`, `git checkout -- <file>`, `git restore`, `git reset`, `git rebase`, `git merge`, branch creation/deletion, tag creation. Only read-only git queries (`git status`, `git diff`, `git log`, `git show`, `git rev-parse`, `git blame`) are permitted for verifiers
|
|
127
127
|
- running integration / end-to-end tests that produce non-local side effects (DB writes against a non-local datastore, external API writes, docker compose against a non-isolated environment) unless that exact command is listed in the approved plan's validation set
|
|
128
128
|
- redirecting tool caches or output to paths outside the worktree — e.g. setting `CARGO_TARGET_DIR`, `PYTEST_CACHE_DIR`, `NODE_OPTIONS=--require=<external>`, or any env var that causes the verifier's command to write outside the worktree's normal build artifact paths
|
|
129
|
+
|
|
130
|
+
## Completion self-check (declaration)
|
|
131
|
+
|
|
132
|
+
- **Completion self-check (declaration).** If this verifier edits project code (not just inspects it), the same completion gate at `prompts/profiles/_implementation-self-check.md` binds before claiming done — same four items, recorded in the audit sidecar.
|
|
@@ -217,9 +217,9 @@
|
|
|
217
217
|
"echo_template": "approved-plan: {value}"
|
|
218
218
|
},
|
|
219
219
|
"approve_plan_confirm": {
|
|
220
|
-
"label": "
|
|
220
|
+
"label": "이대로 구현을 진행할까요?\n {path}\n· 예 — 이 plan 대로 구현을 실행합니다. 플랜이 아직 승인 전이면 지금 data.json(정본) + 리포트를 함께 approved 로 처리한 뒤 진행합니다. (markdown 만 손으로 고치면 일관성 검증에서 거부되므로 이 경로로 승인하세요.)\n· 아니오 — 진행하지 않습니다.",
|
|
221
221
|
"label_final_verification": "이 plan 을 검증 기준으로 삼아 진행할까요?\n {path}\n· 예 — 선택한 stage 의 구현 결과를 위 plan 기준으로 검증합니다. (plan 이 아직 승인 전이면 data.json(정본) + 리포트를 함께 approved 로 처리한 뒤 검증합니다.)\n· 아니오 — 진행하지 않습니다.",
|
|
222
|
-
"html_approval_note": "\n보고서에서
|
|
222
|
+
"html_approval_note": "\n지난 {plan_label} 의 보고서에서 사용자의 승인 기록을 발견했습니다.\n 선택된 방식: {option}",
|
|
223
223
|
"html_approval_note_default_option": "(추천 옵션 그대로)",
|
|
224
224
|
"echo_template": "approve-plan: {value}",
|
|
225
225
|
"options": {
|
|
@@ -231,8 +231,8 @@
|
|
|
231
231
|
"no": "아니오 — 진행하지 않음"
|
|
232
232
|
},
|
|
233
233
|
"options_html_approval": {
|
|
234
|
-
"yes_apply": "예 —
|
|
235
|
-
"yes": "예 —
|
|
234
|
+
"yes_apply": "예 — 지난 {plan_label} 보고서, 사용자의 승인 기록으로 진행 (추천)",
|
|
235
|
+
"yes": "예 — 내보낸 기록 무시 후 진행 — 진행 방식은 구현 중 다시 정함",
|
|
236
236
|
"no": "아니오 — 진행하지 않음"
|
|
237
237
|
},
|
|
238
238
|
"echo_variants": {
|
|
@@ -806,10 +806,17 @@ def _implementation_executor_tail(
|
|
|
806
806
|
) -> str:
|
|
807
807
|
if role != "executor" or _require_string(manifest, "taskType") != "implementation":
|
|
808
808
|
return ""
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
809
|
+
profiles = workspace_root / "prompts" / "profiles"
|
|
810
|
+
parts: list[str] = []
|
|
811
|
+
preflight_path = profiles / "_coding-conventions-preflight.md"
|
|
812
|
+
if preflight_path.is_file():
|
|
813
|
+
parts.append(preflight_path.read_text(encoding="utf-8"))
|
|
814
|
+
else:
|
|
815
|
+
parts.append("# Coding-conventions preflight\n\nApply project-local conventions before editing.")
|
|
816
|
+
selfcheck_path = profiles / "_implementation-self-check.md"
|
|
817
|
+
if selfcheck_path.is_file():
|
|
818
|
+
parts.append(selfcheck_path.read_text(encoding="utf-8"))
|
|
819
|
+
return "\n\n".join(parts)
|
|
813
820
|
|
|
814
821
|
|
|
815
822
|
def _project_relative_path(project_root: Path, path: Path) -> str:
|
|
@@ -628,6 +628,14 @@ def _validate_sidecar_option(plan_path: Path, option_name: str, errors_t: dict)
|
|
|
628
628
|
)
|
|
629
629
|
|
|
630
630
|
|
|
631
|
+
def _plan_short_label(candidate: str) -> str:
|
|
632
|
+
"""plan 파일명에서 사용자용 짧은 식별자를 뽑는다.
|
|
633
|
+
final-report-implementation-planning-002.md → implementation-planning-002"""
|
|
634
|
+
if not candidate:
|
|
635
|
+
return ""
|
|
636
|
+
return Path(candidate).stem.removeprefix("final-report-")
|
|
637
|
+
|
|
638
|
+
|
|
631
639
|
def _stage_plan_for_confirmation(
|
|
632
640
|
state: WizardState, path_str: str, *, suffix: str = ""
|
|
633
641
|
) -> Optional[str]:
|
|
@@ -1713,12 +1721,16 @@ def _build_approve_plan_confirm(state: WizardState) -> Prompt:
|
|
|
1713
1721
|
label = (t["label_final_verification"] or t["label"]) if is_fv else t["label"]
|
|
1714
1722
|
options_map = (t["options_final_verification"] or t["options"]) if is_fv else t["options"]
|
|
1715
1723
|
if state.html_approval_sidecar:
|
|
1724
|
+
plan_label = _plan_short_label(state.approve_plan_candidate)
|
|
1716
1725
|
label += t["html_approval_note"].format(
|
|
1717
|
-
|
|
1726
|
+
plan_label=plan_label,
|
|
1718
1727
|
option=state.html_approval_option
|
|
1719
1728
|
or t["html_approval_note_default_option"],
|
|
1720
1729
|
)
|
|
1721
|
-
options_map =
|
|
1730
|
+
options_map = {
|
|
1731
|
+
k: v.format(plan_label=plan_label)
|
|
1732
|
+
for k, v in t["options_html_approval"].items()
|
|
1733
|
+
}
|
|
1722
1734
|
return Prompt(
|
|
1723
1735
|
step=S_APPROVE_PLAN_CONFIRM, kind="pick",
|
|
1724
1736
|
label=label,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Operating Standard (canonical)
|
|
2
|
+
|
|
3
|
+
This file is the single source of truth for the operating standard injected into
|
|
4
|
+
every okstra agent. The "Common core" block below is inlined verbatim into
|
|
5
|
+
`templates/worker-prompt-preamble.md` (workers) and
|
|
6
|
+
`prompts/lead/okstra-lead-contract.md` (lead). A unit test asserts both inlined
|
|
7
|
+
copies match this core — update all three together.
|
|
8
|
+
|
|
9
|
+
## Common core
|
|
10
|
+
|
|
11
|
+
Work like a senior engineer who owns this result, not a commentator on it.
|
|
12
|
+
- Evidence over assertion — back every claim with a file:line, or mark it an explicit assumption. Never state the unverified as fact.
|
|
13
|
+
- Read before you reason — read each required input end to end; when you lack basis, write "insufficient evidence" instead of filling the gap plausibly.
|
|
14
|
+
- Shortest sound path — chase the most likely cause first; don't re-verify what is settled or pad with restatement.
|
|
15
|
+
- Decide, don't survey — when options exist, give the trade-off and one recommendation, not an exhaustive list.
|
|
16
|
+
- Fit what's here — match the surrounding code and prose; size the response to the request.
|
|
17
|
+
|
|
18
|
+
## Role addendum
|
|
19
|
+
|
|
20
|
+
- Analysis / verification workers add this line: `Hold your own line — reason from your independent angle; do not drift toward the other workers' likely answers or echo the user. Triangulation fails if your view isn't genuinely yours.`
|
|
21
|
+
- Lead adds this line: `Own the synthesis — weigh worker outputs on evidence, not consensus; a better-grounded dissent outranks the majority.`
|
|
22
|
+
- Report-writer worker: common core only (no independence addendum — it authors, it does not analyze).
|
|
@@ -4,6 +4,16 @@ This file is the single source of truth for the boilerplate that every okstra an
|
|
|
4
4
|
|
|
5
5
|
It replaces the previous practice of inlining ~80 lines of identical boilerplate into every worker prompt body.
|
|
6
6
|
|
|
7
|
+
## Operating standard (read before any output)
|
|
8
|
+
|
|
9
|
+
Work like a senior engineer who owns this result, not a commentator on it.
|
|
10
|
+
- Evidence over assertion — back every claim with a file:line, or mark it an explicit assumption. Never state the unverified as fact.
|
|
11
|
+
- Read before you reason — read each required input end to end; when you lack basis, write "insufficient evidence" instead of filling the gap plausibly.
|
|
12
|
+
- Shortest sound path — chase the most likely cause first; don't re-verify what is settled or pad with restatement.
|
|
13
|
+
- Decide, don't survey — when options exist, give the trade-off and one recommendation, not an exhaustive list.
|
|
14
|
+
- Fit what's here — match the surrounding code and prose; size the response to the request.
|
|
15
|
+
- Hold your own line — reason from your independent angle; do not drift toward the other workers' likely answers or echo the user. Triangulation fails if your view isn't genuinely yours.
|
|
16
|
+
|
|
7
17
|
---
|
|
8
18
|
|
|
9
19
|
## Required reading (analysis workers + report-writer worker)
|