# agent-ui 규칙

`agent-ui/`가 있는 프로젝트 또는 agent-ui 생성, 갱신, 검증 요청에서 적용한다.

## 목적

`agent-ui/`는 AI agent와 사람이 UI 의도, 화면 구조, 와이어프레임, 반복 구성요소, 코드 반영 상태를 동기화하기 위한 작업 문맥 저장소다.
초기 기준은 ops/dev UI이며, product UI는 같은 구조 위에 brand, content, assets, tokens, motion 같은 레이어를 추가할 수 있다.

## 기본 구조

```text
agent-ui/
  README.md
  .sync-state.json                # 선택: agent-ui -> code 기준점과 plan/Milestone work 매핑
  USER_REVIEW.md                  # 선택: 사용자 판단이 필요한 활성 리뷰
  archive/
    user-review/
      user_review_001.log

  definition/
    index.md
    views/
      index.md
      <view-id>/
        index.md
    components/
      index.md
      <component-id>/
        index.md
    archive/
      views/
        <view-id>/
          index.log
      components/
        <component-id>/
          index.log

  frame/
    index.md
    views/
      <view-id>/
        index.md                   # visual source가 있을 때만 생성
        wire.excalidraw            # 선택: 1차 visual source 후보
```

## Source of Truth

- `agent-ui/definition/**`은 현재 UI 정의의 source of truth다.
- `agent-ui/frame/**`은 와이어프레임과 visual source를 연결하는 보조 자료다.
- visual source가 없는 view는 `frame/views/<view-id>/`를 만들지 않는다. view 문서의 `frame`은 `null`로 둔다.
- `.excalidraw` 파일만으로 현재 UI 기준을 확정하지 않는다. visual source가 있으면 반드시 대응되는 `frame/views/<view-id>/index.md`가 있어야 한다.
- `frame/views/<view-id>/index.md`는 대응되는 `definition/views/<view-id>/index.md`를 가리켜야 한다.
- 화면 의도, 상태, 액션, 정보 우선순위는 definition에 둔다.
- 배치, 밀도, 시각적 영역 관계는 frame에 둔다.
- 생성된 view/component는 코드, 문서, 사용자 입력 중 어떤 근거에서 왔는지 `Source Evidence`에 남긴다.

## Frontmatter Schema

- 활성 Markdown 문서는 YAML frontmatter를 둔다.
- `ui_doc_type`은 `readme`, `definition-index`, `views-index`, `view`, `components-index`, `component`, `frame-index`, `frame-view`, `user-review`, `archive-log` 중 하나다.
- definition-index 문서는 `surface_type`, `source_evidence`를 둘 수 있다.
- view 문서는 `view_id`, `status`, `frame`, `source_evidence`를 둔다.
- component 문서는 `component_id`, `status`, `source_evidence`를 둔다.
- view 문서의 `frame`은 frame-view 문서가 있으면 경로, 없으면 `null`로 둔다.
- frame-view 문서는 visual source가 있을 때만 만들며 `view_id`, `definition`, `visual_source`, `regions`를 둔다.
- definition-index/view/component의 `source_evidence`는 list이며 각 항목은 `type`, `path`, `notes`를 둔다.
- 이 문서들의 `source_evidence.type`은 `code`, `docs`, `user` 중 하나다.
- 실제 파일 근거가 없으면 `path: null`을 사용한다. placeholder 문자열을 현재 근거처럼 남기지 않는다.
- view에 visual source가 없으면 view 문서의 `frame`을 `null`로 두고 frame-view 문서를 만들지 않는다.
- frame-view를 만들 때 `visual_source`는 실제 존재하는 visual source 경로여야 한다. 없는 `wire.excalidraw`를 기본 근거처럼 쓰지 않는다.
- view/component의 `status` 값은 `구현됨`, `계획`, `가정`, `불명확` 중 하나다. frame-view와 index 문서에는 `status`를 두지 않는다.
- `구현됨`은 코드 반영 완료 상태다. 코드 근거가 있으면 존재하는 `code` evidence path를 함께 둔다.
- `계획`은 정합화된 UI 정의지만 아직 코드 반영 전이거나 사용자 확인 후 재작업 대상인 상태다.
- `가정`은 사용자 입력 또는 추정만 있고 확정 근거가 부족한 상태다.
- `불명확`은 근거가 부족하거나 판단할 수 없는 상태다.
- `가정`과 `불명확`은 코드 동기화 대상이 아니며, sync 전에 `agent-ui/USER_REVIEW.md`로 분리한다.
- view는 frontmatter의 `status`, `source_evidence`, `regions`와 본문 `Status`, `Source Evidence`, `Regions`가 같은 기준을 말해야 한다.
- component는 frontmatter의 `status`, `source_evidence`와 본문 `Status`, `Source Evidence`가 같은 기준을 말해야 한다.
- frame-view는 frontmatter `regions`와 본문 `Required Regions`가 같은 기준을 말해야 하며, `status`나 `Source Evidence`를 요구하지 않는다.
- frontmatter는 기계적 검증을 위한 최소 schema이고, 본문 Markdown은 사람과 agent가 읽는 설명을 유지한다.

