콘텐츠로 이동

ADR-0014 — 자동화 인프라 디자인

Context

ADR-0013은 협업 wiki 진입점 정책을 박제했다 — "Slack @wiki-bot 멘션 → raw 박제 → GitHub Issue 게이트 → 본인 라벨 클릭 → wiki PR". 그러나 실제 동작에 필요한 인프라가 미존재:

  • Slack bot 라이브러리·호스팅 미선택
  • GitHub Action 구조·라벨·시크릿 미정
  • PII redact·dedupe·서명 검증 등 보안 정책 미정
  • 월 비용·구현 공수 미추정

본 ADR은 ADR-0013 정책을 동작시킬 인프라 결정. 외부 조사 1라운드 기반(2026-05-25) — Slack Bolt SDK / Cloudflare Workers / AWS Lambda / Vercel / n8n / Zapier / Slack Workflow Builder / GitHub Action 패턴 / claude-code-action / NIST AI RMF GenAI Profile / Slack 2025-05-29 rate limit 변경 등.

본 ADR은 결정 ADR — 실제 코드(.github/workflows/wiki-ingest-from-issue.yml, Slack bot 코드, 라벨 생성)는 별도 구현 라운드.

Decision

§A — 스택 (5축 단일 결정)

항목 채택 핵심 이유
Slack bot 라이브러리 Slack Bolt JS 공식 SDK / app_mention·reactions_added·message 풀 지원 / 서명 검증 자동
봇 호스팅 Cloudflare Workers V8 isolate 콜드스타트 0ms (Slack 3초 SLA 안전) / 100K req/일 free / 전 세계 edge PoP
GitHub Action 트리거 Stage1 repository_dispatch + Stage2 issues.labeled ADR-0013 2단계 분리와 정확 일치
Claude 진입 anthropics/claude-code-action@beta 공식 GitHub Action / 기존 Claude Code OAuth 시크릿 재사용 / allowed_tools로 권한 제한
GitHub 인증 GitHub App + actions/create-github-app-token@v1 Rate limit 15K/h / fine-grained PAT의 "Resource not accessible" 403 이슈 회피 / 팀 확장 안정

§B — 흐름도 (ADR-0013 §A 인프라 구체화)

[팀원] Slack `@wiki-bot` 멘션 또는 `#wiki-inbox` 게시
   ↓ HTTPS POST (Slack Events API, X-Slack-Signature)
[Cloudflare Workers — Slack Bolt JS]
   ↓ HMAC SHA256 서명 검증 (Bolt 자동, ±300s timestamp)
   ↓ Workers KV로 event_id dedupe (1분 TTL)
   ↓ 3초 안에 200 OK ack
   ↓ 비동기:
      ├─ Notion 링크 추출 → Notion API fetch
      ├─ PII redact (정규식·presidio 패턴)
      └─ GitHub repository_dispatch (event_type: "wiki-inbox", client_payload)
[GitHub Action: wiki-stage1.yml]
   on: repository_dispatch (types: [wiki-inbox])
   - raw/notion/<page>.md 또는 raw/meetings/<yyyy-mm-dd>-<slug>.md 박제
   - Issue 자동 생성 (제목 + 본문 + 자동 분류 라벨)
   - 자동 라벨링 (LLM 본문 분석 → wiki:반영 / wiki:참고 / wiki:금지)
   ↓ Slack chat.postMessage → #wiki-notify
   "raw/<...> 박제 완료 / Issue #N / 자동 분류: {반영|참고|금지}"
[본인] Issue review (GitHub 웹·앱)
   - 라벨 재분류 가능
   - `wiki:ready-to-ingest` 라벨 부착
[GitHub Action: wiki-stage2.yml]
   on: issues: types: [labeled]
   if: github.event.label.name == 'wiki:ready-to-ingest'
   - actions/create-github-app-token@v1로 App token 발급
   - anthropics/claude-code-action@beta 호출
     allowed_tools: Read, Edit, Write, Bash (제한)
   - Claude agent가 Issue 본문·코멘트·라벨 읽어 wiki PR 생성
   ↓ Slack chat.postMessage → #wiki-notify "wiki PR #M 생성됨"
