Skip to content
Go back

KRDS 접근성 도구 구현 회고 — 리서치에서 v0.7.0까지 한 달

시작 — 리서치에서 세운 설계

공공 웹은 범정부 디자인 시스템 KRDS와, 33개 검사항목으로 된 웹 접근성 국가표준 KWCAG 2.2를 함께 지켜야 한다. 지난 글에서는 이 둘을 잇는 도구를 조사하다 방향을 바꿨다. 자동 검사 엔진 axe로 위반을 찾는 “검사 도구”가 아니라, KWCAG 충족 조건이 들어간 KRDS 마크업을 페이지를 만드는 시점에 공급하는 “적용 도구”다.

그때 세운 설계는 세 가지였다.

한 달 동안 이 설계를 MCP 서버로 구현해 v0.7.0까지 일곱 번 배포했다. 서버는 부품·템플릿을 주는 공급 도구와 완성 페이지를 다시 검사하는 도구를 낸다. 검증은 AI 에이전트에게 이 서버를 쥐여 주고 정적 HTML·JSP·React(Next.js 포함) 페이지를 만들게 하는 실사용 테스트로 네 차례 했다. 설계대로 된 것과 틀린 것을 정리했다.

매핑표 — 근거 없이 “자동 충족”이라 쓰지 않는다

43개 컴포넌트를 전수 분류한 결과는 자동 충족 130건, 조건부 89건, 범위 밖 132건, 미확정 40건이다. 문서로 먼저 쓰고, 빌드 스크립트가 코드로 변환한다. 문서와 코드가 어긋나면 테스트가 깨진다.

예상과 달랐던 건 “자동 충족”이라고 주장하기가 생각보다 어려웠다는 점이다. 판정마다 공식 킷의 파일과 행 번호를 근거로 달게 했더니 규칙이 필요해졌다.

확신이 없으면 자동 충족으로 올리지 않고 미확정으로 남겼다. 잘못 붙인 자동 충족은 도구가 거짓 보증을 하게 만들기 때문이다.

필수 입력 강제 — 돌았지만 구멍이 있었다

부품 공급 도구에 레이블 없이 입력란을 요청하면 이렇게 거부한다.

# 텍스트 입력 필드 (krds:text_input)
## 필수 입력이 채워지지 않아 마크업을 제공하지 않는다 (3건)
- labelText — kwcag:7.3.2 레이블 제공
- inputId — kwcag:7.3.2 레이블 제공
(요약)

실사용에서도 강제는 돌았다. 에이전트들은 필수 입력 없이 부품을 불렀다가 거부 안내를 받고, 값을 채워 다시 불렀다.

다만 구멍이 세 개 있었다. 매핑표의 적용 범위 표기를 변형 이름으로 잘못 읽어, 모달 같은 몇몇 부품은 기본 호출에서 필수 입력이 강제되지 않았다. “모달을 배경 밖에 둔다” 같은 확인용 입력에 false를 줘도 통과했다. 목록 도구가 세는 필수 입력 수와 실제로 막는 수가 달라 다섯 번 지적받았다. 셋 다 v0.7.0에서 같은 판정 함수를 쓰게 고쳤다.

또 하나는 강제가 막지 못하는 경로였다. 에이전트들은 값을 넘기고도 킷 데모 마크업을 받아 id·레이블·href를 손으로 다시 쓰고 있었다. 그래서 입력값을 교정본 구조에 넣은 마크업을 도구가 직접 만들게 했고(6종), 재확인한 3세션에서는 다시 쓴 컴포넌트가 0이었다.

axe 연동 — 번역은 쉬웠고 사각지대가 컸다

axe 결과를 KWCAG 번호로 옮기는 번역표는 완전 1 · 부분 19 · 불가 13항목이다. 불가 13항목은 리포트에 수동 체크리스트로 내보낸다.

번역보다 큰 일은 axe가 못 보는 부분이었다. 공식 킷 CSS는 아이콘 경로를 206곳에서 잘못 적어 404가 났는데 axe는 조용했다. 그 404를 메우려고 넣은 교정 CSS가 태그 삭제 버튼에 마스크를 다시 씌워 버튼이 통째로 사라졌을 때도 통과했다. 셀렉트 글자색 대비 3.08:1은 판정을 보류만 했다.

그래서 직접 재는 모듈을 하나씩 붙여 왔다.

3층은 어디까지 — 2층이 바뀌었다

1층(MCP 공급)과 3층(리포트 생성기)은 계획대로 만들었다. 재검사 도구는 3층 리포트 생성기를 그대로 쓴다.

바뀐 건 2층이다. “완성하면 검사하라”는 지시는 따를 때도 건너뛸 때도 있었다. 그래서 PR 시점 CI보다 먼저, AI가 작업을 끝내려는 순간을 막았다. Stop 훅이 검사 기록을 읽어, 위반이 남았거나 검사 뒤에 소스가 바뀌었으면 종료를 거부한다.

// 프로젝트 .claude/settings.json (요약)
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "npx -y @donghok/krds-a11y-mcp stop-hook",
          },
        ],
      },
    ],
  },
}

판정은 gate 명령 한 곳에 두었다. 서버 쪽 CI는 사내 CI 환경이 준비될 때까지 보류했다.

설계 밖에서 틀린 예상

앞의 설계 항목 말고도 틀린 예상이 두 개 더 있었다.

회고

설계의 중심은 맞았다. 필수 입력을 채우지 않으면 마크업을 주지 않으니, 도구로 받은 부품에서는 레이블 누락 같은 위반을 생성 단계에서 막을 수 있었다. 틀린 건 설계 아래 깔린 가정들이었다. 매핑표는 근거 규칙이 있어야 섰고, 강제에는 구멍이 있었고, axe에는 사각지대가 있었고, 지시는 훅이 되어야 돌았다.

공식 샘플도, axe도, 지시문도, 새 기능도 확인 전까지는 가설이었다. 믿을 수 있었던 건 직접 재고, 써 보고, 강제한 결과뿐이었다.


Share this post on:

Comments


Next Post
KRDS를 적용하면 웹 접근성이 따라올까 — KWCAG 자동화 도구 리서치