## 운영 동기화 흐름

- 초기 생성 이후 기본 방향은 `agent-ui -> code` 단방향이다. 코드에서 agent-ui를 만드는 흐름은 `create-agent-ui` 최초 생성에만 사용한다.
- 화면정의서, view, component, frame, wireframe을 agent로 수정하는 요청은 `update-agent-ui`로 처리한다.
- 사용자 리뷰 결정 반영, `UIR-NNN` 해결, "화면정의서와 코드가 안 맞아" 같은 회귀 요청도 `update-agent-ui` 또는 `validate-agent-ui`로 들어와 같은 루프를 재개한다.
- `update-agent-ui`는 agent-ui 문서 갱신을 맡는다. 코드 구현 규모 판정, plan 라우팅, roadmap/milestone 라우팅은 하지 않는다.
- `update-agent-ui` 후에는 변경 범위에 따라 `validate-agent-ui` 필요 여부와 code sync intent 전달 여부만 판단한다. 실행한다면 `validate-agent-ui`가 항상 `sync-agent-ui`보다 먼저 실행된다.
- `validate-agent-ui`는 agent-ui 내부 문서 그래프를 정합화한다. definition, frame, visual source, component, archive, USER_REVIEW 사이의 누락과 충돌을 같은 수준으로 맞춘다.
- 운영 단계의 `validate-agent-ui`는 코드 후보만 보고 새 view/component를 자동 생성하지 않는다. 코드와 agent-ui가 어긋나면 agent-ui 기준 sync 대상, status 회귀, 또는 USER_REVIEW로 분리한다.
- `sync-agent-ui`는 정합화된 agent-ui 변경분을 코드에 반영하기 전에 코드 작업 규모를 판정한다. 작은 코드 작업은 직접 반영하고, 중간 코드 작업은 `plan` 루프로, Milestone이 필요한 큰 코드 작업은 `update-roadmap`의 Milestone/Epic/Task 갱신으로 넘긴다.
- `sync-agent-ui`의 기본 모드는 `.sync-state.json` 기준 이후 변경분만 동기화한다.
- 사용자가 "agent-ui와 코드 전체 동기화"처럼 전체 동기화를 명시한 경우에만 현재 agent-ui 전체를 코드와 대조한다.
- `update-agent-ui` 또는 수동 `validate-agent-ui`가 코드 반영 필요성을 판단했으면 그 판단을 다음 단계로 전달한다. 전달된 판단이 있으면 뒤 단계는 문서 정합성과 sync intent 자체를 재판단하지 않지만, `sync-agent-ui`는 실제 코드 반영 방식 판정을 수행한다.
- 직접 sync가 검증되면 반영된 view/component의 `status`를 `구현됨`으로 바꾼다.
- `sync-agent-ui`가 코드 작업을 `plan-required`로 라우팅한 경우에는 일반 plan/review 문서에 agent-ui 전용 completion section을 추가하지 않는다.
- plan pair 생성 뒤 `sync-agent-ui mode=prepare-code-work`가 `.sync-state.json.pending_code_work`에 task path, status 전환 대상 view/component, validation-only frame-view, 코드 후보, 검증 기준을 기록한다.
- pending UI task가 plan refinement 또는 sibling reindex로 경로가 바뀌면 전체 status 대상을 닫는 child 하나로 기존 entry를 rebind한다. 이전 task path를 남기거나 같은 status/frame path를 여러 child에 중복 배정하지 않는다.
- 일반 code-review PASS와 exact `complete.log` 생성 뒤 원래 `task-path`와 `completion-log`를 전달받은 `sync-agent-ui mode=reconcile-completion`이 matching pending entry만 사용해 `update-agent-ui`와 `validate-agent-ui`를 순서대로 실행한다. view/component만 `구현됨`으로 반영하고 frame-view에는 status를 추가하지 않는다.
- `sync-agent-ui`가 코드 작업을 `milestone-required`로 라우팅하면 exact active Milestone과 UI/code evidence를 `.sync-state.json.pending_milestone_work`에 기록한다. 일반 Milestone 문서에는 agent-ui 전용 완료 필드를 추가하지 않는다.
- Milestone 종료 요청에서는 `complete-milestone check-only`가 종료 가능 근거를 반환한 뒤에만 `sync-agent-ui reconcile-milestone-completion`을 실행한다. 최종 검증과 code evidence가 확인된 view/component만 status를 반영하고 연결된 frame은 정합성만 검증하며, 성공 뒤에만 caller/router가 Milestone close를 계속한다.
- 사용자 확인 또는 후속 검증에서 불일치가 발견되면 해당 항목은 `계획`으로 되돌릴 수 있다.
- `sync-agent-ui`가 검증 실패, 환경 차단, 구현 방향 충돌, 반복 실패를 스스로 해결하지 못하면 commit/push하지 않고 `agent-ui/USER_REVIEW.md`에 게이트를 남긴다.
- 실패한 `sync-agent-ui`가 남긴 작업트리 변경은 사용자 결정과 충돌하지 않으면 보존하고, USER_REVIEW 해결 후 같은 변경을 이어서 재검증할 수 있다.