[본인] PR review + merge
[GitHub Action: wiki-stage3.yml] (선택)
   on: pull_request: types: [closed], if: merged
   - /log-append 자동
   - Issue auto-close
   ↓ Slack chat.postMessage → #wiki-notify
   "wiki/<...> 갱신 완료 / Issue #N close / log entry +1 / PR 링크"

wiki:금지 라벨이 붙은 Issue는 Stage2 트리거 X — auto-close + Slack 알림으로 "PR 생성 X" 통지.

§C — Issue 라벨 5개 (색·자동/수동)

라벨 색 (hex) 의미 부착 주체
wiki:반영 #0e8a16 🟢 green 정식 wiki 페이지 갱신 후보 자동 (Stage1 LLM 분류)
wiki:참고 #fbca04 🟡 yellow wiki/inbox/ draft만 자동
wiki:금지 #d93f0b 🔴 red/orange PII·기밀 — 반영 금지 자동 (Stage1 PII 룰)
wiki:ready-to-ingest #1d76db 🔵 blue 본인 review 후 Stage2 trigger 수동 (본인)
wiki:stale #cccccc ⚪ gray 1주+ 미반영 알림 자동 (별도 cron Action)

라벨 생성은 GitHub repo 설정에서 1회 (또는 actions/labels@v2로 declarative 관리).

§D — 시크릿 매트릭스

시크릿 이름 신규/재사용 출처 권한
SLACK_BOT_TOKEN 신규 api.slack.com (App 생성) app_mentions:read, reactions:read, chat:write, channels:history
SLACK_SIGNING_SECRET 신규 api.slack.com (App 생성) HMAC 검증 전용
WIKI_BOT_APP_ID 신규 github.com/settings/apps App 식별
WIKI_BOT_APP_PRIVATE_KEY 신규 동상 App 인증
NOTION_API_KEY 재사용 기존 .mcp.json·NOTION_API_KEY env 페이지 read
CLAUDE_CODE_OAUTH_TOKEN 재사용 기존 claude.yml 시크릿 claude-code-action 표준

GitHub App 권한: contents:write + issues:write + pull_requests:write + metadata:read. Repo는 idealstudy/mvp-back만 설치.

§E — 보안 (4축)

  1. Slack 서명 검증 — Bolt JS가 X-Slack-Signature HMAC SHA256 + X-Slack-Request-Timestamp ±300s 자동 검증. SLACK_SIGNING_SECRET만 환경변수로 주입.
  2. PII auto-redact — Workers 함수 진입 시 정규식 패턴(이메일·전화·주민번호·카드번호) + (선택) presidio·AWS Comprehend 호출. redact 후 raw 박제·Issue 생성. NIST AI RMF GenAI Profile (AI 600-1) 준수.
  3. 권한 escalation 차단repository_dispatch client_payload는 화이트리스트 필드(source·raw_path·category·slack_thread_url)만. Stage2의 claude-code-action allowed_tools를 Read·Edit·Write·Bash 등 제한, --max-turns 10 명시.
  4. Rate limit·idempotency — Slack Events API 워크스페이스당 30K/h (충분). Workers KV로 event_id 1분 TTL dedupe. 실패 시 exponential backoff 재시도. Stage2 GitHub Action timeout-minutes: 15.

§F — 비용 (월 추정, 1인 + 3~5명 합류 기준)

항목 비용 비고
Cloudflare Workers $0 free tier 100K req/일 (예상 1500~3K req/월의 200배 마진)
Slack Free plan $0 Bolt SDK 무료, Events API 사용
GitHub Actions $0 private repo 2000분/월 free (Stage1·2·3 합쳐 50~200분 추정)
Workers KV (dedupe) $0 1K write/일 free
Anthropic Claude (Max OAuth) 기존 claude.yml 이미 운영 — 증분 0
Notion API $0 기존 계정
합계 $0 증분

확장 시 (수십명·일 1만 req+): Workers Paid $5/월 + Slack Pro $7.25/user/월 검토.

§G — 구현 공수 (6 인일, 약 1~1.5주)

단계 인일
Slack App 생성·OAuth scope·signing secret 발급 0.5
Cloudflare Workers 프로젝트 + Bolt JS 보일러플레이트·서명 검증·ack 1.0
Stage1 wiki-stage1.yml: repository_dispatch + Notion fetch + raw 박제 + Issue·자동 라벨 1.5
Stage2 wiki-stage2.yml: issues.labeled → claude-code-action wiki PR 1.0
라벨 5개 repo 생성 + #wiki-notify broadcast (Bolt → chat.postMessage) 0.5
PII redact 정규식·Workers KV dedupe·timeout·재시도 1.0
E2E QA (Slack 멘션 → PR merge 1회 통과) 0.5
합계 6.0 인일

