---
name: yd-doc-sync
description: 문서 현행화(doc-sync) — 코드·구성이 바뀐 뒤(디렉터리 삭제·이동, 포트·명령·의존성 변경, 큰 리팩터링 머지) 에이전트 지침(AGENTS.md·CLAUDE.md)·README·규칙(.claude/rules)·스킬·docs 가 실제와 어긋난 곳을 찾아 고친다. 지워지거나 옮겨진 경로를 가리키는 참조를 스크립트로 뽑고, 현행 지시와 시점 기록을 갈라 현행만 고친다. "문서현행화", "문서 드리프트 확인", "doc-sync", "남은 참조 정리" 요청에 쓴다. 메모리 감사는 yd-memory-factcheck, AGENTS.yaml 세팅은 yd-agents-yaml 이 맡는다.
---

# yd-doc-sync

코드는 빌드와 테스트가 지켜 주지만 문서는 아무도 지켜 주지 않는다. 디렉터리를
지우거나 옮기면 그 경로를 가리키던 지침·README·규칙이 조용히 거짓이 된다.
에이전트는 그 문서를 읽고 없는 파일을 찾거나 지운 명령을 다시 돌린다.

이 스킬은 **바뀐 실제에 문서를 맞춘다**. 판단 기준은 언제나 코드·설정·파일시스템과
실제 실행 결과다. 문서끼리 맞추는 것이 아니다.

## 경계

| 대상 | 맡는 스킬 |
|---|---|
| 에이전트 영속 메모리의 사실 감사 | `yd-memory-factcheck` (이 스킬은 경로 참조만 같이 고친다) |
| `AGENTS.yaml` 처음 세팅·구조 변경 | `yd-agents-yaml` (이 스킬은 기존 값이 실제와 맞는지만 본다) |
| 프로젝트 전용 대조표 | 레포에 `*-doc-sync` 같은 프로젝트 스킬이 있으면 **그 대조표를 먼저** 따른다 |
| 고친 문장·보고서·이슈/MR 본문의 문장 정리 | `yd-writer-kr` (이 스킬은 무엇을 고칠지 정하고, 문장은 그 규칙으로 쓴다) |
| 이슈·커밋·MR | `yd-git-ship` |

## 워크플로

### 1. 범위 정하기

무엇이 바뀌었는지부터 확정한다. 추측으로 범위를 넓히지 않는다.

```bash
git log --oneline -15                          # 기준점 찾기
git diff --name-status -M <기준> HEAD | head    # 무엇이 지워지고 옮겨졌나
```

- 기준점은 사용자가 말한 커밋·MR, 없으면 문서를 마지막으로 맞춘 머지 직전 커밋이다.
- 레포의 프로젝트 스킬·`AGENTS.md`·`.claude/rules/` 에 문서 갱신 규칙(어떤 코드가 바뀌면
  어떤 문서를 고치는지)이 있으면 읽고 그대로 따른다.

### 2. 드리프트 뽑기 — 스크립트 먼저

손 grep 보다 스크립트가 먼저다. 사람이 짠 정규식은 하위 프로젝트의 같은 이름 경로
(`ews-v3/web/src` 를 가리키는 `web/src`)를 지운 경로로 오인한다.

```bash
S=<이 스킬>/scripts/find_stale_refs.py
python3 $S --removed-since <기준>            # 지워지거나 옮겨진 경로를 가리키는 줄
python3 $S                                  # 전체 존재 검사(첫 조각이 레포에 있는 경로만)
python3 $S --exclude 'model-source/*' --json  # 보존본 제외, 기계 처리용
```

- 추적 중인 문서(`*.md`·`*.yaml`·`*.toml`·`AGENTS*`·`CLAUDE*` 등)만 본다. 코드의 경로
  문자열은 빌드·테스트 몫이다.
- 전체 존재 검사는 첫 경로 조각이 지금 레포에 있는 토큰만 본다(다른 레포 경로 소음을 줄이려고).
  최상위 폴더를 통째로 지웠다면 반드시 `--removed-since` 로 잡는다.