## Sync State

- `agent-ui/.sync-state.json`은 agent-ui 변경분을 코드에 반영한 기준점이다.
- `create-agent-ui`는 생성 결과를 최초 baseline으로 보고 `.sync-state.json`을 만든다.
- 기존 방식으로 생성되어 `.sync-state.json`이 없는 agent-ui는 legacy 상태다. 이 경우 기본 변경분 sync를 시작하지 말고 validate 후 baseline migration으로 기준점을 먼저 만든다.
- baseline은 `code-first`, `concept-first`, `blank` 모두에서 생성된 agent-ui 기준선을 뜻한다. `concept-first` baseline은 코드 구현 완료가 아니라 agent-ui 기준선 확정이다.
- `last_synced_head`는 agent-ui 변경분과 코드 반영이 들어간 sync 결과 commit hash다. `.sync-state.json` 자체를 기록한 commit hash가 아니다.
- schema version 4의 `pending_code_work`/`reconciled_code_work`는 `plan-required` task/UI 매핑과 완료 근거고, `pending_milestone_work`/`reconciled_milestone_work`는 `milestone-required` Milestone/UI 매핑과 완료 근거다. 일반 plan/review/complete.log/Milestone 문서는 이 schema를 알 필요가 없다.
- `status_paths`에는 status schema가 있는 view/component만, `frame_paths`에는 validation-only frame-view만 기록한다.
- pending entry의 `status_paths`와 `frame_paths`는 task와 Milestone을 통틀어 중복 소유할 수 없다. refinement/reindex에서는 helper의 `previous-task-path` rebind를 사용하고 scope/evidence 변경이 있을 때만 검증 후 replace한다.
- direct sync의 agent-ui 경로 트리는 code/Milestone pending entry가 소유한 `status_paths`/`frame_paths`와 겹칠 수 없다. 코드 변경 전과 commit 전 확인하고, `record-sync`도 lock 안에서 동일·상위·하위 경로 겹침을 거부한다.
- pending entry는 `prepare-code-work`만 생성/갱신하고 `reconcile-completion` 검증 통과 시에만 `reconciled_code_work`로 이동한다. 실패, ambiguous completion, evidence 부족에서는 유지한다.
- Milestone pending entry는 `prepare-milestone-work`만 생성/갱신하고 `complete-milestone check-only`와 UI 검증이 모두 통과한 `reconcile-milestone-completion`에서만 `reconciled_milestone_work`로 이동한다. 실패하면 Milestone close를 진행하지 않는다.
- `sync-agent-ui`의 prepare, reconcile, direct/baseline 기록은 모두 `sync-agent-ui/scripts/sync_state.py`의 agent-ui directory lock과 inspection 시점 SHA-256 검증으로 수행한다. shared state를 수동 read-modify-write하지 않는다.
- `reconcile-completion`은 matching agent-ui/code 결과를 모두 포함하는 commit hash가 검증된 경우에만 `last_synced_head`를 갱신한다. 그렇지 않으면 기존 기준점을 보존하고 notes에 사유를 남긴다.
- baseline 또는 sync 완료 시 commit은 두 단계로 남길 수 있다. 먼저 agent-ui/code 변경 commit을 만들고, 그 commit hash를 `.sync-state.json`에 기록한 별도 commit을 만든 뒤 push한다.
- 변경분 판정에서는 `.sync-state.json` 자체 변경을 제외한다.

