Skip to content

Commit 13ba682

Browse files
authored
(#102) status 기반 소크라테스 clarification gate와 repair loop 안정화
* feat: status 기반 소크라테스 clarification gate와 repair loop를 안정화 - status 기반 open/resolved clarification contract와 intake/status gate를 v3로 전환 - reopen 시 downstream phase까지 pending으로 되돌리도록 runtime과 회귀 테스트를 보강 - docs, skills, workflow task artifact를 새 contract와 cleanup 범위에 맞춰 정리 * fix: pre-v3 locked intake 호환성을 복구 - legacy clarification intake가 status 없이도 load, plan, doctor 경로에서 정규화되게 보정 - pre-v3 task의 locked intake 회귀를 막는 CLI 테스트를 추가 - review feedback에서 지적된 loader 회귀를 phase-1 범위에서 수정 * chore: review follow-up task evidence를 갱신 - legacy intake compatibility 수정 이후 phase-1/phase-2 verification evidence를 다시 기록 - task-harness-socratic-uncertainty-gate를 review_ready 상태로 복구 - follow-up repair loop의 kickoff, verification, review run artifact를 남김
1 parent 85f7083 commit 13ba682

99 files changed

Lines changed: 1209 additions & 1915 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.codex/skills/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@
3333
5. 모든 phase가 끝나면 `review-closeout`
3434
6. 실패, block, follow-up이면 `repair-reopen`
3535

36-
새 workflow에서는 markdown spec과 JSON state를 분리한다. `spec.md`는 사람용 요구사항 초안이고, `approve`가 이를 `task.json.intake`로 잠근다. 새 spec contract에서는 clarification coverage category를 모두 채워야 승인된다. `task.json`/`phases.json`/`runs/*.json`은 자동화용 canonical source고, phase boundary kickoff proof도 여기 남긴다.
36+
새 workflow에서는 markdown spec과 JSON state를 분리한다. `spec.md`는 사람용 요구사항 초안이고, `approve`가 이를 `task.json.intake`로 잠근다. 새 spec contract에서는 `Socratic Clarification Log`의 열린 질문이 모두 닫혀야 승인된다. `task.json`/`phases.json`/`runs/*.json`은 자동화용 canonical source고, phase boundary kickoff proof도 여기 남긴다.

.codex/skills/repair-reopen/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ description: failed, blocked, review follow-up, 추가 요구사항이 들어온
2121

2222
1. 왜 reopen이 필요한지 note를 한 줄로 잠근다.
2323
2. 필요하면 target phase를 정한다.
24-
3. `python3 scripts/workflow.py reopen <task-id> --note "..." [--phase-id ...]`로 task를 `approved` 상태로 되돌리고 target phase를 `pending`으로 복구한다.
24+
3. `python3 scripts/workflow.py reopen <task-id> --note "..." [--phase-id ...]`로 task를 `approved` 상태로 되돌리고 target phase와 그 이후 downstream phase를 `pending`으로 복구한다.
2525
4. 추가 요구사항이면 먼저 `spec.md`를 다시 잠근다.
2626
5. spec이 바뀌었으면 `python3 scripts/workflow.py approve <task-id> --note "..."``task.json.intake`를 다시 잠근다.
2727
6. 필요하면 `plan`으로 phase를 다시 적재한다.
@@ -30,6 +30,6 @@ description: failed, blocked, review follow-up, 추가 요구사항이 들어온
3030
## 결과
3131

3232
- `state=approved``task.json`
33-
- rerunnable target phase (`status=pending`)
33+
- rerunnable target/downstream phases (`status=pending`)
3434
- cleared `blocked_reason`
3535
- new reopen run evidence

.codex/skills/socratic-spec-authoring/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ description: 소크라테스 질문으로 `spec.md`를 잠그고, 사용자 명
2020
## 작업 방식
2121

2222
1. 질문으로 request, problem, goals, non-goals, constraints, acceptance를 `spec.md`에 기록한다.
23-
2. `Socratic Clarification Log``Q:`, `A:`, `Decision:` triplet으로만 적고, 새 contract에서는 각 `Q:``[scope]`, `[goal]`, `[non_goal]`, `[constraint]`, `[acceptance]` coverage category를 붙인다.
24-
3. `status`에서 `coverage_missing`이 비고 unresolved clarification이 없어질 때까지 질문 루프를 반복한다.
23+
2. `Socratic Clarification Log`clarification마다 `Q:`로 시작하고 마지막 줄에 `Status:`를 둔다. `open``Q:`와 선택적 `A:`를 허용하고, `resolved``Q:`/`A:`/`Decision:`/`Status: resolved`를 순서대로 가진다.
24+
3. `status`에서 `open_clarification_count=0`이고 `validation_errors`가 비어 있을 때까지 질문 루프를 반복한다. 질문은 고정 목록이 아니며, spec 작성 중 새 애매점이 생기면 언제든 추가하거나 다시 연다.
2525
4. placeholder가 남아 있지 않은지 확인한다.
2626
5. 사용자가 현재 `spec.md` 초안에 명시적으로 동의했을 때만 `python3 scripts/workflow.py approve <task-id> --note ...`를 실행한다.
2727
6. `approve``spec.md``task.json.intake`로 잠근다는 점을 전제로, 승인 전에는 phase 생성이나 구현을 시작하지 않는다.

AGENTS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ NEVER: control plane 문서를 앱 source-of-truth보다 우선시하지 않는
3737
## Workflow Contract
3838

3939
1. `new``workflows/tasks/<task-id>/spec.md``task.json` skeleton을 만든다.
40-
2. 소크라테스 질문으로 `spec.md`를 잠근다. `Socratic Clarification Log``Q:`, `A:`, `Decision:` triplet만 사용하고, 새 spec contract에서는 `[scope]`, `[goal]`, `[non_goal]`, `[constraint]`, `[acceptance]` coverage를 모두 채운다.
40+
2. 소크라테스 질문으로 `spec.md`를 잠근다. `Socratic Clarification Log`각 clarification마다 `Q:`와 마지막 줄의 `Status:`를 가진다. `Status: open` 질문이 하나라도 남아 있으면 승인하지 않는다. `resolved` 항목만 `A:``Decision:`으로 닫고, spec 작성 중 애매점이 생기면 언제든 질문을 추가하거나 다시 연다.
4141
3. 사용자가 동의하면 `approve`가 같은 task 디렉터리의 `spec.md`에 Approval block을 추가하고, `spec.md` 내용을 `task.json.intake`로 잠근 뒤 `task.json``approved`로 전이한다.
4242
4. 추가 요구사항으로 spec을 다시 잠그면 `approve`를 다시 실행해 `task.json.intake`를 재잠근다.
4343
5. `plan --from <json>` 또는 `plan --stdin`이 phase 초안을 읽어 `phases.json`으로 적재한다. 각 phase는 `required_reads`, `starting_points`, `deliverables`, `completion_signal` bootstrap 정보를 가져야 하며, `spec.md``task.json.intake`가 어긋나 있으면 plan을 시작하지 않는다.
@@ -49,7 +49,7 @@ NEVER: control plane 문서를 앱 source-of-truth보다 우선시하지 않는
4949
11. verification이 다음 pending phase를 활성화하면 `task.json.kickoff_required_for_phase`를 기록하고 task를 다시 `approved`로 전이한다.
5050
12. 모든 phase가 완료되면 `review`가 review readiness를 기록한다.
5151
13. `review --close --user-validation-note ...`만 최종 완료를 닫을 수 있다.
52-
14. 실패, block, 추가 요구사항이 생기면 `reopen`으로 target phase를 `pending`으로 되돌리고 repair loop를 재개한다. reopened phase가 2번째 이상 phase면 kickoff를 다시 요구한다.
52+
14. 실패, block, 추가 요구사항이 생기면 `reopen`으로 target phase와 그 이후 downstream phase들을 `pending`으로 되돌리고 repair loop를 재개한다. reopened phase가 2번째 이상 phase면 kickoff를 다시 요구한다.
5353
15. `pre_push`의 branch-aware 예외는 현재 브랜치가 `main`이고 로컬 `main` tip이 로컬 `develop` tip과 같을 때의 동기화 publish에만 허용한다.
5454

5555
## TDD Contract
@@ -89,7 +89,7 @@ python3 scripts/workflow.py hook pre_push --command-text "..."
8989
- `init``.githooks/*``workflows/system/hooks.json`을 source 기준으로 다시 동기화하고, `doctor`는 drift를 실패로 취급한다.
9090
- 실제 실행 엔진은 `scripts/workflow_runtime/cli.py`, `engine.py`, `models.py`, `guards.py`, `doctor.py`, `git_ops.py`가 분담한다.
9191
- `workflow.py`를 유지하는 이유는 사람과 AI가 하나의 안정적인 명령 surface만 기억하면 되기 때문이다.
92-
- `status`는 새 spec contract에서 `coverage_missing` active phase bootstrap summary를 노출해 다음 세션 시작점을 복원한다.
92+
- `status`는 새 spec contract에서 `ready_for_approval`, clarification count, open/resolved count, `open_clarifications`, active phase bootstrap summary를 노출해 다음 세션 시작점을 복원한다.
9393

9494
## Source Of Truth Order
9595

docs/artifact-model.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ workflows/
1818

1919
## Artifact Roles
2020

21-
- `workflows/tasks/<task-id>/spec.md`: 사람용 requirement artifact. 요청, 문제, 목표, 비목표, 제약, acceptance, 소크라테스 질문 로그, 승인 기록을 담는다. 새 spec contract에서는 clarification question마다 coverage category를 잠근다.
21+
- `workflows/tasks/<task-id>/spec.md`: 사람용 requirement artifact. 요청, 문제, 목표, 비목표, 제약, acceptance, 소크라테스 질문 로그, 승인 기록을 담는다. 새 spec contract에서는 clarification마다 `Status: open|resolved`를 명시하고, 열린 질문이 없어질 때까지 질의를 계속한다.
2222
- `workflows/tasks/<task-id>/task.json`: mutable task state이자 승인 시점의 locked intake source다. approval, active phase, latest run, latest verified run, kickoff requirement, blocked reason, user validation과 `intake`를 담는다.
2323
- `workflows/tasks/<task-id>/phases.json`: 승인 이후 생성된 executable phase 집합이다. phase 목표, write scope, acceptance command, test policy, retry count와 다음 세션 kickoff용 bootstrap metadata를 담는다.
2424
- `workflows/tasks/<task-id>/runs/*.json`: phase completion, phase kickoff, verification, review, reopen evidence다.
@@ -28,7 +28,7 @@ workflows/
2828
## Spec And Phase Loading Flow
2929

3030
1. `new`가 task 디렉터리와 `spec.md`, `task.json`, `phases.json` skeleton을 만든다.
31-
2. 소크라테스 질문으로 `spec.md`를 채운다. `Socratic Clarification Log``Q:`, `A:`, `Decision:` triplet만 허용하고, 새 contract에서는 `[scope]`, `[goal]`, `[non_goal]`, `[constraint]`, `[acceptance]` coverage를 모두 채운다.
31+
2. 소크라테스 질문으로 `spec.md`를 채운다. `Socratic Clarification Log`clarification마다 `Q:`로 시작하고 마지막 줄에 `Status:`를 둔다. `open``Q:`와 선택적 `A:`허용하고, `resolved``Q:`/`A:`/`Decision:`/`Status: resolved`를 순서대로 가진다.
3232
3. 사용자가 현재 spec 초안에 명시적으로 동의하면 `approve`가 같은 `spec.md`에 Approval block을 추가하고, 내용을 `task.json.intake`로 잠근 뒤 `task.json``approved`로 전이한다.
3333
4. 추가 요구사항으로 spec을 다시 잠그면 `approve`를 다시 실행해 `task.json.intake`를 갱신한다.
3434
5. `plan --from` 또는 `plan --stdin`이 외부 phase 초안을 읽어 같은 task 디렉터리의 `phases.json`으로 적재한다.
@@ -65,10 +65,9 @@ workflows/
6565
`intake.clarifications`의 각 항목은 아래 필드를 가진다.
6666

6767
- `question`
68-
- `category`
6968
- `answer`
7069
- `decision`
71-
- `resolved`
70+
- `status`
7271

7372
## Phase Fields
7473

docs/runbook.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@ python3 -m unittest discover -s tests -v
1616
python3 scripts/workflow.py new task-001 --title "..." --primary-repo git-ranker-workflow
1717
```
1818

19-
이후 `workflows/tasks/task-001/spec.md`를 소크라테스 질문으로 잠근다. 새 spec contract에서는 `Socratic Clarification Log`아래처럼 coverage category를 포함한 `Q/A/Decision` triplet을 모두 채워야 한다.
19+
이후 `workflows/tasks/task-001/spec.md`를 소크라테스 질문으로 잠근다. 새 spec contract에서는 `Socratic Clarification Log`질문 단위의 `Status:`를 명시하고, `Status: open` 질문이 하나라도 남아 있으면 승인되지 않는다.
2020

2121
```md
22-
- Q: [scope] phase canonical source는 무엇인가?
22+
- Q: phase canonical source는 무엇인가?
2323
- A: executable plan은 prose가 아니라 JSON이어야 한다.
2424
- Decision: `phases.json`만 canonical plan으로 쓴다.
25+
- Status: resolved
26+
```
27+
28+
답을 아직 못 받았거나 추가 확인이 필요한 질문은 아래처럼 열린 상태로 남긴다.
29+
30+
```md
31+
- Q: 아직 확인이 필요한 요구사항은 무엇인가?
32+
- Status: open
2533
```
2634

2735
사용자가 현재 spec 초안에 명시적으로 동의하면 approve 한다. 이때 `approve``spec.md``task.json.intake`로 잠근다.
@@ -57,7 +65,7 @@ python3 scripts/workflow.py review task-001 --close --user-validation-note "vali
5765

5866
## Repair / Reopen
5967

60-
실패, block, review follow-up, 추가 요구사항이 들어오면 `reopen`으로 다시 `approved` 상태로 되돌린다. `reopen`은 target phase를 `pending`으로 복구해서 바로 `run --start`로 재개할 수 있게 만든다. 추가 요구사항이면 `spec.md`를 다시 잠근 뒤 `approve`를 다시 실행하고, 그 다음 `plan`으로 phase를 갱신한다.
68+
실패, block, review follow-up, 추가 요구사항이 들어오면 `reopen`으로 다시 `approved` 상태로 되돌린다. `reopen`은 target phase와 그 이후 downstream phase를 `pending`으로 복구해서 repair loop가 뒤 단계 실패 상태에 걸리지 않게 만든다. 추가 요구사항이면 `spec.md`를 다시 잠근 뒤 `approve`를 다시 실행하고, 그 다음 `plan`으로 phase를 갱신한다.
6169

6270
```bash
6371
python3 scripts/workflow.py reopen task-001 --note "추가 요구사항 반영"

docs/runtime.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@
3737
## Runtime Rules
3838

3939
- `approve` 전에는 `plan`, `run`, `verify`, `review`를 허용하지 않는다.
40-
- `approve``spec.md`의 필수 section, placeholder 제거 여부, `Socratic Clarification Log``Q/A/Decision` triplet 형식을 검증한다.
41-
- 새 task contract에서 `approve`는 clarification coverage도 검증한다. `scope`, `goal`, `non_goal`, `constraint`, `acceptance`가 모두 없으면 승인되지 않는다.
40+
- 새 clarification contract에서 열린 질문은 `Status: open`으로 남기고, 모든 질문이 닫힌 뒤에만 승인을 요청한다.
41+
- `approve``spec.md`의 필수 section, placeholder 제거 여부, `Socratic Clarification Log``Q:`/`A:`/`Decision:`/`Status:` 형식을 검증한다.
42+
- `approve`는 clarification이 최소 1개 이상인지, 열린 질문이 없는지, `open` 항목에 `Decision:`이 없는지, `resolved` 항목이 `A:``Decision:`으로 완결되는지 검증한다.
4243
- `approve`는 승인된 spec을 `task.json.intake`로 잠그며, 이후 `spec.md`를 수정했으면 `approve`를 다시 실행해 intake를 재잠가야 한다.
4344
- `plan`은 명시적 phase 입력 없이는 실행되지 않는다.
4445
- `plan``task.json.intake`와 현재 `spec.md`가 일치할 때만 허용하며, 각 phase를 새 세션이 시작할 수 있도록 bootstrap metadata를 함께 적재한다.
45-
- `status``spec.md`를 읽어 `ready_for_approval`, `clarification_count`, `coverage_present`, `coverage_missing`, `unresolved_clarifications`를 JSON으로 노출한다.
46+
- `status``spec.md`를 읽어 `ready_for_approval`, `clarification_count`, `open_clarification_count`, `resolved_clarification_count`, `open_clarifications`, `validation_errors`를 JSON으로 노출한다.
4647
- `status`는 active phase의 `required_reads`, `starting_points`, `deliverables`, `completion_signal`도 함께 노출해 다음 세션 시작점을 복원한다.
4748
- `run --complete``allowed_write_paths``workflows/tasks/<task-id>/` 밖 변경을 차단한다.
4849
- `run --start``task.json.kickoff_required_for_phase`가 active phase와 일치하면, matching `phase_kickoff` evidence 없이는 시작되지 않는다.
@@ -75,6 +76,6 @@
7576
- verification 실패도 retry에 포함한다.
7677
- 동일한 `error_fingerprint`가 짧은 시간 안에 반복되면 Circuit Breaker가 `blocked`로 전이한다.
7778
- `blocked`는 외부 입력, spec 재정의, phase 재계획이 필요한 상태다.
78-
- `reopen``failed`, `blocked`, `review_ready`, `completed` task를 다시 `approved`로 되돌리고 target phase를 `pending`으로 복구한 뒤 repair loop를 재시작한다.
79+
- `reopen``failed`, `blocked`, `review_ready`, `completed` task를 다시 `approved`로 되돌리고 target phase와 그 이후 downstream phase를 `pending`으로 복구한 뒤 repair loop를 재시작한다.
7980
- reopened target phase가 2번째 이상 phase면 kickoff proof를 다시 요구한다.
80-
- 추가 요구사항이면 `reopen``spec.md`를 다시 잠그고 `approve`를 재실행한 뒤 `plan`으로 phase를 다시 적재한다.
81+
- 추가 요구사항이면 `reopen``spec.md`에 새 clarification을 열고, 질문을 닫은 다음 `approve`를 재실행한 뒤 `plan`으로 phase를 다시 적재한다.

scripts/workflow_runtime/constants.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
from pathlib import Path
44

5-
CURRENT_TASK_CONTRACT_VERSION = 2
6-
CLARIFICATION_REQUIRED_CATEGORIES = ["scope", "goal", "non_goal", "constraint", "acceptance"]
5+
CURRENT_TASK_CONTRACT_VERSION = 3
76

87
TASK_STATES = {"draft", "approved", "in_progress", "failed", "blocked", "review_ready", "completed"}
98
PHASE_STATES = {"pending", "in_progress", "completed", "failed", "blocked"}
@@ -65,10 +64,10 @@
6564

6665
DOC_REQUIRED_MARKERS = {
6766
"docs/README.md": ["AGENTS.md", "docs/runtime.md", "docs/artifact-model.md"],
68-
"docs/artifact-model.md": ["task.json", "intake", "clarifications", "kickoff_required_for_phase", "required_reads"],
69-
"docs/runtime.md": ["소크라테스 질문", "approve", "plan", "kickoff", "review --close"],
67+
"docs/artifact-model.md": ["task.json", "intake", "clarifications", "status", "kickoff_required_for_phase", "required_reads"],
68+
"docs/runtime.md": ["소크라테스 질문", "Status: open", "approve", "plan", "kickoff", "review --close"],
7069
"docs/hooks.md": [".githooks/", "TDD Guard", "Dangerous Command Guard", "Circuit Breaker", "workflow.py hook"],
71-
"docs/runbook.md": ["사용자가 현재 spec 초안에 명시적으로 동의하면 approve 한다.", "approve", "plan", "kickoff"],
70+
"docs/runbook.md": ["Status: open", "사용자가 현재 spec 초안에 명시적으로 동의하면 approve 한다.", "approve", "plan", "kickoff"],
7271
}
7372

7473
STALE_REFERENCE_PATTERNS = [

0 commit comments

Comments
 (0)