- 레포 어딘가에 실제로 있는 경로(하위 프로젝트 기준 상대경로, `docs/12` 같은 번호 축약)는
  빼고 보고한다. 옮겨진 경로는 `renamed -> 새 경로` 로 알려 준다.
- 스크립트가 못 잡는 드리프트는 따로 확인한다. 서술 종류마다 근거 원천이 정해져 있고,
  **문서끼리 맞추지 않는다**.

  | 서술 | 근거 원천 |
  |---|---|
  | 환경변수 이름 | 설정을 읽는 코드(`os.Getenv`·config 로더), `.env.example` |
  | 포트·컨테이너·헬스체크 | Quadlet `*.container`·compose 의 `HealthCmd`·`PublishPort`, 실제 `podman ps`/`docker ps` |
  | 실행 명령·CI 잡 | `package.json` scripts, `Makefile`, CI 설정 파일 |
  | 의존성·버전 | `go.mod`·`package.json`·lock 파일 |
  | 개수·수치("테이블 37개") | 실제 조회 결과와 그 날짜(DB 쿼리·`find`·`grep -c`) |
  | 트래커 동작(자동 클로즈 등) | 직전 이슈·MR 의 실제 state |

- 고친 서술은 레포 전체에서 같은 서술을 다시 찾는다(`git grep`). zsh 에서 `grep --include`
  를 쓰면 glob 을 따옴표로 감싼다(`--include='*.md'`) — 안 그러면 `no matches found` 로 멈춘다.
- `AGENTS.yaml` 이 있으면 레포의 검증기(`scripts/check-agents-yaml.sh`)를 돌린다.

#### 레포별 범위 — `AGENTS.yaml` 의 `x-doc-sync`

레포마다 「고치지 않는 시점 기록」과 「아예 안 보는 경로」가 다르다. 레포 루트
`AGENTS.yaml` 에 적어 두면 스크립트가 읽는다(`yd-agents-yaml` 규약의 `x-` 섹션).

```yaml
x-doc-sync:
  history:              # 찾아도 history 로만 센다 — 고치지 않는 기록
    - CHANGELOG.md
    - docs/superpowers/{plans,specs}/**
    - .claude/memory/archive/**
  exclude:              # 훑지 않는다 — 원본 사본·생성 데이터
    - data/manual/**
```

`*`·`**`(둘 다 `/` 를 넘는다)·`{a,b}` 를 쓴다. 섹션이 없으면 기본값(CHANGELOG·`archive/`
는 이력, 잠금 파일·`node_modules` 등은 제외)으로 돈다. 레포에 이 섹션을 처음 넣을 때는
`AGENTS.md` 에 「문서 현행화는 `yd-doc-sync` 를 쓴다」 한 줄도 같이 둔다.

### 3. 분류 — 현행 지시와 시점 기록을 가른다

찾은 줄을 셋으로 나눈다. 스크립트의 `current`/`history` 는 낱말 기반 추정이니
**줄을 직접 읽고** 정한다.

| 분류 | 예 | 처리 |
|---|---|---|
| 현행 지시 | "서버는 `backend/cmd/server` 로 띄운다", 규칙 파일의 `paths:` | 실제에 맞게 고친다. 대상이 없어졌으면 문장을 지우거나 새 위치로 바꾼다 |
| 시점 기록 | CHANGELOG, "2026-09-21 커밋 `e59d98b` 기준", 이슈 번호가 붙은 결정 기록, 지난 계획·스펙(`plans/`·`specs/`), 실행 로그(`runs/`), 메모리 `archive/`, 보존용 원본 사본 | **고치지 않는다.** 현행 지시처럼 읽혀 오해를 부르면 "(#N 에서 제거)" 같은 표지만 붙인다 |
| 생성물 | 스크립트가 만든 HTML·SVG·코드 | 직접 고치지 않는다. 생성기(템플릿·스크립트)를 고치고 다시 돌린다 |