## 명명 규칙

- view id, component id, 파일명, 디렉터리명은 kebab-case를 사용한다.
- view 기준 문서는 `definition/views/<view-id>/index.md`에 둔다.
- component 기준 문서는 `definition/components/<component-id>/index.md`에 둔다.
- 같은 레벨에서 `<name>.md`와 `<name>/`를 함께 두지 않는다.
- 하위 정의가 필요하면 `<name>/index.md`와 `<name>/<child>.md`를 사용한다.

## ID 규칙

- region id는 `<view-id>.<region>` 형식을 사용한다.
- 하위 region은 `<view-id>.<region>.<subregion>` 형식을 사용할 수 있다.
- component id는 `definition/components/` 아래 경로에서 `index.md`를 제외한 path id로 본다. 예: `data-table`, `data-table/job-list`.
- frame-view가 있으면 view 정의서의 region id와 frame 정의서의 region id는 동일해야 한다.
- view에서 참조한 component id는 대응되는 component 정의 문서가 있어야 한다.
- frame-view가 있으면 frame-view frontmatter의 `regions`와 view 본문의 region id는 같은 집합이어야 한다. 단, 차이가 제품 판단을 요구하면 USER_REVIEW로 남긴다.

## Archive 접근

- `agent-ui/definition/archive/**`는 일반 작업에서 읽지 않는다.
- `agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다.
- 예외: 사용자가 과거 결정 확인, 복원, 비교, 특정 archive 경로 확인, 해결된 user review 확인을 요청한 경우에만 필요한 파일을 좁게 읽는다.
- validate 작업은 archive 경로 존재 여부와 tree 대응 여부를 확인할 수 있지만, 위 예외가 없으면 archive 본문을 읽지 않는다.

## USER_REVIEW

- agent가 확정할 수 없는 UI 의도, 화면 구조, region 추가/삭제, component 신규 생성 여부, page/drawer/split 같은 UX 결정은 `agent-ui/USER_REVIEW.md`에 남긴다.
- `agent-ui/USER_REVIEW.md`는 `update-agent-ui`, `validate-agent-ui`, `sync-agent-ui`의 통합 gate다.
- 항목에는 어느 단계에서 막혔는지 알 수 있게 `Source Skill`, `Stage`, `Blocking Step`, `Context`, `Options`, `Needed For`를 남긴다.
- 현재 동기화 범위에 미해결 USER_REVIEW 항목이 있으면 `sync-agent-ui`는 실행하지 않는다.
- 해결된 user review는 `agent-ui/archive/user-review/user_review_N.log`로 이동할 수 있다.
- USER_REVIEW 해결 요청은 관련 결정을 agent-ui 활성 문서에 반영한 뒤, 해당 항목을 archive log로 이동하고, 필요하면 `validate-agent-ui`와 `sync-agent-ui`를 순서대로 재개한다.
- `USER_REVIEW.md`가 있으면 관련 agent-ui 갱신이나 검증 결과에 남은 review id를 보고한다.

## Excalidraw

- 1차 visual source 후보는 `wire.excalidraw`다.
- VS Code Excalidraw extension은 초기 편집 워크플로우로 사용할 수 있다.
- excalidraw.com import/export 워크플로우는 기본 표준으로 삼지 않는다.
- Excalidraw self-host는 R&D 후보이며, 기본 agent-ui scaffold의 필수 조건이 아니다.
- `.excalidraw`는 JSON으로 다룬다. 검증 시 가능하면 JSON parser로 `elements`의 text label 또는 `customData.region_id`를 확인한다.
- visual source에 region label이 있으면 `frame-view.regions`와 `definition` region id의 집합과 비교한다.
- visual source가 있는데 region label이 없으면 frame과 definition의 연결 근거가 부족한 상태로 본다.
- visual source에 정의되지 않은 region label이 있거나 필수 region label이 없으면 자동으로 UI 의도를 확정하지 않고 USER_REVIEW로 남긴다.

## 스킬

- agent-ui 초기 scaffold 생성은 `create-agent-ui`를 사용한다.
- 화면정의서, view, component, frame, wireframe 갱신은 `update-agent-ui`를 사용한다.
- 구조와 정합성 검사, 문서 간 자동 보정, USER_REVIEW 생성은 `validate-agent-ui`를 사용한다.
- 정합화된 agent-ui 변경분을 코드에 반영할 때는 `sync-agent-ui`를 사용한다.