Consequences

긍정

  • 월 $0 증분 — 모든 인프라 free tier 내. 학습·실험에 부담 0
  • 콜드스타트 0ms — Workers V8 isolate가 Slack 3초 SLA 안전
  • 기존 자산 100% 재사용NOTION_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, GitHub Actions 11개 인프라
  • 2단계 분리로 LLM 환각 사고 차단ADR-0013 §G 정책 인프라로 1:1 매핑
  • provenance 3겹 — Slack thread + GitHub Issue + wiki/log.md
  • edge computing·서버리스 학습 효과 — d-edu 자동화가 첫 프로젝트로 적절

부정

  • 초기 셋업 일회성 공수 — Slack App·Cloudflare 계정·GitHub App 발급 등 6 인일 (1~1.5주)
  • Workers JS·TypeScript만 지원 — Python·Java 코드 필요 시 Lambda로 이전
  • Bolt JS + Workers + claude-code-action 학습 ramp (1주 정도)
  • GitHub App 발급 30분~1시간 (PAT는 5분)
  • Slack workspace 권한 관리 — 비-CLI 팀원 변동 시 추가 운영
  • PII redact 정규식 의존 — 한국어 PII(주민번호·전화) 외 케이스 누락 가능 → 실제 사고 발생 시 presidio·Bedrock Guardrails 업그레이드 필요

Alternatives 거부

옵션 거부 사유
AWS Lambda + API Gateway 콜드스타트 100~500ms (Java/Python)로 Slack 3초 SLA 위험. ack 패턴으로 우회 가능하나 복잡도 ↑. IAM 학습 비용
Vercel Edge Functions Hobby tier non-commercial 전용. 상용 시 Pro $20/user/월 발생
n8n self-host (Docker) DigitalOcean/EC2 월 $5~$15 비용. 워크플로 JSON export로 git과 비대칭 버전 관리. UI는 빠르나 PII redact·dedupe는 코드 노드로 우회 필요
n8n Cloud / Zapier / Make task 한도 빠르게 소진 (Zapier 100/월, Make 1K ops/월). PII redact 어려움. lock-in ↑
Slack Workflow Builder 유료 플랜 전용. 키워드 trigger 채널 20개 제약. 코드 hook 한계
Slack outgoing webhook only reactions_added event 불가 (ADR-0013 §F 알림 정책 위반). legacy 카테고리 — Slack이 Events API 마이그레이션 권고
GitHub Action만 (outgoing webhook → repo_dispatch) Slack 3초 SLA 위반 — Actions 부팅 30~60s. ack 레이어 필요 → Workers와 동일 구조
fine-grained PAT "Resource not accessible" 403 빈번. Rate limit 5K/h. 사용자 권한 종속 (회사 떠나면 토큰 죽음)

향후 검토 항목

  1. 실제 구현 라운드 (Track Wiki-Bot, 6 인일)
  2. Slack App 생성 + OAuth scope + Bolt JS Workers 보일러플레이트
  3. GitHub App 발급 + WIKI_BOT_APP_ID·WIKI_BOT_APP_PRIVATE_KEY 시크릿 등록
  4. Cloudflare 계정 + Workers 프로젝트 + KV namespace
  5. wiki-stage1.yml·wiki-stage2.yml·wiki-stage3.yml 작성
  6. 라벨 5개 GitHub repo 생성
  7. PII redact 정규식·dedupe·timeout 구현
  8. E2E 검증 (Slack 멘션 → PR merge 1회)
  9. ADR-0015 디자이너·마케터 워크플로 — 본 인프라 그대로 재사용 (멘션 태그만 #design·#marketing 추가)
  10. 확장 시 Workers Paid·Slack Pro — 월 1만 req 이상 도달 시
  11. PII redact 업그레이드 — 정규식 → presidio·AWS Bedrock Guardrails (실제 PII 사고·법적 요구 발생 시)
  12. GitHub App → Slack App marketplace 등록 (오픈소스화·외부 사용 시)

Status

  • 2026-05-25: accepted

Date

2026-05-25