- 설계 결정 기록(ADR·D-엔트리)이 있는 레포에서 구조가 바뀌었으면 결정 항목을 하나
  더하고, 옛 서술은 그 항목을 가리키게 표시한다. 옛 결정 본문을 다시 쓰지 않는다.
- 메모리 파일은 경로 참조만 고치고, 사실 자체의 낡음은 `yd-memory-factcheck` 로 넘긴다.

### 4. 고치기

- **근거를 확인한 것만 고친다.** 새 경로·명령·값은 실제 파일을 열거나 명령을 돌려 확인한
  뒤 적는다. 확인 못 한 줄은 고치지 말고 보고서의 「확인 필요」에 둔다.
- 지운 기능을 설명하던 절은 통째로 지운다. 빈 껍데기 문장("~는 없다")을 여러 군데
  남기지 말고, 사라진 사실은 한 곳(README·결정 기록)에만 남긴다.
- 문서 갱신 규칙이 있는 파일(규칙 표, 스킬 목록, 인덱스)은 표와 실제 파일 목록을 함께 맞춘다.
- **고친 문장은 항상 `yd-writer-kr` 로 정리한다.** 경로만 바꾸면 앞뒤 문장이 어긋나기
  쉽다. 고친 줄과 그 문단을 그 스킬 규칙으로 다시 읽고 다듬는다. 문체는 그 문서의 것을
  따르고, 고치지 않은 문단까지 손대지 않는다.
- 고친 파일이 많으면 파일 범위를 겹치지 않게 나눠 서브에이전트에 맡겨도 된다. 사실
  업데이트(예: 운영 철거 완료)가 생기면 즉시 모든 서브에이전트에 전달한다.

### 5. 검증

```bash
python3 $S --removed-since <기준>   # current 0 이거나, 남은 줄마다 둔 이유가 있다
<레포 검증기들>                      # AGENTS.yaml 검증기, 문서 정합성 검사, 링크 검사 등
<레포 빌드·테스트>                   # 문서와 함께 바뀐 스크립트·설정이 있으면
```

남은 `current` 는 줄마다 왜 두는지(다른 레포 경로, 의도된 이력) 한 줄로 적는다.

### 6. 보고

채팅에는 짧게, 상세는 이슈·MR 본문에 둔다. 보고서와 이슈·MR 본문도 `yd-writer-kr` 로 쓴다.

```
## 문서 현행화 — <기준>..HEAD
- 고친 것: <파일 N개> — <무엇을 무엇으로>
- 기록으로 둔 것: <파일·줄> — <이유>
- 확인 필요: <줄> — <무엇을 확인해야 하는지>
- 대조하지 못한 범위: <폴더·문서 종류> — <이유(접근 불가·근거 원천 없음·시간)>
- 검증: find_stale_refs current <n>건(사유 명시), <검증기> 통과
```

커밋·MR 은 `yd-git-ship` 절차로 올린다. 문서 현행화는 코드 변경과 같은 MR 에 넣는 것이
원칙이다(코드를 바꾼 MR 이 문서도 같이 고친다). 이미 머지된 변경을 뒤따라 맞출 때만
별도 이슈로 연다.

## 완료 조건

- `find_stale_refs.py --removed-since <기준>` 의 `current` 가 0 이거나, 남은 줄마다 둔 이유가 보고서에 있다.
- 고친 서술마다 근거 파일·명령 결과를 확인했다.
- 시점 기록과 생성물은 직접 고치지 않았다.
- 고친 문장과 보고서·이슈·MR 본문을 `yd-writer-kr` 로 정리했다.
- 레포의 문서 검증기와, 함께 바뀐 스크립트의 테스트가 통과한다.
- 보고서·MR 본문에 대조하지 못한 범위를 적었다(없으면 「없음」). 빠뜨린 폴더가 다음 드리프트가 된다.
