파이프라인 4단계(Design) 산출물 · 2026-08-26 · 사용자 흐름 순열 분석 정본 순서: Seed Spec v3.1.0 > 조직 규약(cc-flutter·cc-coui 스킬) > PRD/BDD > Discovery
작성 방식: 초안을 작성한 에이전트와 별도의 검증 에이전트가 원본 파일을 직접 열어 대조하고 교정했다. 이 파일은 교정본이다.
⚠️ 이 문서 작성 이후 확정된 사항 (2026-08-26, 반영 필요)
아래 셋은 이 문서를 생성한 워크플로가 시작된 뒤 확정됐다. 본문에 반영돼 있지 않으므로 이 블록이 우선한다.
1. Flutter master 채널 + 네이티브 윈도잉 API (D-022) — 창 분리를
window_manager가 아니라 Flutter 네이티브 윈도잉(RegularWindow·DialogWindow·PopupWindow·SatelliteWindow·WindowingOwner·WindowRegistry)으로 구현한다. 결정적 근거는windowHandle이ffi.Pointer<ffi.Void>로 네이티브 핸들(LinuxGtkWindow·macOSNSWindow·Win32HWND)을 노출해 네이티브 도킹이 가능하다는 점이다(_window_linux.dart:208,_window_macos.dart:200).
- 채널 제약:
windowingFeature가master:만 선언하므로 stable 에서는available:false이고 설정으로도 켤 수 없다(flutter_features.dart:99가 config 를 읽기 전에 반환). 제품 빌드 전체가 master 채널 위에 서게 된다.- 인수한 위험:
@internalAPI · 패치 버전에서도 breaking change 예고 · CI·개발 환경·cob doctor가 모두 master 전제. 완화로 창 관리 호출을 얇은 자체 인터페이스 뒤에 두어 수정 지점을 한 곳으로 모은다.2. 프로젝트 초기 세팅은
cob로 수행 (D-023) — 모노레포 생성과 기능 추가를cob(co-bricks CLI)로 한다.cob doctor전 항목 통과 확인. 관련 명령:cob create·cob generate(project.yaml → 모노레포+기능)·cob compose/add·cob apply·cob plan(PRD FR/AC 커버리지 게이팅, 고아 FR hard-fail). 미결: cocode ADE 는 앱이 아니라 데스크톱 IDE 이고 Serverpod 백엔드가 없어, 기존 brick 이 이 형태를 지원하는지 Scaffold 단계에서cob list-features로 확인해야 한다.3. CoUI 실측 인벤토리 (
docs/coui-inventory-cocode.md) — 이 문서가 인용하는 CoUI 컴포넌트는 그 인벤토리와 대조해야 한다. 특히 주의:coui-dock은 IDE 도킹이 아니라 모바일 하단 내비게이션 바이고,coui-diff는 코드 diff 가 아니라 이미지 비교 슬라이더다(코드 diff 는coui-code-diff). Figma 검색 결과Terminal·Toolbar·StatusBar·Sidebar·Panel(단독)·Input·Split·CommandPalette는 실재하지 않는다.
사용자 흐름 순열 분석: cocode ADE
- 작성일: 2026-08-26 · 에이전트: flow-permutation
- 대상:
docs/seed-spec-cocode.mdv3.1.0(정본) ·docs/prd-cocode.md§2 흐름 1~5 ·docs/bdd-cocode.mdFeature 1~9 - 핵심 대상: DelegatedTask 상태 기계(Seed Spec §3, 79행)
- 열거량: 상태 전이 행렬 49칸(7×7) · 입력 순열 11행 · 조건 분기 진리표 4종 44행(T-A 12 · T-B 12 · T-C 11 · T-D 9) · 오류 복구 경로 9종 · 순열 항목 FP-101~FP-503, 47건
- 누락: Critical 8 · Important 10 · Nice-to-have 5 (전수 주장 아님 — 아래 §7 참조)
인용 규칙. 모든 인용은 파일을 열어 행 번호를 확인했다.
seed:NN=docs/seed-spec-cocode.mdNN행,prd:NN,bdd:NN,dl:D-NNN=의사결정 일지,pi:§N=planning-inputs-cocode.md. 수치는 출처가 있는 것만 쓰고, 없으면 값 대신 **"누가 언제 정하는가"**를 적었다.불변식 인용 시 엔티티를 함께 적는다. 이 문서 집합에는 이름이 겹치는 불변식이 있다 — Workspace 불변식2(seed:74, 승인 대기 중 잠금 미유지)와 DelegatedTask 불변식2(seed:83, 사람승인 모드 전이)는 서로 다른 조항이다. 아래에서는 항상 엔티티명을 붙인다.
자기 문서의 구조 카운트도 같은 규율을 받는다. 위 열거량은 본문에서 직접 계수했다. 초안이 적었던
FP-001~FP-058(58건)·입력 순열 22행·진리표 47행은 원문과 일치하지 않아 정정했다 — 자기 내용을 세는 자리가 가장 검증하기 쉬운 자리이며, 그 자리에서 틀리면 나머지 계수의 신뢰도가 함께 무너진다.
0. 먼저 — 이 분석의 최상위 발견
Planning 게이트가 지적한 "대기→실행중→자가검증중 전이 조건 미규정"은 증상이지 원인이 아니다.
grep 으로 확인한 사실:
| 확인 항목 | 결과 |
|---|---|
대기·실행중·자가검증중이 seed-spec 에 등장하는 위치 |
79행(status 값 집합) 단 한 곳. 114행·122행의 "대기"는 동사(대기하며/무한 대기하지 않는다), 8행의 "재평가 대기"는 메타데이터 서술이며 어느 것도 status 값이 아니다 |
| §3 DelegatedTask 불변식 5개(seed:82~86)가 명시하는 출발 상태 | 0개. 전부 도착 상태와 조건만 규정한다 |
| AC-01~AC-21 중 전이의 출발 상태를 명시한 것 | 0개. 단 상태를 쓰는 AC 는 둘 있다 — AC-10(seed:112)은 "사람승인대기"에 머물며로 체류 상태를, AC-19(seed:121)는 Given 작업이 "실패"로 전이했을 때로 읽기 규칙의 전제 상태를 쓴다. 둘 다 전이의 출발 상태를 지정하지는 않는다 |
결론: Seed Spec 은 7개 상태를 선언하지만, 어떤 전이 규칙도 출발 상태를 지정하지 않는다. 그 결과 상태 3종(대기·실행중·자가검증중)은 Seed Spec 의 어떤 규칙에서도 참조되지 않는 고아 상태이며, 초기 상태도 규정되지 않았다(AC-17(seed:119)은 새 작업의 completion_mode 기본값만 규정하고 초기 status는 규정하지 않는다).
⚠ 이 공백은 이미 하류에서 조용히 메워졌다 — 그것이 실질 위험이다. BDD 는 규칙이 없는 채로 출발 상태를 전제로 쓰기 시작했다: Feature 4 의
[AC-07] 재시도가 3회를 초과하면…·[AC-07] retry_count 가 3 인 동안에는…·[AC-08] 단일 자가 검증 시도가…세 시나리오가 모두Given 작업 "T" 의 status 가 "자가검증중" 이다로 시작한다. Seed Spec 이 규정한 적 없는 상태 배치가 인수 계약 후보 문서에 먼저 굳은 것이다. C-1 을 먼저 확정해야 하는 이유가 추상적 완전성이 아니라 이것이다.
이것이 아래 모든 Critical 누락의 공통 뿌리다.
1. 기법 ① — 상태 전이 매핑
1.1 전이 규칙 인벤토리 (스펙에 존재하는 것 전부)
| # | 도착 상태 | 조건 | 출발 상태 | 근거 |
|---|---|---|---|---|
| T-1 | 완료 | completion_mode=자가검증 ∧ C-04 방법 중 적용 가능한 것 1종 이상 통과 ∧ verification_log 기록 |
미규정 | seed:82(DelegatedTask 불변식1), seed:111(AC-09) |
| T-2 | 사람승인대기(완료승인) |
completion_mode=사람승인 ∧ 에이전트가 편집을 마침 |
미규정 | seed:83(DelegatedTask 불변식2), seed:112(AC-10) |
| T-3 | 사람승인대기(테스트변경승인) |
기존 테스트 파일 변경 포함 ∧ 적용 직전 (completion_mode 무관) | 미규정 | seed:84(DelegatedTask 불변식3), seed:113(AC-11) |
| T-4 | 실패 | retry_count > 3 |
미규정 | seed:85(DelegatedTask 불변식4), seed:109(AC-07) |
| T-5 | 실패 | 단일 자가 검증 시도가 시간 상한 초과 | 미규정 | seed:85. ⚠ AC-08(seed:110)은 "실패로 기록"이라 전이와 범위가 다르다 — prd:470 미결 B |
| T-6 | 종결 상태(→ 실패로 연역) | 프로바이더/ACP 에이전트 응답 불가 감지 | 미규정 | seed:122(AC-20) ∩ DelegatedTask 불변식1·2·5 → prd:371~375 연역. 감지 기준 미정(prd:630 D-3). ⚠ AC-20 의 Given 은 "작업 도중"이므로 아직 시작되지 않은 작업에는 미치지 않는다고 읽는 것이 자연스러우나, 그 한정이 문면에 없다 |
| T-7 | 롤백됨 | 사용자의 명시적 롤백 요청 (필요조건만) | 미규정 | seed:86(DelegatedTask 불변식5) |
| T-8 | 완료 | 사람승인대기에서 사용자의 명시적 승인 | 사람승인대기 — 단 AC-10 이 명시한 것은 체류이지 출발이 아니다. 출발 상태로 읽는 것은 이 문서의 독법 | seed:112(AC-10) |
1.2 전이 행렬 (7×7 = 49칸)
행=출발, 열=도착. W대기 R실행중 V자가검증중 P사람승인대기 C완료 F실패 B롤백됨
| ↓출발 \ 도착→ | W | R | V | P | C | F | B |
|---|---|---|---|---|---|---|---|
| W 대기 | — | N1 | · | · | !1 | R?(T-6) | N7 |
| R 실행중 | N9 | — | N2 | R(T-3) | !1 | R(T-6) N5 | R(T-7) N8 |
| V 자가검증중 | · | N3 | N3 | R(T-2,T-3) | R(T-1) | R(T-4,T-5,T-6) | R(T-7) |
| P 사람승인대기 | · | N4 | N4 | !2 | R(T-8) | N6 | R(T-7) |
| C 완료 | · | · | · | · | — | · | R(T-7)·prd:467 |
| F 실패 | · | N10 | · | · | · | — | R(seed:121 AC-19 + T-7) |
| B 롤백됨 | · | · | · | · | · | · | — |
범례
- R = 스펙 규칙이 이 칸을 덮는다. 단 출발 상태는 스펙에 없으므로 행 배치는 이 문서의 독법이다.
- R? = 규칙의 Given 한정("작업 도중")이 이 행에 미치는지 문면상 불분명한 칸.
- N = 제품이 성립하려면 필요하나 어떤 규칙도 덮지 않는다(미규정).
- ! = 규칙이 배제하지 않는 부적절한 전이(구멍).
- · = 이 문서 판단으로 도달 불필요. 스펙이 금지한 것은 아니다.
미규정 칸(N) 목록 — 10건
| ID | 전이 | 왜 필요한가 | 스펙 근거 부재 확인 |
|---|---|---|---|
| N1 | 대기 → 실행중 | 작업이 시작되는 유일한 경로 | prd:436 "스펙이 전이 조건을 규정하지 않음" |
| N2 | 실행중 → 자가검증중 | 자가 검증이 시작되는 경로 | 동일 |
| ~~N3~~ 확정 (#16) | 자가검증중 → 실행중 (자기 루프 금지) | 재시도가 되돌아가는 상태 = 실행중. retry_count 는 그 전이 시점에 1 증가 |
docs/state-machine-cocode.md §3 (전이 ⑧). 이 확정이 #20 의 시도 경계 정의를 잠정이 아닌 확정으로 만든다 |
| N4 | 사람승인대기 → 실행중/자가검증중 | 테스트변경승인 후 작업 재개 | prd:500 미결 A, prd:661 |
| N5 | 실행중 → 실패 (시간 초과) | 편집 단계에는 시간 상한이 없다 — AC-08(seed:110)은 "자가 검증 시도"에만 걸린다 | seed:110 문면 |
| N6 | 사람승인대기 → 실패/기타 | 사용자가 승인도 롤백도 하지 않을 때. seed-spec 에 거부 0회·취소 0회(grep 확인) |
prd:487, bdd:794 |
| N7 | 대기 → 롤백됨 | 편집 0건 작업에 롤백 요청 시 | DelegatedTask 불변식5는 필요조건만 |
| N8 | 실행중 → 롤백됨 | 에이전트가 편집을 계속하는 중의 롤백 | 미규정 |
| N9 | 실행중 → 대기 | 잠금 대기 시 대기 값을 재사용하는가 |
bdd:107 U-11 "대기 중 두 번째 작업의 status 미규정" |
| N10 | 실패 → 실행중 | 수동 재개. AC-07(seed:109)은 자동 재시도만 금지한다 | 미규정 |
구멍(!) 2건
- !1 — 대기/실행중 → 완료 직행 (
completion_mode=자가검증에 한정). DelegatedTask 불변식1(seed:82)은 완료의 조건만 규정하고 경유 상태를 요구하지 않는다. 자가검증중을 거치지 않고 완료에 도달하는 구현이 이 불변식을 위반하지 않는다.사람승인모드에서는 이 구멍이 없다 — AC-10(seed:112)이 "사람승인대기에 머물며"로 경유를 강제한다. - !2 — 사람승인대기 → 사람승인대기(승인 종류 전환).
pending_approval_kind(seed:78)는 값 하나만 갖는 enum 이고, 두 승인의 순서가 규정되지 않아 동시 발생이 배제되지도 않았다. §4 C-2 참조.
2. 기법 ② — 입력 순열 행렬
Seed Spec 이 정의하는 사용자 입력과 그 순열(11행). 유효/경계/무효/동시 4축.
| 입력 | 유효 | 경계 | 무효 | 동시·반복 | 스펙 규정 |
|---|---|---|---|---|---|
작업 생성 prompt |
일반 문자열 | 빈 문자열 / 초장문 / 한글·IME 조합 중 확정 | — | 연타로 중복 작업 생성 | 없음 (seed:78 에 속성만) |
completion_mode 지정 |
자가검증 / 사람승인 | AC-17 발동 상태에서 사용자가 자가검증 지정 |
— | — | 기본값만(AC-17). override 미규정(prd:645 D-18) |
agent_backend_kind × provider |
cocode_agent×2종 이상 / cocode_acp×1종 이상 | 미인증·미설치 provider | 존재하지 않는 provider | 실행 중 변경 | AC-06(seed:108)만. 인증 흐름 UI 는 pi:§5.3 미정 |
승인 (완료승인) |
승인 | — | ✅ 거부 입력이 생겼다 — D-032(seed v3.3.0)가 AC-23 을 신설했다. 초판의 「입력 자체가 없음」은 그 이전 기술이다 | 더블 클릭 → ✅ no-op 흡수(D-058 / prd FR-405) |
AC-10 · AC-23 · D-058 |
승인 (테스트변경승인) |
승인 | ✅ 작업 1건 단위(UX-D-13) · 부분 승인 금지(D-058 §3 / prd FR-409) |
✅ [적용하지 않음] = 거부 입력 → 거부됨(D-058 §2 / FR-407). 「미승인 방치」는 D-032 이후 불완전한 기술이다 |
✅ 나중 승인이 충돌로 떨어진다(D-058 §4 — 앞 승인 적용으로 base 가 달라진다) | AC-11 · AC-23 · D-057(C-3) · D-058 |
| 롤백 지점 선택 | 특정 EditSnapshot | 최소 sequence_no(=작업 시작 직전과 동치) / 최대 sequence_no(되돌릴 대상이 자기 하나) | ✅ 이미 롤백된 지점 재선택 → no-op 흡수(D-058 / FR-408) | ✅ 롤백 중 재롤백 → 같음(멱등 — DD-25 R4 · DD-11 7단계) | AC-02(seed:104), EditSnapshot 불변식4(seed:95) · D-058 |
| 작업 열기(diff) | 편집 N건 | 편집 0건 — ⚠ 이 경우는 AC-01 의 Given("에이전트가 파일을 편집한 DelegatedTask가 존재할 때")을 충족하지 않으므로 AC-01 의 사정 밖이다 | — | 실행 중 열기(bdd Feature1 이 커버) | AC-01(seed:103) |
| 에디터 직접 편집 | 임의 | 에이전트 편집을 사람이 되돌려 에이전트 결과와 동일한 해시로 복귀 | — | 에이전트 편집과 동시 | C-02 Rationale(seed:61) — EditSnapshot 대상 아님 |
| 워크스페이스 생성 | brick + 변수 | 변수 검증 실패 | Dart/Flutter 아닌 타입 선택 | — | AC-05·AC-13. "진행 중 실패" 정의 확정 — D-049(위치 기준 [첫 스테이징 쓰기, 커밋 완료)). 변수 검증 실패는 첫 쓰기 이전이면 착수 전 거부라 이 행의 실패 경로가 아니다 |
| 설정 변경(시간 상한) | 양의 유한값 | 0 / 음수 — AC-08 의 "양의 유한한 시간값" 문면은 설치 직후에 걸려 있어 사용자 설정값에 대한 규정이 없다 | 무한대 — AC-08 이 명시적으로 배제한다("미설정·무한대는 허용하지 않는다") | 작업 실행 중 변경 | AC-08. 실행 중 변경의 반영 시점은 미규정 |
| 작업 취소·중지 | — | — | — | — | 입력 자체가 스펙에 없다 (취소 0회, grep 확인) |
사람이 자리를 비운 동안에는 사용자 입력을 기대할 수 없다 — C-04(seed:63)가 규정한 비동기 위임 모델의 귀결이다(입력이 정의상 금지되는 것이 아니라, 도착을 보장할 수 없다). 따라서 아래 §3·§4 의 자동 분기가 유일한 방어선이다.
3. 기법 ③ — 조건 분기 열거
T-A. 사람 부재 중 4대 분기 (과제 지정 항목) — 12행
| ID | 사건 | 스펙이 규정한 결과 | 미규정 | 등급 |
|---|---|---|---|---|
| FP-101 | 자가 검증 실패 누적 retry_count=3 |
실패 아님 (DelegatedTask 불변식4는 "3을 초과") | — | 커버됨(bdd Feature4 경계값 시나리오) |
| FP-102 | retry_count > 3 |
실패 전이 + 에스컬레이션 + 자동 재시도 중단 | 어느 상태에서 실패로 가는가(N3) | 커버됨 |
| FP-103 | 3회 재시도 중 각 시도가 남긴 편집의 처분 | 누적 — 되돌리지 않는다(D-030) | 해소 (#20) — seed-spec §3 EditSnapshot 이 attempt_no 를 신설하고 「시도 경계 롤백」 규칙(ⓐ시도 k 시작 직전 ⓑ시도 k 가 남긴 편집만 ⓒ작업 시작 직전)을 규정한다. 4세트는 여전히 누적되지만 이제 구분된다 — 되감기가 아니라 표시로 푼 것이 D-030 의 선택이다 |
~~I-5~~ 해소 |
| FP-104 | 단일 자가 검증 시도 시간 상한 초과 | 시도 중단 + (DelegatedTask 불변식4)실패 전이 | AC-08 은 "기록", 불변식4는 "전이" — 범위 차이(prd:470 미결 B). 중단된 시도의 부분 편집 처분 미규정 | I-8 |
| FP-105 | 편집 단계(실행중)에서 에이전트가 매달림 | ✅ DD-22 S2(단계를 가리지 않는 유휴 초과) + AC-22 중지 입력 | ✅ 해소(D-059 §1.1) — 자동 상한을 두지 않는다. 조용한 매달림은 S2 가 덮고 「이벤트를 내며 진전 없음」만 남아 중지 입력이 덮는다. ⬜ 무인 구간의 잔여 위험은 오너 판정(B-07) | C-5 |
| FP-106 | 작업 전체의 시간 총량 | ✅ 구간별로 유한 — 자가검증 ≤ 60분(D-033 × 4, D-056) · 환경 재실행 유한(D-055 §5) · 잠금 대기 구조적 유한(#77) | ✅ 해소(D-059 §1.2) — 총량 상한을 두지 않는다. 남은 무한은 편집 축 하나이고 §1.1 이 처분했다. 총량 시계는 같은 공백에 두 번째 근거 없는 값을 걸고, 어느 규칙도 어기지 않은 작업을 임의 시각에 끊는다 | C-5 |
| FP-107 | 프로바이더 응답 불가 감지 | 종결 상태 전이(→실패로 연역) + 사유 제시 | ✅ 해소(D-059 §1.3) — DD-22 로 이미 덮인다: S1(TransportClosed) ∪ S2(유휴 초과), 둘 다 판정 없는 신호. ⬜ 잔여 둘은 범위 밖 — 유휴 상한 값(#50, AC-08 을 시드로) · DD-22 비준(#112) |
C-5 |
| FP-108 | 에이전트 프로세스 비정상 종료 | 잠금 해제만(AC-18, seed:120) | 작업 자신의 status 미규정(prd:536 미결 A). 실행중에 잔류하면 AC-19(실패 작업의 diff·롤백)도 AC-20 도 적용되지 않는다 | C-8 |
| FP-109 | 비정상 종료 시점에 파일은 썼고 EditSnapshot 은 못 남긴 경우 | 없음 | C-02(seed:61)는 "EditSnapshot 없는 편집 경로는 존재하지 않는다"를 요구하지만 쓰기 순서·원자성을 규정하지 않는다 | C-7 |
| FP-110 | acp 에이전트 프로세스 사망 | AC-18(잠금)과 AC-20(응답 불가)이 같은 사건에 각각 다른 결과를 규정 | 어느 쪽이 이 사건을 담당하는가 미규정. AC-20 이 프로세스 사망을 "응답 불가"에 포함하지 않으면 FP-108 의 영구 잔류가 발생 | C-8 |
| FP-111 | 네트워크 단절로 빌드 실패(C-04 ①) | failure:env_network_unreachable 로 분류 → retry_count 를 소진하지 않고 별도 환경 상한을 쓴다 |
✅ 해소(D-055, #73) — docs/verification-failure-class-cocode.md §3(분류 폐쇄 5종·판정 절차) · §4(값별 계수). allowed_hosts 차단은 별개 값 failure:policy_host_blocked 이며 프록시 403 ↔ 502 로 갈린다(같은 문서 §3.1) |
I-8 |
| FP-112 | 부재 중 사람승인대기 진입 | 승인 없이 완료 불가(AC-10) | 무기한 체류. 알림·타임아웃 없음(N6) | I-2 |
T-B. completion_mode × 테스트변경 × 자가검증 결과 진리표 — 12행
| # | completion_mode | 기존 테스트 변경 | 자가검증 결과 | 스펙이 정한 종착 | 미규정 |
|---|---|---|---|---|---|
| FP-201 | 자가검증 | 없음 | ①~④ 중 1종 통과 | 완료 | — |
| FP-202 | 자가검증 | 없음 | ①~④ 전부 적용 불가 → ⑤ 통과 | 완료(사유 코드 기록) | ①~④ "적용 불가" 판정 규칙(prd:629 D-2) |
| FP-203 | 자가검증 | 없음 | 통과 0건 | 완료 아님 | 후속 status 미규정(bdd:466) |
| FP-204 | 자가검증 | 있음 | 통과 | 승인 전 사람승인대기(테스트변경승인) → 승인 → ? → 완료 | 승인 후 복귀 상태(N4), pending_approval_kind를 없음으로 되돌리는 규칙 |
| FP-205 | 자가검증 | 있음 | 미승인 | 변경 미적용 | 작업이 어디에 머무는가 미규정 |
| FP-206 | 사람승인 | 없음 | 통과 | 사람승인대기(완료승인) → 승인 → 완료 | — |
| FP-207 | 사람승인 | 없음 | 실패 | 사람승인대기(완료승인) — 검증은 정보(DelegatedTask 불변식2) | 실패한 검증에도 승인 시 완료. 의도된 동작임을 Design 이 확인해야 함 |
| FP-208 | 사람승인 | 있음 | 임의 | 승인 2종이 모두 필요 | ✅ 해소(D-057, #70) — 순서는 테스트변경승인 → 완료승인(적용이 편집 완료보다 앞서므로 정의에서 따라온다. 단일 값 enum 으로 충분) · 복귀는 항상 실행중(테스트 대상이 바뀌었으므로 자가 검증을 다시 탄다, retry_count 불변) · 리셋은 엔티티 생성자가 강제한다 |
| FP-209 | 임의 | 있음(복수 파일) | 임의 | 작업별(UX-D-13) | ✅ 해소(D-058) — 승인은 작업 1건 단위이고 부분 승인은 금지(prd FR-409). 표현할 자리(pending_approval_kind 폐쇄)도 부분 적용 어휘도 없고, C-05 가 없앤 파일별 판정을 되살린다 |
| FP-210 | 임의 | 있음 | — | 승인 대기 중 잠금 해제(Workspace 불변식2, seed:74) | ✅ 해소(D-057, #70) — 적용 직전 (경로, 투영 전이) 단위 재검사, 다르면 자동 적용하지 않고 충돌 제시(DD-25 R4 와 같은 논거 — 결과적으로 같아도 충돌). 검사는 리스 안이라 창이 없다 |
| FP-211 | 자가검증(override) | — | — | — | override 가능 여부 자체가 미규정(prd:645 D-18) |
| FP-212 | C-04 전환 조항 3상황 중 하나 | — | — | 새 작업 기본값 사람승인 |
⚠ AC-17 문면은 2상황(기준 미설정 · 검증 미수행)이며 세 번째(기준 미달)는 C-04 본문(seed:63)에서 온다 — bdd Feature 4 의 Outline 주석이 이 출처 분리를 직접 명시한다. 3행 전부 커버됨 |
T-C. 롤백 충돌 진리표 (과제 지정 항목: 충돌 × 다중 파일 × 부분 실패) — 11행
v3.1.0(seed:172 ①)이 충돌 판정을 **현재 해시 ≠ 그 파일의 마지막 EditSnapshot 의 result_content_hash**로 교체했다(seed:93, seed:104).
| # | 파일 수 | 사람 직접 편집 | 다른 작업이 그 사이 편집 | 파일 존재 | 스펙 결과 | 미규정 |
|---|---|---|---|---|---|---|
| FP-301 | 1 | 없음 | 없음 | 존재 | 자동 적용 | — |
| FP-302 | 1 | 있음 | 없음 | 존재 | 충돌 제시 | 충돌 후 선택지(prd:514) |
| FP-303 | N | 1건만 충돌 | 없음 | 존재 | 전량 미적용(AC-02 + EditSnapshot 불변식3 결합) | bdd Feature1 이 커버 |
| FP-304 | 1 | 없음 | 있음(T2가 순차 편집) | 존재 | 충돌로 잡히지 않는다 | seed:93·104 가 "그 파일에 대한 가장 마지막 EditSnapshot"이라 쓰고 작업 범위를 한정하지 않는다. 현재 해시 = T2 의 result_content_hash 이므로 일치 판정 → 자동 적용 → T2 의 편집이 조용히 소멸 |
| FP-305 | 1 | 있었으나 에이전트 결과와 동일한 해시로 복귀(사람이 자기 편집을 되돌림) | 없음 | 존재 | 자동 적용 | 현재 해시 = result_content_hash 이므로 안전 — 결함 아님. ⚠ 사람이 에이전트 편집 이전 원본으로 되돌린 경우는 다르다: 현재 해시 = base_content_hash ≠ result 이므로 충돌로 제시된다(FP-302 와 같은 칸) |
| FP-306 | 1 | — | — | 삭제됨 | 해소 (#28) — 삭제 스냅샷은 (H→∅). 현재 상태가 ∅ 이면 일치(복원 = blob H 재생성), 파일이 다시 있으면 충돌 | architecture §4.7 DD-25 R1·R4 |
| FP-307 | 1 (에이전트가 생성한 파일) | — | — | 존재 | 해소 (#28) — 생성 스냅샷은 (∅→H). 롤백 = ∅ 로 복원 = 삭제. 현재 ≠ H(사람이 고쳤거나 지웠거나)면 충돌 | architecture §4.7 DD-25 R1·R4. AC-11 예외(생성)는 R6 이 투영 전이 단위로 판정 |
| FP-308 | N | 없음 | 없음 | 존재 | 원자적 적용 | 적용 도중 중단 시의 원자성 구현(저널·2단계 커밋) 미규정 |
| FP-309 | 1 | — | — | 보존 정책으로 스냅샷 삭제됨 | 없음 | C-02(seed:61)는 "작업 시작 직전 상태를 포함해 임의의 EditSnapshot 경계 시점으로 되돌릴 수 있다"를 무조건 보장한다 |
| FP-310 | 1 | — | 다른 작업이 편집 중(쓰기 진행 중) | 존재 | 없음 — edit_locks는 사용자 롤백을 막지 않는다(seed:70: "에이전트가 현재 편집 중인 파일 경로 집합") |
레이스 |
| FP-311 | 부분 롤백(sequence_no 1 남기고 2·3만 되돌림) | — | — | — | 원자적 적용 | 작업의 status 가 롤백됨이 되는지 미규정 — bdd:152~154 가 이 공백을 이미 문서화하고 단언을 회피했다 |
T-D. AC-12 잠금 타이밍 진리표 (과제 지정 항목) — 9행
| # | 상황 | 스펙 결과 | 미규정 |
|---|---|---|---|
| FP-401 | T1 이 a.dart 편집 중, T2 가 a.dart 접근 | T2 대기, 동시 편집 없음(AC-12) | 해소 (#77) — 대기열 규칙은 status 값에 의존하지 않는다(판정 입력은 큐 조회 + editLocks 의 ownerTaskId 대조). U-11 의 값 결정은 #16 소유이며 docs/edit-lock-queue-cocode.md §1 이 인용만 한다. ⚠️ #76(D-045)이 획득을 편집 시도 시점으로 확정해 대기하는 작업은 이미 실행중 이다 — #16 §4 의 전이 함의 문장은 갱신 요청 대상 |
| FP-402 | T1 이 a.dart 편집 종료 | 잠금 해제, T2 진행 | 해소 (#76, D-045) — 「편집을 마치는 시점」 = 그 편집의 게이트 연산이 반환하는 순간(D-14 후보 ③). docs/edit-lock-lifecycle-cocode.md §2 |
| FP-403 | 잠금 획득 시점 | 게이트 연산 직전 | 해소 (#76, D-045) — 편집 시도 시점(후보 ⓐ). 일괄 예약은 작업 시작 시점에 편집할 파일 집합의 출처가 없어 성립하지 않는다 |
| FP-404 | T1 이 승인 대기 진입 | 잠금 해제(Workspace 불변식2, seed:74) | T1 의 미적용 변경을 edit_locks가 표현하지 못한다 → FP-210(C-3)의 원인 |
| FP-405 | T1: a잠금+b대기 / T2: b잠금+a대기 | 정렬 획득으로 성립 불가 | 해소 (#77 · 기전 정정 #75) — 한 연산이 요구하는 모든 경로(FileEditOperation.touchedPaths)를 전부-아니면-전무로 획득한다. 리스를 든 채 기다리는 작업이 없으므로 순환 대기가 성립할 수 없고, 추월 예외가 필요 없어 엄격 FIFO 가 유지된다(기아도 함께 닫힌다). ⚠️ #77 초판의 「정렬해 하나씩 획득」은 포함 충돌에서 성립하지 않는다 — 구현 리뷰가 교착 3종을 재현했다. ⚠️ 별개로, 디렉터리 연산은 리스 1개를 들면서 하위 파일 N개를 한 커밋에 담으므로 충돌 판정을 경로 포함 관계로 둔다 — 정확 일치만 보면 delete(dir) 중에 하위 파일 쓰기가 통과해 동시 편집이 된다(edit-lock-queue-cocode.md §3.1). 검출기를 두지 않는다 — 예방이 성립하면 도달 불가 코드이고, 희생자 선택 규칙의 근거도 없다. docs/edit-lock-queue-cocode.md §3 |
| FP-406 | 잠금 해제 시 대기자 복수 | 경로별 FIFO | 해소 (#77) — 우선순위는 DelegatedTask 속성 10종에 근거가 없어 기각. FIFO 는 앞 순번이 단조 감소하고 리스 구간이 유한하므로(게이트 연산 1회) 기아가 자료구조로 닫힌다. docs/edit-lock-queue-cocode.md §2 |
| FP-407 | T1 프로세스 비정상 종료 | 잠금 해제(AC-18) | 감지 기준(prd:640 D-13) |
| FP-408 | ADE 자체 재시작 | 잔존 리스 전부 무효(DD-13 트리거 3) + 스윕 뒤에만 잠금 칸 렌더 | 해소 (#75 구현 · #78 검증 · D-048) — 디스크에 남은 리스는 어떤 작업에도 잠금을 주지 않고(유령 잠금 없음), 재기동 후 새로 시작된 두 작업에는 배타가 그대로 걸린다(잠금 소실 없음). 해석 불가한 잔존 파일도 폐기한다 — 깨진 파일이 경로를 영원히 잠그면 그것이 최악의 유령 잠금이다. ⚠️ 「재기동 후 기존 작업이 이어서 실행되는지」는 여전히 미정이라 그 전제를 쓰지 않았다 |
| FP-409 | 두 작업이 같은 기존 테스트 파일을 각각 승인 대기 | ✅ 있음 — forward apply 재검사(D-057 §5) | ✅ 해소(D-058 §4) — 앞 승인이 적용되면 그 경로의 현재 해시가 바뀌어 뒤 승인의 사전검사가 충돌로 떨어진다. 관찰 조건: 「적용 시점의 현재 해시 ≠ 승인 시점 base 이면 적용되지 않는다」. 순서가 뒤집혀도 대칭이고 동시 도착은 리스가 직렬화한다 |
4. 과제 지정 질문에 대한 직접 답변
Q. completion_mode가 실행 중 전환되는 경우가 있는가 — C-04 전환 조항은 작업 생성 시점 기준인가?
답: 인수 기준 수준에서는 생성 시점 기준이 유일하게 규정된 것이며, 실행 중 전환은 규정도 금지도 되어 있지 않다.
근거 3건(전부 원문 확인):
- AC-17(seed:119) —
When 새 DelegatedTask 가 생성되면, Then completion_mode 의 기본값은 사람승인이며→ 판정 시점이 생성 시점으로 못 박혀 있다. 이것이 전환 조항에 붙은 유일한 인수 기준이다. - C-04 전환 조항(seed:63) —
기본 완료 모드는 "사람 승인 후 완료"로 전환된다. 시점을 말하지 않는다. 그리고 "기본 모드"는 시스템 수준 기본값이지 인스턴스 속성이 아니다. - §3 DelegatedTask(seed:78) —
completion_mode는 인스턴스 속성이다. 속성값의 변경 가능 여부에 대한 불변식은 없다(seed:82~86 5개 중 해당 항목 없음).
즉 "기본 모드"(시스템)와 "completion_mode"(인스턴스)가 서로 다른 층위인데 전환 조항이 둘을 잇는 규칙을 쓰지 않았다. 결과적으로 미규정 시나리오 3종:
| # | 시나리오 | 현재 스펙의 답 |
|---|---|---|
| FP-501 | A-02 스파이크 결과가 작업 실행 중에 확정되어 기본 모드가 바뀜 | 없음 — 진행 중 작업의 completion_mode가 재평가되는지 |
| FP-502 | 사용자가 개별 작업에서 기본값을 뒤집음 | 없음 — prd:645 D-18 이 이미 "override 가능 여부 미규정"으로 등록 |
| FP-503 | 실행 중 agent_backend_provider 변경이 모드에 영향을 주는가 |
없음 |
권고(판정이 필요 없는 규칙). completion_mode는 작업 생성 시점에 1회 평가해 인스턴스에 고정하고 이후 불변으로 둔다. 이 규칙은 ⓐ AC-17 의 문면과 정확히 일치하고 ⓑ C-04 본문("기본 모드")과 모순되지 않으며 ⓒ 실행 중 재평가가 만드는 모든 조합(FP-501)을 소멸시킨다.
⚠ 이 권고는 안전 방향이 아니다 — 그것이 오너 판단을 요구하는 이유다. 잔여 위험은 스파이크 미달 판정 전에 생성된 진행 중 작업이 자가검증만으로 완료될 수 있다는 것이며, C-04 가 전환 조항을 둔 취지("기준 미설정 시의 기본값은 안전한 쪽")와 방향이 어긋난다. 대안은 "전환 발동 시 진행 중 작업도 사람승인으로 승격"이며, 이쪽은 안전하지만 실행 중 상태 변경 조합(FP-501)을 되살린다. 값이 아니라 정책 판단이므로 프로젝트 오너 또는 Design 이 D-18 과 함께 결정해야 한다. 이 문서는 어느 쪽도 확정하지 않는다.
5. 기법 ④ — 오류 복구 경로 (9종)
| 오류 상태 | 재시도 | 대체 동작 | 탈출 경로 | 부분 완료 처분 | 미규정 |
|---|---|---|---|---|---|
| 자가 검증 실패 | 최대 3회(AC-07) | — | 실패 전이 + 에스컬레이션 | 그때까지 편집 유지 | 재시도 복귀 상태(N3), 시도 경계 식별(I-5) |
| 시간 상한 초과 | 없음 | — | 실패 전이 | 미규정 | AC-08 "기록" vs DelegatedTask 불변식4 "전이"(prd:470) |
| 프로바이더 응답 불가 | 없음 | — | 종결 전이 + 사유 제시 | AC-19 가 diff·롤백 보장 | 감지 기준(D-3), 재연결·백오프 없음 |
| 에이전트 프로세스 사망 | 없음 | — | 잠금 해제만 | 미규정 | 작업 status(C-8), 스냅샷 기록 누락 창(C-7) |
| 실패 상태 | 자동 금지(AC-07) | — | ⓐ 롤백 → 롤백됨 ⓑ 편집 유지 | AC-19 보장 | 수동 재개(N10), "조용히"의 판정 기준(prd:642 D-15) |
| 롤백 충돌 | — | 자동 적용 금지 + 충돌 제시 | 미규정 | 전량 미적용(원자성) | 선택지(강제/파일별/취소) — prd:514 |
| 롤백 적용 중단 | — | — | 미규정 | 미규정 | 원자성 구현 수단(C-7) |
| 스캐폴딩 실패 | — | 전량 제거 | 워크스페이스 미생성(AC-13) | 없음 | ✅ "진행 중 실패"의 정의 = D-049(#41) · 사유 제시 형태 = UX-D-23(폐쇄 코드 5종 + 「아무것도 만들어지지 않았습니다」 고정 문구) |
| 샌드박스 위반 시도 | — | 차단(AC-14) | — | — | 차단 후 작업 진행 여부, 미지 리다이렉트 처리(prd:649 D-22) |
6. 누락 분류
6.1 Critical — 구현 차단 (8건)
| ID | 누락 | 영향 흐름 | 확인된 근거 |
|---|---|---|---|
| C-1 | 상태 기계에 출발 상태·초기 상태가 하나도 규정되지 않았다. 상태 3종(대기·실행중·자가검증중)이 Seed Spec 의 어떤 규칙에서도 참조되지 않는 고아이고, DelegatedTask 불변식1 이 경유 상태를 요구하지 않아 자가검증 모드에서 대기→완료 직행이 금지되지 않는다. 그 사이 BDD 는 규정 없는 출발 상태를 이미 전제로 쓰고 있다 | 흐름 2·3 전체 | grep: 세 값이 seed:79 에만 등장. 불변식 5개(seed:82~86)·AC 21개 모두 전이의 출발 상태 없음. bdd Feature 4 AC-07·AC-08 시나리오가 Given status 가 "자가검증중" 사용 |
C-2 ✅ 해소 (#70 / D-057 — docs/approval-rules-cocode.md §3) |
승인 2종의 순서·복귀·리셋 규칙이 없다. pending_approval_kind(seed:78)는 값 하나만 갖는 enum 인데, completion_mode=사람승인 ∧ 기존 테스트 변경 포함 작업(FP-208)에서 두 승인이 모두 필요하고 순서가 규정되지 않아 동시 발생이 배제되지 않는다. 승인 후 어느 상태로 복귀하는지(N4), pending_approval_kind를 없음으로 되돌리는 규칙도 없다 — 현행 문면대로 구현하면 승인 뒤 작업이 사람승인대기에 잔류한다. (순차 배치가 가능하므로 "단일 값으로 표현 불가"는 성립하지 않는다 — 결함은 표현력이 아니라 규칙 부재다) |
흐름 3-A·3-B | seed:78(속성 정의), seed:83·84(DelegatedTask 불변식2·3이 같은 status 를 서로 다른 kind로 요구), prd:661 |
C-3 ✅ 해소 (#70 / D-057 — docs/approval-rules-cocode.md §5) |
승인 후 적용(forward apply) 시 충돌 감지 규정이 없다. 승인 대기 중 잠금을 해제하므로(Workspace 불변식2) 그 사이 다른 작업·사람이 같은 파일을 바꿀 수 있다. 충돌 감지는 롤백 시에만 규정된다 | 흐름 3-B, FP-210·FP-409 | seed:74(승인 중 잠금 미유지) vs seed:93(충돌 감지가 "롤백 시"로 한정) |
| C-4 | 롤백 충돌 판정의 "그 파일에 대한 가장 마지막 EditSnapshot"에 작업 범위 한정이 없다. 두 작업이 순차 편집한 뒤 앞 작업을 롤백하면 현재 해시가 뒤 작업의 result_content_hash와 일치하므로 충돌로 잡히지 않고 자동 적용되어 뒤 작업의 편집이 소멸한다. 바로 다음 불변식(seed:94)은 "같은 작업에서"라고 범위를 명시하므로, 이 비대칭은 누락이지 의도가 아니다 |
흐름 4, FP-304 | seed:93·seed:104 문면 vs seed:94. AC-12(seed:114)가 순차 편집을 명시적으로 허용 |
C-5 ✅ 해소 (#71 / D-059 — docs/stop-and-limits-cocode.md) · 잠금 축은 #77 |
부재 중 무한 체류를 막는 상한이 편집 단계·작업 총량·잠금 대기 어디에도 없다. AC-08 은 "자가 검증 시도"에만 걸린다. 유일한 대체 방어인 AC-20 의 감지 기준이 미정. — 잠금 대기 축은 해소됐다: 상한을 두지 않되 그 근거가 「무방비」가 아니라 구조적 유한성이다(교착은 정렬 획득으로 성립 불가 · 기아는 FIFO 로 성립 불가 · 승인 대기는 리스 구간 밖이라 대기열을 잡지 않는다 · 보유자 사망은 DD-13 트리거 3종이 덮는다). docs/edit-lock-queue-cocode.md §4. ✅ 세 축도 #71 이 닫았다(D-059): FP-105 = 자동 상한 없음(조용한 매달림은 DD-22 S2 가 덮고, 「이벤트를 내며 진전 없음」은 AC-22 중지 입력이 덮는다) · FP-106 = 총량 상한 없음(나머지 구간이 이미 유한하고 별도 시계는 근거 없는 두 번째 값을 요구한다) · FP-107 = DD-22 로 이미 덮임(잔여는 값 #50 · 비준 #112). ⚠️ UX-D-06(「작업 중단/취소 버튼을 두지 않는다」)은 D-032 로 폐기됐다 — 그 안전 근거였던 「AC-07·AC-08 이 자동 종료를 보장」은 AC-08 의 Given 이 「자가 검증 시도가 진행 중일 때」(seed:110)로 한정돼 편집 단계·잠금 대기를 덮지 못하므로 성립하지 않는다. ⬜ 남는 위험: 편집 단계 라이브락은 사람이 돌아올 때까지 계속 돈다 — 상한을 AC 로 신설할지는 미정 — 결정 필요(프로젝트 오너, B-07 지정) |
흐름 2 전체, FP-105·106·107, ~~405~~ | seed:110 문면, prd:630 D-3, seed:114(대기 규정에 타임아웃 없음) |
| C-6 | EditSnapshot 보존 정책이 C-02 의 무조건 롤백 보장과 정면 충돌한다. C-02 는 "작업 시작 직전 상태를 포함해 임의의 경계 시점"을 무조건 보장하는데, 어떤 보존 상한도 스냅샷을 삭제한다. 따라서 이 항목은 Design 결정만으로 닫히지 않는다 — 선택지는 ⓐ C-02 를 보존 범위 안으로 한정하는 Seed Spec 개정 ⓑ 삭제하지 않고 용량 위험을 인수(CH-022 의 현 상태 유지) 둘뿐이다 | 흐름 4, FP-309 | seed:61(C-02 문면), contrarian:144 CH-022(Accepted, Design 이관), prd:680 |
| C-7 | 파일 쓰기 ↔ EditSnapshot 기록의 순서·원자성, 그리고 롤백 적용 자체의 원자성이 미규정. 파일 기반 저장(오너 결정 3)에서는 이 둘이 없으면 C-02·AC-02 가 구현 불가 | 흐름 2·4, FP-109·308 | seed:61(C-02 가 결과만 요구), seed:94(원자성 요구하나 수단 없음) |
| C-8 | 비정상 종료한 작업 자신의 status 가 미규정. 실행중에 잔류하면 AC-19(실패 작업의 diff·롤백)도 AC-20 도 적용되지 않아 편집이 무기한 미처분 상태로 남는다. AC-18 과 AC-20 이 같은 사건을 다루는지도 불명 | 흐름 5 별도 경로, FP-108·110 | seed:120(AC-18 은 잠금만), prd:536 미결 A |
6.2 Important (10건)
| ID | 누락 | 근거 |
|---|---|---|
| ~~I-1~~ 해소 (#76 · #77) | 획득 시점 = 편집 시도 시점, 해제 시점 = 게이트 연산의 반환(D-045). 교착은 전부-아니면-전무 획득으로 예방(검출기 없음), 기아는 엄격 FIFO 로 닫힌다 — 둘 다 같은 성질(hold-and-wait 제거)의 따름정리이고, 판정이 아니라 자료구조·계산이다 | docs/edit-lock-lifecycle-cocode.md §1·§2, docs/edit-lock-queue-cocode.md §2·§3, FP-403·405·406 |
| I-2 | 작업 취소·중지 입력이 존재하지 않는다(취소 0회 grep 확인). 사람이 돌아와 잘못된 작업을 멈출 방법이 없다 — 롤백은 편집을 되돌릴 뿐 실행을 멈추지 않는다 |
seed-spec 전문 grep |
| I-3 | completion_mode 실행 중 전환·override(§4 답변) |
AC-17 vs C-04 층위 차이, prd:645 D-18 |
| ~~I-4~~ 해소 (#28) | 생성·삭제·이름변경은 두 해시의 부재값(∅) 과 previous_path 로 표현되고(이름변경 = 스냅샷 1건 · 경로 2개 투영), 불변식 2·4 는 경로별 투영 전이에 적용된다 — architecture §4.7 DD-25. Seed Spec §3 문면 반영은 개정 요청(일지 D-038, 오너 판정) 대기 |
architecture §4.7 DD-25, ux-spec §4.1~§4.3 UX-D-21, FP-306·307 |
| ~~I-5~~ 해소 (#20) | 재시도 시도 간 편집은 누적으로 확정(D-030)되고, 어느 시도의 편집인지는 EditSnapshot 의 attempt_no 가 표현한다. 시도 경계 롤백 규칙(ⓐ시도 k 시작 직전 ⓑ시도 k 가 남긴 편집만 ⓒ작업 시작 직전)이 대상 집합을 유일하게 결정한다 |
seed-spec §3 EditSnapshot(속성 + 「시도 경계 롤백」 표), D-030, FP-103 |
| I-6 | 부분 롤백 후 작업 status | bdd:152~154 가 이 공백을 이미 문서화 |
| ~~I-7~~ 해소 (#75 · #78) | edit_locks 는 locks/edit_locks.json 에 영속하되 시작 시 전부 폐기한다 — 쓰는 이유는 트리거 3 을 관측 가능하게 만들고(없으면 「잔존 리스 전부 무효」가 검증할 대상 없는 문장이 된다) 크래시 시점의 기록을 남기기 위해서다. 유령 잠금도 잠금 소실도 없음을 restart_lock_consistency_test.dart 가 단언한다. 표시 쪽은 D-048 이 순서를 고정했다 |
architecture §4.5 DD-13, docs/decision-log-cocode.md D-048, FP-408 |
| I-8 | ✅ 앞 절반 해소(D-055, #73) — 검증 실패 원인 구분은 docs/verification-failure-class-cocode.md §3·§4 가 failure_class 폐쇄 5종으로 닫았고 환경 문제는 더 이상 retry_count 를 소진하지 않는다. ⬜ 뒤 절반(AC-08 "기록" vs 불변식4 "전이" 범위 차이)은 #67 소관으로 남는다 |
prd:470 미결 B, FP-111, FP-104 |
| I-9 | ✅ 해소 (#72 / D-058) — 입력 4종(완료승인·테스트변경승인·[적용하지 않음]·롤백 지점) 전부 no-op 흡수이고 검사 주체는 TaskTransition(DD-05 — UI 비활성화만으로 구현하지 않는다). docs/approval-idempotency-cocode.md §1 · prd FR-405~FR-408 |
prd FR-405~408, D-058 |
| I-10 | ✅ 해소 (#72 / D-058) — granularity 는 작업 1건 단위(UX-D-13 이 「파일별?」을 기각) 이고 부분 승인은 금지(prd FR-409). 같은 테스트 파일 다중 대기는 나중 승인이 충돌로 떨어진다(D-057 §5 의 forward apply 재검사) |
seed:113 AC-11, FP-209·409, D-057, D-058 |
6.3 Nice-to-have (6건 — N-6 은 #88 이 추가)
| ID | 누락 |
|---|---|
| ~~N-1~~ 해소 (#89 / UX-D-27) | 편집 0건 작업의 diff 화면은 열리고 좌측 목록을 0건으로 그리며 CoUI EmptyState(ux-spec:525)를 표시한다 — 예외를 던지지도 화면을 막지도 않는다. AC-01 의 Given 밖 경계라 BDD 라벨은 [AC-01] 이 아니라 [UX-D-27] 이다. B-16 이 그 시나리오로 작성됐다(bdd Feature 1). ⚠️ 스냅샷 0건 타임라인(S-10)은 이 항목이 아니라 #88 이 §6.3 에 신규 항목으로 더한다 — 관찰 대상이 AC-02 계열로 다르다 |
| ~~N-2~~ 부분 해소 (#89 / UX-D-29) | 빈 문자열 — 해소. trim() 후 비었으면 생성 CTA 가 비활성이고 사유가 필드 옆에 뜬다(길이 검사만으로는 공백만 있는 입력이 통과한다). 초장문 — 미해소: 상한 값이 flow-permutation:124 기준 「스펙 규정 없음」이라 값을 만들지 않고 ux-spec §12 미결로 등재했다. IME 조합 중 제출 — 이 항목 밖이다(ux-spec:640 UX-D-18 I1~I3 이 소유) |
| N-3 | 실패 작업의 수동 재개(AC-07 은 자동 재시도만 금지) |
| ~~N-4~~ 표시 해소 · 규칙 미정 (#89 / UX-D-28) | 표시 — 해소: 되돌릴 대상이 0건이면 되돌리기 버튼이 비활성 + 사유(「선택한 지점 이후에 되돌릴 편집이 없습니다」), 1건이면 스냅샷 1건 · 경로 1개 로 그린다. 두 경우 모두 위젯 테스트로 고정됐다. ⚠️ 어느 쪽이 일어나는지를 정하는 규칙은 이 항목이 아니다 — 「특정 스냅샷으로의 롤백이 그 스냅샷 «자신»을 되돌리는가」가 리포 안에서 갈린다(seed:94 「그 이후 생성된 모든」 ↔ :129 「되돌릴 대상이 자기 하나」 ↔ :289 「no-op」). 그 확정은 별도 결정 항목으로 #24 앞에 세웠고(#89 소유 경계), 이 행의 「no-op」 전제는 아직 비준되지 않았다. 화면은 확정 결과가 어느 쪽이든 옳게 그린다 |
| ~~N-6~~ 해소 (#88 / UX-D-31 ⓒ) | 스냅샷 0건 타임라인(S-10)의 표시 — 「작업 시작 직전 상태」 노드만 그리고 스냅샷 행 0건 + EmptyState.compact + 되돌리기 비활성·사유. ⚠️ N-1 과 같은 근원이지만 관찰 대상이 다르다 — N-1 은 AC-01 계열의 빈 diff 목록(#89 소유)이고 이 항목은 AC-02 계열의 스냅샷 타임라인(#88 소유)이다. 그래서 N-1 을 갱신하지 않고 신규 항목으로 더했다. 비활성 사유 문구는 #89 의 UX-D-28 을 소비한다 |
| ~~N-5~~ 해소 (#77) | 순서는 경로별 FIFO, 화면은 S-06 실행중 행의 잠금 표시를 세 값(잠금 N · 잠금 대기 · 빈칸)으로 넓힌다. 예상 대기는 그리지 않는다 — 계산할 입력이 없다(소요 분포 측정 장치 없음 · DelegatedTask 에 시각 속성 없음). 순번도 그리지 않는다 — 계산은 가능하나 읽는 사람의 행동을 바꾸지 않는다. docs/edit-lock-queue-cocode.md §2·§5 |
7. BDD 시나리오 추천
BDD 문서는 현재 47 시나리오다. 두 경로로 교차 확인했다 — §2 대응표 "시나리오 수" 열 합산(2+4+1+1+2+2+2+2+3+2+5+3+2+6+1+1+2+1+1+1+3 = 47)과 원문 계수(Scenario: 41건 + Scenario Outline: 6건 = 47). 아래는 그 위에 추가할 것이다.
원칙: 규칙이 없으면 시나리오도 쓸 수 없다. Critical 8건은 "시나리오를 추가하라"가 아니라 **"규칙을 먼저 정하고, 그 규칙에 대한 시나리오를 쓰라"**이다. 근거는 이 프로젝트의 기록된 실패 패턴이다 — spec-evaluation:127 이 1번 패턴으로 **"근거 없는 수치 생성"**을, 4번으로 **"인용 오류"**를 든다. 값 생성이 반복된 구간은 v1.1.0~v2.1.0 이며(prd:705), 8 은 평가 라운드 수이지 사건 수가 아니다(prd:267 이 이 혼동을 명시적으로 금지한다). 8 라운드 내내 확인된 것은 "지적된 항목은 고쳐지지만 같은 결함 유형의 새 사례가 생긴다" 는 패턴이다. 규칙 없이 시나리오를 쓰는 것은 그 패턴의 새 사례가 된다 — bdd Feature 4 가 이미 규정 없는
자가검증중을 Given 으로 굳힌 것이 실물 증거다. bdd:796 자신도 "작성되어 있다는 것과 판정할 수 있다는 것은 다르다" 고 적었다.
7.1 Must Have — Critical 해소 직후 작성 (규칙 확정이 선행 조건) — 12건
| # | 시나리오 | 선행 확정 사항 | 확정 주체 | 대응 |
|---|---|---|---|---|
| B-01 | 새 작업이 생성되면 status 가 초기 상태를 갖고, 정해진 경유 상태를 거치지 않으면 "완료"에 도달하지 않는다 | 초기 상태 + 각 전이의 출발 상태 | Design(상태 기계 확정) | C-1, FP-!1 |
| B-02 | 대기/실행중에서 자가 검증 기록 없이 완료 전이를 시도하면 거부된다 | 동일 | Design | C-1 |
| B-03 | 사람승인 모드 작업이 기존 테스트 파일을 바꾸려 하면 두 승인이 정해진 순서로 요구되고, 둘 다 승인되어야 완료에 도달한다 |
✅ 확정(D-057) — 순차 배치(테스트변경승인 먼저) | Design → 완료 | C-2, FP-208 |
| B-04 | 테스트변경승인 후 작업이 정해진 상태로 복귀하고 pending_approval_kind가 없음이 된다 |
복귀 상태(N4) + 리셋 규칙 | Design | C-2, FP-204 |
| B-05 | 승인 대기 중 다른 주체가 같은 파일을 바꾸면, 승인 후 적용은 자동 적용되지 않고 충돌로 제시된다 | ✅ 확정(D-057) — 현재 상태 ≠ 승인 시점 base 이면 충돌(판정 없음) | Design → 완료 | C-3, FP-210 |
| B-06 | 두 작업이 같은 파일을 순차 편집한 뒤 앞 작업을 롤백하면, 뒤 작업의 편집이 소멸하지 않는다 | "마지막 EditSnapshot"의 작업 범위 확정 | Seed Spec 개정 또는 Design(seed:93·104 문면 수정 필요) | C-4, FP-304 |
| B-07 | 편집 단계에서 진전이 없는 작업이 설정된 상한을 넘기면 종결 상태로 전이한다 | ⬜ 미정 — 결정 필요. #71(D-059 §1.1)이 「자동 상한을 두지 않는다」로 결론냈으므로 이 시나리오는 쓰지 않는다(존재하지 않는 규칙을 단언하게 된다 — §7.3 원칙). 그 자리는 AC-22·AC-23 시나리오 3건이 덮는다. 상한이 AC 로 신설되면 그때 쓴다 | 프로젝트 오너(AC-08 과 같은 층위의 인수 기준 신설이 필요) | C-5, FP-105·106 |
| B-08 | 잠금 대기가 상한을 넘기거나 교착이 검출되면 작업이 무한 대기하지 않는다 | ~~교착 정책~~ 해소 (#77) — 상한도 검출기도 없이 그 속성을 만족한다(둘 다 사후 수습 수단인데 예방으로 사후가 발생하지 않는다). 시나리오는 「상한 초과」가 아니라 정렬 획득·FIFO 의 성질을 단언하는 형태로 쓴다 | ~~Design~~ 확정 | ~~C-5~~ 잠금 축, ~~FP-405~~ |
| B-09 | 보존 정책이 삭제할 수 있는 스냅샷의 범위와, 삭제된 작업의 롤백 가능 여부가 UI 에 정확히 반영된다 | C-02 의 무조건 보장을 유지할지 완화할지(§8 머리말) | 프로젝트 오너 + Design | C-6, FP-309 |
| B-10 | 파일 쓰기 직후 프로세스가 죽어도 EditSnapshot 없는 에이전트 편집이 남지 않는다 | 쓰기 순서·원자성 | Design(파일 기반 저장 설계) | C-7, FP-109 |
| B-11 | 롤백 적용 도중 중단되어도 부분 적용 상태가 남지 않는다 | 원자성 구현 수단 | Design | C-7, FP-308 |
| B-12 | 에이전트 프로세스가 비정상 종료하면 작업이 종결 상태로 전이하고 diff·롤백 수단이 제공된다 | 비정상 종료 시 작업 status | Design(prd:640 D-13 과 함께) | C-8, FP-108·110 |
B-09 의 문면이 초안에서 바뀐 이유. 초안은 "보존 정책이 삭제한 스냅샷 때문에 롤백이 불가능해지지 않는다" 로 썼는데, 그것은 §8 R-2·R-5(종결 작업의 스냅샷 삭제 허용, 롤백 불가 표시)와 정면으로 어긋난다. 같은 문서의 두 절이 서로를 반증하면 어느 쪽도 인수 계약이 될 수 없다. C-02 를 유지할지 완화할지가 먼저 정해져야 시나리오 문면이 정해진다.
7.2 Should Have — 기존 규정만으로 지금 쓸 수 있는 것 (4건)
| # | 시나리오 | 근거 | 대응 |
|---|---|---|---|
| B-13 | completion_mode는 작업 생성 시점에 고정되며, 이후 기본 모드가 바뀌어도 진행 중 작업의 값은 바뀌지 않는다 |
AC-17(seed:119)의 생성 시점 문면. ⚠ §4 의 잔여 위험(안전 방향이 아님)이 오너 결정으로 수용된 뒤에만 쓴다 | I-3, FP-501 |
| B-14 | 사람승인 모드에서 자가 검증이 실패해도 사람승인대기에 도달하며, 승인 시 완료된다 |
DelegatedTask 불변식2(seed:83) "자가 검증 결과와 무관하게". bdd 의 기존 AC-10 시나리오는 ①~④ 전부 통과 케이스만 덮으므로 중복이 아니다 | FP-207 |
| B-15 | retry_count가 3인 시점의 편집과 3을 초과한 시점의 편집이 모두 diff 에 나타난다 |
AC-19(seed:121) + C-02(seed:61). ✅ 작성됨 — bdd Feature 1 [AC-19] 재시도가 남긴 모든 시도의 편집이 시도 경계와 함께 제시된다(#20). D-030 이 누적을 확정했으므로 이 문면이 그대로 성립한다 |
I-5(해소), FP-103 |
| B-16 | 편집이 0건인 작업을 열면 빈 diff 목록이 제시되고 오류가 발생하지 않는다 | AC-01(seed:103)의 Given 밖 경계 — 동작 정의가 선행됐다(#89 / UX-D-27). ✅ 작성됨 — bdd Feature 1 [UX-D-27] 편집이 0건인 작업을 열면 빈 diff 목록이 제시되고 오류가 발생하지 않는다. 라벨이 [AC-01] 이 아닌 이유는 이 경계가 그 AC 의 Given 을 충족하지 않기 때문이다 |
N-1(해소) |
초안의 B-17 은 삭제했다 — 이미 존재한다. "사용자가 승인도 롤백도 하지 않은 채 시간이 지나면 작업은 사람승인대기에 머문다" 는 bdd Feature 4 의
[AC-10] 사람승인 모드에서 자가 검증 결과는 정보이지 완료의 관문이 아니다시나리오(When 사용자가 승인하지 않은 채 시간이 지난다→Then status 가 "사람승인대기" 에 머문다)와 동일하다. "유사 1건 존재, 중복 여부 확인 필요"가 아니라 중복이다.
7.3 규칙 확정 없이 시나리오를 쓰지 말 것 (3건)
취소 입력(I-2), 생성·삭제 EditSnapshot(I-4 — 규칙은 #28 DD-25 로 섰다. Seed Spec §3 반영(개정 요청 D-038)이 끝나기 전에는 시나리오를 쓰지 않는다), 승인 granularity(I-10)은 입력·엔티티 자체가 스펙에 없다. 시나리오를 먼저 쓰면 없는 기능을 인수 계약으로 만드는 것이 된다. 순서는 범위 결정 → Seed Spec 또는 PRD 반영 → 시나리오다.
8. CH-022 보존 정책 — 이 설계가 정해야 할 항목 (오너 결정 3)
Contrarian CH-022(contrarian:144)가 Design 으로 미뤄둔 항목이며, 오너 결정 3(파일 기반 저장, Lumide local_history 방식)이 이제 이 설계에 그 결정을 넘겼다.
⚠ 먼저 정해야 할 것은 규칙이 아니라 C-02 의 범위다. C-02(seed:61)는 "작업 시작 직전 상태를 포함해 임의의 EditSnapshot 경계 시점으로 되돌릴 수 있다"를 무조건 보장한다. 스냅샷을 하나라도 지우는 순간 이 보장은 깨진다 — 종결된 작업만 지워도 마찬가지다. 따라서 아래 R-1~R-5 는 C-02 를 "보존 정책이 유지하는 범위 안에서"로 한정하는 Seed Spec 개정이 승인된 뒤에만 성립한다. 개정 없이 채택하면 설계가 불변 층위를 위반한 채 남는다. 대안은 삭제를 하지 않고 용량 위험을 계속 인수하는 것(CH-022 의 현 상태 유지)이며, 어느 쪽을 고를지는 오너 판단이다.
출처가 있는 참조값 1건: Lumide local_history = 파일당 최대 50버전 / 5MB(dl:37 D-003 본문, contrarian:144 에 "참고 기준"으로 재기재). 이것은 Lumide 의 값이지 cocode ADE 의 값이 아니다 — 그대로 채택할 근거는 없다.
이 문서가 제안하는 것은 값이 아니라 규칙의 형태다 (판정이 필요 없도록 구성):
| 규칙 | 이유 | 값 확정 주체 |
|---|---|---|
| R-1. 종결되지 않은 작업(대기·실행중·자가검증중·사람승인대기)의 EditSnapshot 은 보존 상한의 대상이 아니다 | 진행 중 작업에서는 C-02 의 보장을 그대로 유지한다. 상태 판정만으로 결정되므로 내용 판정이 없다 | 규칙 자체는 C-02 에서 연역 — 값 불필요 |
| R-2. 상한은 종결된 작업(완료·실패·롤백됨, seed:30)에만 적용한다 | 손실 범위를 상태로 경계 짓는다. 단 이 규칙은 위 ⚠ 의 C-02 개정을 전제로 한다 | 값 불필요 (전제: 오너 개정 승인) |
R-3. 상한은 파일당 버전 수와 작업당 총 바이트 두 축을 모두 갖는다. 바이트 계수 규칙(무엇을 세는가 — diff 본문의 인코딩 후 바이트인지, 압축 후인지, 메타데이터 포함인지)을 함께 규정한다 |
Lumide 선례가 두 축(50버전/5MB)을 쓴다. 한 축만 두면 큰 파일 1건 또는 작은 파일 수천 건 중 하나를 못 막는다. 계수 규칙이 없으면 prd:633 D-6 이 경고한 "두 구현이 서로 다른 허용 집합을 만든다" 가 용량 축에서 재현된다 — EditSnapshot(seed:89)에 크기 속성이 없으므로 산출 규칙이 필수다 | 값: 프로젝트 오너 또는 Planning — 근거는 A-06 최소 셸 실측(pi:§6 3행) 이후. 계수 규칙: Design |
R-4. 상한 도달 시 삭제 순서는 그 작업의 EditSnapshot 중 최대 timestamp(seed:89) 오름차순이며, 한 작업의 스냅샷은 작업 단위로 통째로 삭제한다 |
부분 삭제는 AC-02 의 "작업 시작 직전 상태" 복원(EditSnapshot 불변식4, seed:95)을 반쯤 깨뜨린 상태를 만든다. 작업 단위 삭제는 "롤백 가능/불가능" 이진 상태만 만든다 | 규칙 자체는 불변식4에서 연역 — 값 불필요 |
| R-5. 스냅샷이 삭제된 작업은 UI 에서 롤백 불가로 표시된다 | AC-19(seed:121)의 "조용히 폐기되지 않는다"와 같은 축 | 표시 방식: Design |
R-4 가 초안에서 바뀐 이유 — 초안 규칙은 실행 불가였다. 초안은 삭제 순서를 "작업 종결 시각 오름차순" 으로 규정했으나, DelegatedTask 에는 시각 속성이 없다. seed:78 의 속성은 task_id · prompt · status · completion_mode · pending_approval_kind · agent_backend_kind · agent_backend_provider · retry_count · verification_log · created_by 10종뿐이며, prd:614 가 이 부재를 이미 기록해 두었다("§3의 DelegatedTask Attributes에 시각 속성이 없다(EditSnapshot에만
timestamp)"). 존재하지 않는 값으로 정렬하라는 규칙은 Planning 게이트가 AC-02 에서 잡아낸 것과 같은 유형(정의되지 않은 값을 판정 기준으로 삼음)이다. 위 R-4 는 실재하는timestamp(seed:89)로 다시 썼다. DelegatedTask 에 종결 시각 속성을 신설하는 §3 개정도 대안이며(§3 머리말은 잠금 후 추가를 허용한다), 어느 쪽이든 Design 이 명시적으로 골라야 한다.
미확정으로 남기는 것: R-3 의 두 수치. 근거 없이 값을 쓰지 않는다 — A-06 스파이크(pi:§6 3행)가 실측치를 내놓기 전에는 Lumide 값을 복사하는 것 외에 근거가 없고, cocode ADE 는 에이전트 런타임을 포함하므로 그 값을 그대로 쓸 근거가 없다(D-013, dl:150 의 동일 논리).
9. Seed Spec 과 어긋나는가 — 명시
이 분석은 Seed Spec v3.1.0 을 뒤집지 않는다. 단 세 곳에서 스펙 문면 자체의 수정 여부를 오너에게 묻는다 — 구현 가능성이 아니라 문면의 결함 또는 범위 결정이기 때문이다:
- seed:93 · seed:104 (EditSnapshot 불변식2 · AC-02) — "그 파일에 대한 가장 마지막 EditSnapshot"의 작업 범위 한정 누락(C-4). 바로 다음 불변식(seed:94)은 "같은 작업에서"라고 범위를 명시하므로 이 비대칭은 누락이지 의도가 아니다. AC-12 가 명시적으로 허용하는 순차 편집과 결합해 편집 소멸을 만든다. v3.1.0 이 고친 것과 같은 유형의 결함이며(seed:172 ①이 "모든 롤백이 충돌로 보고되는" 반대 방향 결함을 고쳤다), 이번은 "충돌이어야 할 것이 충돌로 잡히지 않는" 방향이다.
- seed:110 (AC-08) — 시간 상한이 "자가 검증 시도"에만 걸려 편집 단계와 작업 총량이 무방비(C-5). D-008(dl:88)이 재시도 상한을 도입한 근거 문장("무인 상태에서 무한정 자원을 소모할 수 있다")이 편집 단계에 적용되지 않은 채 남아 있다. 이는 D-020 의 ⚠️ 정정(dl:235)이 지적한 "매달린 경우를 판정할 인수 기준 부재"와 같은 공백이 다른 단계에서 재발한 것이다(그 지적 자체는 v3.0.0 이 AC-08 을 신설해 자가 검증 단계에서는 해소했다).
- seed:61 (C-02) — 보존 정책을 도입하려면 "임의의 EditSnapshot 경계 시점"의 무조건 보장을 한정해야 한다(C-6, §8 머리말). 개정하지 않으면 어떤 보존 상한도 불변 층위를 위반한다. 삭제를 하지 않고 용량 위험을 계속 인수하는 선택지도 유효하며, 어느 쪽인지는 값이 아니라 오너의 범위 결정이다.
나머지 Critical 5건(C-1·C-2·C-3·C-7·C-8)은 스펙 개정 없이 Design 결정으로 해소 가능하다.
10. 다음 단계
- C-1(상태 기계 출발 상태·초기 상태)을 먼저 확정한다. 나머지 7건 중 3건(C-2·C-5·C-8)과 N1~N10 전부가 이것에 종속된다. 확정 전까지 bdd Feature 4 의
Given status 가 "자가검증중"전제는 잠정 표기임을 BDD 에 주석으로 남긴다 — 규칙보다 시나리오가 먼저 굳는 것을 막는다. - C-4·C-5·C-6 은 Seed Spec 개정 여부를 오너에게 올린다 — Design 결정으로 덮으면 불변 층위와 설계가 어긋난 채 남는다. C-6 은 개정과 "삭제하지 않음" 두 선택지가 모두 유효하다.
- C-6·C-7 은 오너 결정 3(파일 기반 EditSnapshot 저장)의 직접 산출물이므로 저장소 설계와 같은 문서에서 함께 결정한다. §8 R-1~R-5 를 초안으로 쓸 수 있되, R-2 는 C-02 개정 승인이, R-3 은 바이트 계수 규칙이, R-4 는 정렬 키(
timestamp사용 또는 속성 신설) 선택이 각각 선행한다. - B-01~B-12 는 각 규칙이 확정된 뒤에 BDD 에 추가한다. 규칙 없이 먼저 쓰지 않는다. B-13~B-16 은 지금 쓸 수 있다(B-13 은 §4 잔여 위험 수용이 선행).
- 이 목록을 전수라고 주장하지 않는다. 열어 확인한 문서는 seed-spec v3.1.0 전문, prd 전문, bdd 전문, planning-inputs 전문, discovery 전문, decision-log 전문(D-001~D-023 — prd 가 "D-001~D-021"로 적은 범위보다 2건 많다), spec-evaluation §판정과 권고, contrarian CH-022 2행이다. cc-flutter
flutter-patterns·package-layers·coui-flutter-rules는 참조했으나 이 분석에 인용된 규정이 0건이므로 근거 목록에서는 제외한다(이 산출물은 상태 기계·인수 경계 층위이며 위젯·패키지 계층을 다루지 않는다).
Generated by cc-spec flow-permutation agent · 2026-08-26