처음 하는 사람이 전문가 없이 업무 자동화 앱을 만들고, 올리고, 운영하기까지 — 부딪히는 7개의 벽과, 그 벽마다 standarda 가 세워 둔 장치.
업무 자동화(AX)를 외부 전문가에게 맡기면 빠르다. 그런데 만든 사람이 떠나는 날, 고객에게 무엇이 남는지는 따로 물어야 한다.
그런데 직접 하려면 벽이 있다
요즘은 AI 에게 말로 시키면 앱이 나온다. 하지만 말 한마디 뒤에는 처음 하는 사람이 답할 수 없는 질문이 숨어 있다 — 무엇이 다 필요한지, AI 가 만든 것이 맞는지, 모르고 한 실수는 없는지, 서버에는 어떻게 올리는지. 보통은 이 질문마다 전문가를 찾는다. 그래서 결국 다시 "맡기는" 쪽으로 돌아간다.
Brie 는 AX 를 대신 해 주지 않는다.
고객이 스스로 하게 만든다.
처음 하는 사람이 혼자 해낼 수 있는 이유는 그가 전문가가 되어서가 아니다. 전문가가 하나씩 답하던 질문들의 답을 출발점·부품·일하는 방식·검사기·서버 도구·교훈으로 미리 만들어 두었기 때문이다. 사람은 질문마다 공부하는 대신 무엇을 만들지 정하고, 승인하고, 확인한다.
이 자료는 처음 하는 사람이 부딪히는 벽을 하나씩 짚고, 각 벽에서 standarda 가 무엇을 대신 정해 두었는지를 실제 화면·명령·기록으로 보여 준다. 각 장 뒤의 "안 들여다보기" 쪽은 그 장치가 실제로 어떻게 생겼는지 궁금한 사람을 위한 것이다.
| 1 | 빈 화면"어디서부터?" — 질문의 답이 든 출발점을 세 번의 요청으로 연다 | 출발점(template) | 6 |
| 2 | AI 부품AI 호출·문서 읽기·메일·결과 검증을 검증된 공용 부품으로 | 공용 부품(core) | 18 |
| 3 | AI 에게 어떻게 시키나코드를 읽지 못해도 무엇을 만들지는 내가 정한다 | 일하는 방식(/develop) | 28 |
| 4 | 모르는 실수모르고 한 실수는 저장하기 전에 막힌다 | 검사기(hook) | 45 |
| 5 | 서버·배포·운영"배포해 줘" 한 마디, 실패하면 스스로 되돌아온다 | 서버 헬퍼(/release) | 58 |
| 6 | 혼자 배운 건 혼자만 안다한 사람이 겪은 일이 다음 사람의 출발점이 된다 | 교훈 고리(lesson-finder) | 70 |
| 7 | 우리 회사 인프라에서도?우리 회사의 서버·계정·도메인 위에 같은 체계가 선다 | 값 파일(site.env) | 81 |
| + | 처음부터 배포까지, 한 번에7개의 장치가 한 흐름으로 이어지는 모습과 지금까지의 기록 | 91 |
각 층은 처음 하는 사람이 혼자 답하기 어려운 질문 묶음 하나를 맡는다. 어느 층도 사람에게 공부를 요구하지 않는다 — 정해 둔 답을 쓰게 한다.
/develop)로. 사람은 쉬운 말 요약을 한 번 승인하고, 대조·점검은 AI 와 검증 에이전트가 한다.업무 자동화 앱을 직접 만들겠다고 마음먹은 사람이 가장 먼저 만나는 벽은 기술이 아니라 "어디서부터?"다. standarda 에서 시작은 한 문장이고, 끝은 남에게 보여 줄 수 있는 실제 주소다.
Brie 는 AX 를 대신 해 주지 않는다. 고객이 스스로 하게 만든다.
— 그 첫 번째 장치.
요즘은 말로 시키면 된다. "앱 만들어 줘. 회원가입·로그인 만들어 줘. DB 만들어 줘. 서버 주소 준비해 줘." 맞다 — standarda 도 말로 시킨다. 문제는 그 말 한마디 뒤에 숨은 질문들이다.
AI 는 이 질문마다 그럴듯한 답을 골라 만들어 준다. 처음 해 보는 사람은 그 답이 맞는지, 무엇을 더 물어야 하는지 알 수 없다. 그래서 남는 길은 둘이다.
질문마다 검색하고, 물어보고, 시행착오를 겪는다. 바이브코딩이라도 결국 본인의 시간과 노력이 든다.
모르는 질문은 고민조차 하지 않는다. 그러다 실제로 쓰는 날 막히고 나서야 그런 질문이 있었다는 걸 안다. 그때 고치는 데 더 오래 걸린다.
standarda 의 출발점에는 앞 쪽 질문들의 답이 이미 정해져 들어 있다. 그래서 사람은 질문마다 공부하는 대신, 그 출발점을 여는 세 가지만 한다.
./setup.sh — 사람이 넣는 값은 DB 비밀번호 하나settle_helper_admin 처럼 프로젝트 이름을 따서, 비밀번호는 무작위로 만들어 한 번만 보여 준다settle-helper-dev.brie.co.kr 을 등록한다실측 때 만든 프로젝트를 바로 열어 본 화면이다. 업무 기능은 아직 하나도 만들지 않았지만, 가입·로그인부터 견본 업무 화면까지 이미 동작한다. 사람이 할 일은 여기에 "우리 업무"를 얹는 것뿐이다.


한 문장으로 만든 프로젝트는 standarda-template 이라는 표준 골격에서 나온다. 이 골격이 어떤 기술로 되어 있고, 계정·데이터·화면·파일·공통 기능을 어떤 약속으로 정해 두었는지 여섯 쪽에 걸쳐 본다.
화면·서버·데이터베이스를 따로 다른 기술로 나누지 않는다. 서버 하나(Django)가 화면도 그리고 API 도 내보내므로, 업무를 아는 한 사람이 AI 와 함께 처음부터 끝까지 고칠 수 있다.
| 층 | 무엇으로 | 왜 이렇게 |
|---|---|---|
| 화면 | Django 템플릿 + HTML·CSS·JavaScript 프레임워크 없음 · 디자인 시스템 base.css | 빌드 도구 없이 파일을 고치면 바로 반영된다. 배울 것이 적다 |
| 서버 | Python 3.11 · Django 4.2 · Django REST Framework 3.14 | 화면과 API 를 한 서버에서. 계정·관리 화면이 기본으로 딸려 온다 |
| 데이터베이스 | PostgreSQL | 프로젝트마다 자기 DB 를 따로 가진다 |
| AI | Claude · GPT · Gemini, LangChain · LangGraph 공용 부품 standarda-core 를 통해 호출 | 모델을 바꿔도 코드를 거의 고치지 않는다 (벽 2 에서 자세히) |
| 설정 | 개발은 .env, 운영은 .env.production — 서버가 스스로 골라 읽는다 | 같은 코드로 개발·운영을 오간다 |
| 운영 | gunicorn + 웹서버 | 배포 명령 하나로 올린다 |
벽 1 의 "로그인 만들어 줘" 뒤에 숨은 질문들에 대해, 출발점은 아래처럼 답을 정해 두었다. 아이디는 이메일이다.
| 함께 정해진 것 | 출발점의 답 |
|---|---|
| 비밀번호 규칙 | 8자 이상, 영문·숫자·키보드 기호 각 1자 이상. 화면이 안내하는 규칙과 서버가 검사하는 규칙이 같고, 둘이 같은지 자동 테스트가 확인한다 |
| 로그인 없이 보이는 화면 | 첫 화면·로그인·가입·아이디 찾기·비밀번호 찾기 5개. 나머지는 로그인해야 열린다 |
| 프로필 | 계정이 어떤 방법으로 생기든(가입·관리자 도구·명령어) 함께 자동으로 만들어진다 |
| 관리자 계정 | 프로젝트를 만들 때 이름_admin 으로 자동 생성, 비밀번호는 무작위로 한 번만 보여 준다 |
| 메일 발송 | Google 메일(SMTP)로 보낸다. 설정이 빠지면 "메일 설정이 아직 안 됐다"고 화면에 원인을 알려 준다 |
| Google 계정 | Google 로그인(첫 로그인 시 자동 가입)과, 사용자별 Gmail·Drive 사용 동의를 서버에 갖춰 두었다. 화면 버튼은 Google 키를 넣은 뒤 켠다 |
출발점에는 목록·상세·등록·수정·삭제를 모두 갖춘 견본 업무 앱이 들어 있다. 새 업무 앱은 이 견본을 통째로 복사해 시작하므로, 데이터 구조·API·관리 화면이 프로젝트마다 같은 약속을 따른다.
| 칸 | 뜻 |
|---|---|
slug | 주소에 쓰는 고유 이름. 저장할 때 자동으로 만들어진다 |
name | 이름 |
owner | 만든 사람. 화면·API 는 "내가 볼 수 있는 것"만 꺼내는 한 가지 방법(visible_to)으로만 조회한다 |
active | 삭제하면 지우지 않고 숨긴다 — 관리 화면에서 되살릴 수 있다 |
timestamp · updated | 만든 시각 · 마지막으로 고친 시각 (이름을 모든 앱에서 통일) |
| 요청 | 하는 일 |
|---|---|
GET /api/앱/?q=…&page=… | 목록 — 검색, 20개씩 페이지 |
POST /api/앱/ | 등록 — 만든 사람은 로그인한 사람으로 자동 지정 |
GET · PATCH · DELETE /api/앱/이름/ | 상세 · 일부 수정 · 숨김 삭제 |
응답은 늘 같은 모양 — 성공 {"success": true, "data": …}, 입력 오류 {"success": false, "errors": …}. 화면 쪽 JS 는 이 모양 하나만 알면 된다.
/앱/ 목록 · /앱/new/ 등록/앱/이름/ 상세 · /앱/이름/edit/ 수정YYYY.MM.DD화면마다 파일 구성이 같고, 버튼·입력창·표·모달 같은 부품은 디자인 시스템에 이미 들어 있다. 그래서 새 화면은 부품을 조립하고 그 화면의 동작만 쓰면 된다.
base.css 에 들어 있는 부품색은 직접 값 대신 변수로 쓴다 — 회사 색으로 바꿀 때 한 곳만 고치면 된다.
api.js| 함수 | 해 주는 일 |
|---|---|
apiFetch() | 서버 호출 한 줄. 요청 형식·인증 토큰을 알아서 붙이고, 로그인이 풀렸으면 로그인 화면으로 보내고, 서버의 오류 문구를 꺼내 준다 |
escapeHtml() | 사용자가 입력한 글자를 화면에 그대로 안전하게 보여 준다 |
formatDateTime() | 날짜를 2026.11.11 13:50 형식으로 통일 |
goToLogin() | 지금 보던 화면을 기억한 채 로그인 화면으로 |
화면 동작은 늘 같은 순서로 쓴다 — 입력 확인 → 버튼을 "처리 중"으로 → 서버 호출 → 결과 그리기 → 버튼 되돌리기.
CSS·JS·이미지 같은 정적 파일과 사용자가 올린 파일은 코드 폴더 밖, 프로젝트 폴더 옆에 따로 모인다. 코드를 새로 받아도 올린 파일이 섞이거나 사라지지 않는다.
~/settle_helper/ ← 프로젝트 (파이썬 환경 포함)
└── src/ ← 코드 (GitHub 에 올라가는 곳)
├── static/ ← 내가 만든 CSS · JS · 이미지
└── templates/
~/settle_helper_static_cdn/ ← 코드 밖, 프로젝트 옆
├── static/ ← 운영용으로 모은 정적 파일
└── media/ ← 사용자가 올린 파일
| 개발 서버 | 운영 서버 | |
|---|---|---|
| 정적 파일 | 개발 서버가 src/static/ 을 직접 내보낸다. 고치면 새로고침만으로 반영 | 배포할 때 한곳(_static_cdn/static)으로 모으고, 웹서버가 직접 내보낸다 |
| 파일 이름 | 그대로 | 내용이 바뀌면 이름에 표시가 붙어, 사용자 브라우저가 옛 파일을 붙잡고 있지 않는다 |
| 올린 파일 | 개발 서버가 내보낸다(로그인 필요) | 웹서버가 _static_cdn/media 에서 직접 내보낸다 |
| 모으는 작업 | 필요 없다 | 배포 명령이 매번 알아서 한다 |
폴더는 프로젝트를 만들 때(setup.sh) 자동으로 생긴다. 출발점에 들어 있는 업로드 칸은 프로필 이미지 하나이며, 날짜별 폴더에 겹치지 않는 이름으로 저장된다.
utils/ 에는 거의 모든 프로젝트가 똑같이 필요로 하는 일을 미리 만들어 둔 함수가 모여 있다. 화면과 API 를 만들 때는 이 함수들을 가져다 쓰고, 같은 코드를 다시 쓰지 않는다.
| 함수(파일) | 하는 일 | 그래서 덜어 주는 것 |
|---|---|---|
login_required | 로그인해야 열리는 화면을 기본으로 만든다. 열어 둘 화면만 목록에 적는다 | 화면마다 "로그인 확인" 코드를 넣지 않는다 |
api_auth | 로그인이 풀린 API 요청에 "로그인 필요"(401)로 답한다 | 화면 JS 가 이 답을 보고 로그인 화면으로 보낸다(apiFetch) |
validator_utils | 비밀번호 규칙, 빈 값·중복·존재 여부, 3분 시간 제한, 두 값 일치 등 입력 확인 | 가입·찾기 화면의 확인 규칙을 한 곳에서 관리 |
accounts_utils.send_email | Google 메일로 HTML 메일 발송. 텍스트판 함께 첨부, 한글 발신자 이름 처리 | 인증번호·알림 메일을 한 줄로 보낸다 |
generator_utils | 겹치지 않는 무작위 이름(slug) 생성 | 모든 데이터의 주소용 이름을 자동으로 |
error_data 외 | 오류 번호 목록, 권한 확인, 응답 형식 등 계정 기능이 쓰는 보조 함수 | 계정 기능 안에서 쓰인다 |
새 업무 앱은 견본 방식을 따른다
업무 앱(견본 앱)은 Django·DRF 가 기본으로 주는 기능만으로 만들어져 있고, 위 함수 중 로그인 관련 함수와 이름(slug) 생성 함수만 가져다 쓴다. 계정 기능 전용 보조 함수는 계정 앱 안에서만 쓰인다 — 새 앱을 만들 때 따라야 할 기준은 하나, 견본 앱이다.
| 항목 | 내용 |
|---|---|
| 일시·장소 | 2026-11-11, Brie 개발 서버(brie-box). 관리자 계정으로 실행 |
| 방법 | 3쪽의 세 단계를 사람이 하듯 그대로 실행하고 단계마다 시작·끝 시각을 기록했다. 1·3단계는 Claude Code 에 말로 요청했고, 2단계는 ./setup.sh 에 DB 비밀번호를 넣어 실행했다 |
| 끝난 기준 | 바깥에서 주소 https://timing-check-dev.brie.co.kr/ 가 정상 응답(HTTP 200)한 시각 |
| 포함하지 않은 것 | 처음 쓰는 사람이 한 번만 하는 준비 — 서버 접속, GitHub·Claude 로그인 (교육 첫 시간에 함께 한다) |
| 뒷정리 | 측정에 쓴 프로젝트·저장소·데이터베이스·주소는 측정 직후 모두 지웠다 |
출발점을 열었다면 다음은 "우리 업무"다. 문서를 읽고, 엑셀을 정리하고, 메일을 보내고, 결과를 시트에 적는 일이다. 이 일들에 필요한 AI 기능을 매번 새로 만들면 처음 하는 사람은 그 자리에서 멈춘다. standarda 에서는 검증된 부품을 꺼내 쓴다.
Brie 는 AX 를 대신 해 주지 않는다. 고객이 스스로 하게 만든다.
— 그 두 번째 장치.
업무 자동화의 대부분은 문서를 읽고, AI 에게 묻고, 결과를 어딘가에 남기는 일이다. 말로 시키면 AI 가 코드를 써 준다. 하지만 그 코드가 실제 업무에서 매일 돌아가려면 아래 질문들에 먼저 답해야 한다.
벽 1 과 같다. AI 는 질문마다 그럴듯한 답을 골라 만들어 준다. 처음 하는 사람은 그 답이 맞는지 알 수 없고, 질문마다 찾아보고 공부하거나, 업무에 쓰는 날 막히고 나서야 안다.
앞 쪽 질문들의 답은 공용 부품 묶음 standarda-core 에 함수로 들어 있다. 그리고 출발점의 AI 작업 규칙이 "AI 기능은 core 부품으로만 만든다"고 정해 두었다. 그래서 사람은 부품 이름을 몰라도 된다.
| 앞 쪽 질문 | 부품이 정해 둔 답 |
|---|---|
| 어느 AI 를 쓰나 | 함수 하나로 연결. 모델 이름은 설정 파일에 — 코드는 그대로 |
| 글자로 읽나, 그림으로 보나 | 두 방법이 모두 부품으로 있다. 문서 성격에 맞춰 고르기만 한다 |
| AI 답을 프로그램이 읽을 수 있나 | 앞뒤 설명을 걷어내고 표 형식만 꺼내는 함수 — 가장 많이 쓰이는 부품 |
| 비용은 얼마나 드나 | 반복 지시문은 자동으로 캐시, 구간별 사용량·비용을 모아 준다 |
| 모델이 새로 나오면 | 새 모델의 차이는 부품이 흡수한다 (다음 쪽) |
AI 는 몇 달마다 새 모델이 나오고, 그때마다 예전엔 되던 것이 갑자기 안 된다. 프로젝트마다 AI 코드를 따로 갖고 있으면 그 원인을 각자 찾아야 한다. standarda 에서는 부품 한 곳을 고치고, 각 프로젝트는 부품 버전만 올린다.
| 실제로 겪은 일 | 원인 | 부품이 정한 답 |
|---|---|---|
| 새 Claude 모델·SDK 로 바꾸자 AI 호출이 전부 실패 | 새 버전이 예전 설정값 하나를 더 이상 받지 않았다 | 부품이 모델을 보고 그 값을 빼고 보낸다 — 한 번 고쳐 전 프로젝트 반영 |
| 같은 지시문을 반복해서 보내는데 캐시 적중률 3% 미만 — 비용이 그대로 나감 | 캐시 표시를 붙이는 위치가 틀렸다 | AI 도구 호출 뼈대가 캐시 표시를 자동으로 붙인다 |
| Gemini 새 버전에서 답을 글자로 못 읽음 | 답이 글자가 아니라 여러 조각의 목록으로 왔다 | 어느 모델의 답이든 글자 하나로 맞춰 주는 함수 |
| 알림 메일의 줄바꿈이 사라짐 — 두 번 반복 | 메일 본문을 만들 때마다 각자 다르게 처리 | 알림 메일 HTML 을 만드는 부품 하나로 통일 |
| 회의 녹음 받아쓰기 실패 | 파일 형식·특수 문자 처리 | 녹음을 표준 형식으로 바꾸고, 나눠서 동시에 받아쓴 뒤 정리하는 부품 |
한 프로젝트에서 검증된 기능은 core 로 올라와 모두의 부품이 된다. 슬라이드 PDF 만들기, 회의 녹음 받아쓰기, 결과 검증 함수가 그렇게 올라왔다. core 는 2026년 2월 이후 버전 30개를 냈고, 이 서버의 프로젝트 13개가 core 를 버전으로 고정해 쓰고 있다.
처음 하는 사람은 AI 의 변화를 쫓지 않아도 된다
새 모델에 맞추는 일, 비용을 아끼는 일, 파일 형식마다 읽는 법을 찾는 일은 부품이 맡는다. 사람은 업무 흐름에만 집중한다.
공용 부품 묶음 standarda-core 는 모든 프로젝트가 설치해 쓰는 파이썬 패키지다. 부품 21개 파일에 공개 함수 52개, 구글 서비스 연결 43개가 들어 있다. 다섯 쪽에 걸쳐 묶음별로 본다.
어느 회사의 AI 든 함수 하나로 연결한다. 코드에는 "AI 를 쓴다"만 적고, 어떤 모델을 쓸지는 설정 파일이 정한다.
| 함수 | 연결하는 곳 | 기본 모델 (설정으로 변경) |
|---|---|---|
get_anthropic_llm() | Claude | claude-sonnet-5-5 |
get_openai_llm() | GPT | gpt-6-luna |
get_google_llm() | Gemini | gemini-3.8-flash |
get_openrouter_llm() | OpenRouter — 여러 회사 모델을 한 곳에서 | 쓸 때 지정 |
get_openai_embedding() | 문장을 숫자로 바꾸기(검색용) | text-embedding-3-small |
| 차이 | 부품이 하는 일 |
|---|---|
| 새 Claude 모델은 예전 설정값(temperature)을 받지 않는다 | 모델·SDK 버전을 보고 그 값을 빼고 보낸다 |
| 생각하는 모델은 답이 길다 | 답 길이 상한을 넉넉히 기본으로 둔다(설정으로 변경) |
| Gemini 새 버전은 답이 여러 조각으로 온다 | 답을 글자 하나로 맞추는 response_text() |
| 키가 없으면 | 프로그램을 멈추지 않고, 경고를 남기고 "연결 없음"을 돌려준다 |
모든 연결에 응답 대기 시간·재시도 횟수를 정할 수 있고, 호출 기록은 추적 도구(LangSmith)에 자동으로 남는다 — 어느 단계에서 무엇을 묻고 무엇을 받았는지 나중에 볼 수 있다.
PDF 와 엑셀에는 읽는 길이 두 가지씩 있다. 문서가 깔끔한 글자 위주면 글자로, 표·도장·스캔본이면 그림으로 읽는다. 어느 쪽이든 함수 하나다.
| 문서 | 글자로 읽기 — 빠르고 싸다 | 그림으로 보기 — 표·스캔본도 정확하게 |
|---|---|---|
send_pdf_to_text_llm()글자를 뽑아 AI 에 보낸다 | send_pdf_to_vision()쪽마다 이미지로 바꿔 AI 가 본다 (기본 15쪽까지) | |
| 엑셀 | send_excel_to_text_llm()셀 값을 글자로 뽑아 보낸다 | send_excel_to_vision()PDF 로 바꾼 뒤 그림으로 본다 — 서식·병합 셀이 많을 때 |
| 구글 시트 | send_sheet_to_llm() — 시트 내용을 그대로 AI 에 보낸다 | |
| 기타 문서 | extract_text_from_document() — 텍스트·마크다운·워드·PDF·한글(HWP·HWPX)·RTF·ODT 에서 글자를 뽑는다. 한글 인코딩이 깨지지 않게 여러 방식을 차례로 시도한다 | |
글자 인식(OCR) 프로그램은 따로 두지 않는다 — 스캔본도 AI 가 그림으로 읽는다.
| 함수 | 하는 일 |
|---|---|
parse_json_from_llm() | AI 답에서 앞뒤 설명을 걷어내고 표 형식(JSON)만 꺼낸다. 프로젝트 코드에서 가장 많이 불리는 부품 |
response_text() | 어느 모델의 답이든 글자 하나로 맞춘다 |
사람이 이 코드를 쓰지 않는다 — "이 계약서에서 금액과 기간을 뽑아 줘"라고 하면 AI 가 이 부품들로 조립한다.
자동화의 결과는 새 화면이 아니라 늘 쓰던 곳에 남을 때 쓰인다. 구글 업무 도구 네 가지를 부품으로 연결해 두었다.
| 도구 | 기능 수 | 할 수 있는 일 |
|---|---|---|
| 구글 시트 | 21 | 값·수식 읽고 쓰기, 한꺼번에 고치기, 시트 복제·삭제·복사, 행 넣고 빼기, 셀·머리글 찾기, PDF 로 내보내기 |
| 구글 드라이브 | 11 | 폴더·파일 목록, 폴더 만들기, 올리기·내려받기, 복사·이동, HTML 을 구글 문서로 바꿔 올리기 |
| Gmail | 8 | 첨부 메일·알림·답장 보내기, 받은편지함·보낸 메일 조회, 첨부 내려받기, 답장 찾기 |
| 구글 문서 | 3 | 문서 내용 읽기 — 탭이 여러 개인 문서도 |
연결 방식은 두 가지 — 회사 계정 하나로 쓰거나, 사용자마다 자기 구글 계정으로 동의하고 쓴다(내 메일·내 드라이브를 대상으로 하는 업무).
render_email_html()transcribe_audio()create_presentation()AI 를 매일 업무에 쓰기 시작하면 세 가지가 남는다. 비용이 얼마나 드는지, 여러 단계를 스스로 처리하는 에이전트를 어떻게 돌리는지, 결과를 어떻게 믿을지.
| 부품 | 하는 일 |
|---|---|
| 지시문 캐시 | 매번 같은 긴 지시문은 한 번만 제값을 내고 다음부터는 싸게 보낸다. 캐시 표시를 붙이는 위치를 부품이 정해 둔다 |
track_usage() | "이 작업 한 번에 얼마"를 잰다 — 그 구간의 모든 AI 호출 사용량을 모아 비용으로 바꾼다(모델별 가격표 내장) |
| 단계별 모델 고르기 | 여러 단계로 된 작업에서 단계마다 어떤 모델 조합이 같은 정확도에 가장 싼지 실험한다(AgentOpt) |
build_tool_loop_graph()AI 가 도구(검색·조회·계산 등)를 골라 쓰고, 결과를 보고, 다시 판단하는 반복 구조의 뼈대다. 도구를 순서대로 실행하고, 대화가 길어져도 캐시를 이어 붙이고, 반복 횟수 상한과 마지막 답 꺼내기까지 정해져 있다. 프로젝트는 도구만 만들어 끼운다.
AI 가 "다 처리했다"고 말하는 것과 실제로 맞게 처리된 것은 다르다. 검증 부품은 그 차이를 숫자로 보여 준다 — 사람은 다른 것만 보면 된다.
여러 사람이 만든 여러 프로젝트가 같은 부품을 쓴다. 그래서 부품은 "쓰는 쪽 코드는 그대로, 버전만 올리면 좋아진다"는 약속을 지킨다.
| 약속 | 지키는 방법 |
|---|---|
| 버전으로 고정해서 쓴다 | 각 프로젝트는 core 를 버전 번호로 고정해 설치한다. 올리기 전까지는 아무것도 바뀌지 않는다 — 오래된 프로젝트도 그대로 돈다 |
| 있던 것은 지우지 않는다 | 함수와 입력값은 지우거나 이름을 바꾸지 않고, 새 옵션만 더한다. 꼭 합쳐야 하면 옛 이름을 남겨 둔다 |
| 테스트가 지킨다 | 자주 쓰는 함수 9개의 입력값 이름을 테스트로 묶어 두었다. 이름이 사라지면 자동 검사가 실패한다. 파이썬 두 버전·깨끗한 설치에서 매번 확인 |
| 바뀐 것은 기록한다 | 버전마다 무엇이 바뀌었는지, 쓰는 쪽이 할 일이 있는지, 어느 프로젝트에서 확인했는지를 팀 위키에 남긴다 |
약속을 문서로만 두었을 때 생긴 일
2026년 8월, 함수 두 개를 하나로 합치면서 옛 입력 방식 하나가 빠졌다. 그 방식으로 부르던 엑셀 그림 읽기가 모두 실패했고, 위치로만 부르던 프로젝트들은 멀쩡해서 몇 버전 동안 드러나지 않았다. 그날 바로 옛 방식을 되살리고, 자동 검사를 들였다 — 하루에 버전 세 개. 그 뒤로 약속은 사람이 아니라 테스트가 지킨다.
| 시기 | 무엇이 들어왔나 |
|---|---|
| 2 ~ 4월 | 한 프로젝트의 공통 기능을 떼어 내 부품 묶음을 만들었다 — 문서 읽기, AI 연결 |
| 4 ~ 5월 | 구글 드라이브·Gmail·문서 부품 확장, 문서 글자 뽑기 |
| 6 ~ 7월 | 캐시·비용 집계, 에이전트 뼈대, OpenRouter |
| 7 ~ 8월 | 프로젝트에서 검증된 기능을 부품으로 — 결과 검증, 발표 자료, 한글, 사용자별 구글 연결, 받아쓰기, 알림 메일 |
| 8월 | 약속을 테스트로 — 자동 검사 도입 |
| 9 ~ 11월 | 새 모델 세대(Claude 5 등)에 맞춤 |
출발점과 부품이 있어도, 결국 일은 AI 에게 말로 시킨다. 처음 하는 사람이 여기서 막히는 이유는 AI 가 못해서가 아니라, AI 가 만든 것이 맞는지 판단할 방법이 없어서다. standarda 는 AI 가 일하는 방식 자체를 정해 둔다.
Brie 는 AX 를 대신 해 주지 않는다. 고객이 스스로 하게 만든다.
— 그 세 번째 장치.
AI 는 시키면 만든다. 문제는 그다음이다. 결과를 판단하고, 이어서 고치고, 남에게 넘기는 일은 여전히 사람의 몫인데, 코드를 읽지 못하면 그 판단을 할 근거가 없다.
이 질문들은 코드 지식이 아니라 일하는 방식의 문제다. 숙련된 개발자는 경험으로 답하지만, 처음 하는 사람에게는 답할 근거가 없다.
"만들어 줘", "고쳐 줘" 같은 개발 요청은 따로 말하지 않아도 /develop 이라는 정해진 흐름으로 처리된다. 흐름 안에서 사람이 하는 일은 한 번의 승인뿐이고, 나머지 확인은 AI 와 검증 에이전트가 한다.
docs/specs/앱.md 에 쓴다 — 위층은 비개발자용 요약, 아래층은 코드와 하나씩 대조할 수 있는 검증용 명세.spec_check.md)대로 스펙의 명제마다 코드를 확인한다. 하나라도 어긋나면 합치기가 막히고, 고친 항목만 다시 확인한다. 화면 주소가 실제로 열리는지도 본다.merge_check.md)로 미커밋 변경·필수 문서·다른 작업과 겹치는 파일·관련 테스트를 확인한다. 통과하면 정본에 합치고, 작업 공간을 정리하고, 할 일 목록에서 완료 처리한다.오타·문구·설정값처럼 자명한 변경은 이 흐름 없이 바로 고친다. 회원가입·로그인 요청은 이미 있는 기능이므로 먼저 /signup 으로 확인한다.
앞 쪽의 질문들은 숙련자라면 경험으로 답한다. standarda 는 그 경험을 흐름과 규칙으로 바꿔, 처음 하는 사람도 같은 답을 갖고 일하게 한다.
| 질문 | standarda 의 답 |
|---|---|
| 내가 원한 게 맞나 | 코드가 아니라 쉬운 말 요약을 보고 승인한다. 맞게 만들어졌는지는 그 요약에서 나온 검증 명세를 기준으로 AI 가 점검표대로 하나씩 확인한다 |
| 어디서 내가 확인하나 | 시작 전 한 번. 판단이 필요한 지점을 한곳에 모았다 |
| 다른 기능은 멀쩡한가 | 합치기 전 점검이 관련 테스트를 돌리고, 다른 작업과 겹친 파일을 알려 준다 |
| 동시에 여러 개를 시키면 | 요청마다 격리된 작업 공간. 끝나면 정본 하나로 합친다 |
| 내일의 AI 는 기억하나 | 스펙 파일과 프로젝트 메모리가 남는다. 다음 대화의 AI 는 그것부터 읽는다 |
| 오류가 나면 | 규칙이 "추측하지 말고 로그부터"를 정해 두었고, 로그를 먼저 읽는 에이전트가 있다 |
| 무엇을 남겨야 하나 | 스펙은 반드시, 버그 수정이면 원인·해결·교훈을 담은 이슈 문서 — 빠지면 합치기 전에 걸린다 |
| 매번 같은 품질인가 | 누가 시키든 같은 흐름·같은 규칙. 사람마다 다른 "시키는 법"이 하나로 정리된다 |
처음 하는 사람에게 필요한 것은 코딩 실력이 아니라 판단할 자리다
standarda 는 그 자리를 "쉬운 말 요약을 승인하는 한 번"으로 만들어 두었다. 다음 쪽부터는 이 흐름을 받치는 AI 작업 규칙, 스킬 17개, 에이전트 12개를 하나씩 본다.
출발점에는 코드와 함께 AI 가 일하는 방식이 들어 있다. 이것을 하네스(harness, 마구)라고 부른다 — 힘센 말이 엉뚱한 데로 달리지 않게 채우는 장비처럼, AI 가 정해진 방향으로 일하게 한다.
| 구성 | 쉬운 말로 | 규모 |
|---|---|---|
AI 작업 규칙CLAUDE.md | AI 가 매 대화를 시작할 때 자동으로 읽는 근무 규칙집 | 536줄, 16개 섹션 |
| 스킬 | AI 에게 주는 업무 매뉴얼. "배포해 줘"처럼 말로 부르면 그 순서를 따른다 | 17개 |
| 에이전트 | AI 가 일을 나눠 맡기는 전문 보조원. 대부분 읽기만 하고 결과를 보고한다 | 12개 |
| 작업 공간 | 같은 코드의 작업용 사본. 여러 작업이 동시에 돌아도 섞이지 않는다 | 요청마다 하나 |
AI 가 규칙을 어기려 할 때 기계가 멈추는 장치(hook)는 벽 4 에서 따로 다룬다.
CLAUDE.md 는 AI 가 대화를 시작할 때마다 자동으로 읽는 문서다. 사람마다 AI 에게 다르게 설명하던 "이 프로젝트에서는 이렇게 한다"가 여기 한곳에 적혀 있어, 누가 시키든 AI 가 같은 기준으로 일한다.
| 섹션 | 무엇이 적혀 있나 |
|---|---|
| 팀 위키 참조 | 작업 전에 팀 위키부터 읽는다. 서버 사용법·포트 고르는 법 |
| 명령·구조·환경 설정 | 자주 쓰는 명령, 공통 앱 5개(견본 앱 포함), core 부품 목록, 설정 값 목록, 파일 저장 위치 규약 |
| 구글 연동·화면 규칙 | 시트·메일·드라이브·문서를 쓰는 법, 화면은 프레임워크 없이·공통 JS 로 |
| 코드 규칙 (128줄, 가장 큼) | 반복된 실수를 규칙으로 만든 목록 — 아래 |
| 디버깅 규칙 | 추측하지 말고 증거부터 — 5단계 |
| 개발 흐름 | 개발 요청은 /develop 이 기본, 회원가입은 /signup 먼저 |
| Git 규칙 | 정본은 하나, 작업은 사본에서, 끝나면 정본에 합치고 정리까지 |
| 문서 규칙 | 문서 종류별 위치, 버그 기록 양식과 "교훈을 어디까지 퍼뜨릴지" 분류 |
| 스킬·에이전트 규칙 | 만드는 위치, 이름표(description) 쓰는 법, 말로도 부를 수 있게, 되돌릴 수 없는 일은 실행 전 확인 |
get_*_llm(), AI 답은 response_text()·parse_json_from_llm(), PDF·엑셀은 글자/그림 중 골라서, 받아쓰기는 transcribe_audio()debug-server-log)에게 먼저 맡긴다.핵심 문장
디버깅의 품질은 AI 가 더 똑똑하게 추측하는 데서가 아니라, AI 가 닿을 수 있는 진짜 증거의 양에서 나온다.
버그를 고치면 원인·해결·교훈을 담은 이슈 문서를 남기고, 그 교훈을 어디까지 퍼뜨릴지 네 층 중 하나로 고른다.
| 층 | 교훈이 가는 곳 |
|---|---|
| 1 코드 규칙 | 이 규칙집의 코드 규칙으로 — 앞으로 모든 AI 가 따른다 |
| 2 공통 · 3 분야별 | 팀 위키의 교훈 모음으로 — 다른 프로젝트에서 lesson-finder 가 찾아 준다 |
| 4 이 프로젝트만 | 이슈 문서에만 남긴다 |
스킬은 AI 에게 주는 업무 매뉴얼이다. 슬래시(/dev)로 불러도 되고 "서버 켜 줘"처럼 말로 해도 된다. 개발 흐름 /develop 은 앞에서 보았으므로, 나머지를 본다.
https://이름-dev.brie.co.kr, 규칙집의 접속 정보/develop 보다 먼저 쓴다/develop 으로 고친다(관리자 승인제는 참고 구현 포함)/email-setup) → 브라우저로 직접 가입해 보기 → 운영 반영·고객 안내 문구/signup 이 중간에 부른다스킬이 서로를 부른다
회원가입 하나만 해도 /signup → /develop → /email-setup → /dev → /release 가 차례로 이어진다. 사람은 "회원가입 만들어 줘" 한 마디와 그 사이의 결정 몇 가지만 한다.
업무 시스템은 만들고 끝나지 않는다. 쓰는 사람에게 사용법을, 확인하는 사람에게 테스트 방법을 넘겨야 한다. 이 자료들을 실제 코드와 화면을 기준으로 만든다.
ui-tester 에게 맡긴다 — 기존 데이터만 쓰고 저장·전송은 누르지 않는다docs/features/기능.mdscreen-reviewer 여러 명에게 동시에 나눠 눈으로 판정하게 한다/develop 으로한 프로젝트에서 찾은 더 나은 방법이 그 프로젝트에만 남으면 다음 프로젝트는 같은 시행착오를 다시 겪는다. 두 스킬이 출발점(템플릿)과 프로젝트 사이를 양쪽으로 잇는다.
docs/structures/주제.mddocs/skill_agent_list/ 목록표에이전트는 메인 AI 가 일을 나눠 맡기는 전문 보조원이다. 대부분 읽기만 하고 결과를 보고하며, 일부는 더 가볍고 빠른 모델로 돈다. 검증 에이전트는 메인 AI 가 만든 것을 다른 눈으로 본다.
스펙 대조·합치기 전 점검은 메인 AI 가 직접 한다 (2026-11-13~)
원래 spec-verifier·merge-master 두 에이전트가 맡던 일이다. 리허설에서 검증 에이전트가 멈춰 메인이 7분을 기다린 뒤, 두 에이전트를 메인 AI 가 따르는 점검표(spec_check.md·merge_check.md)로 바꿨다. 점검 항목은 같다 — 스펙의 명제마다 코드 대조(입출력·흐름·업무 규칙·주소·계산), 합치기 전 미커밋 변경·필수 문서·다른 작업과 겹친 파일·관련 테스트.
/screen-audit 이 여러 명을 동시에/develop 이 큰 작업일 때 자동docs/llm_usage.md (매번 전체를 새로)/develop 마지막에 자동/develop 에서 API 를 바꿨을 때/develop 이 끝나면 "화면 확인이 필요하면 ui-tester 로" 한 줄을 남긴다하루 동안 오가는 요청이 어느 스킬로 들어가고, 그 스킬이 어떤 에이전트를 부르는지 한 장에 모았다. 사람이 외워야 할 명령은 없다 — 말로 하면 규칙집이 맞는 흐름으로 보낸다.
처음 하는 사람이 알아야 할 것은 "무엇을 원하는지"뿐이다
스킬 17개와 에이전트 12개의 이름을 몰라도 된다. 그 대신 승인할 때 쉬운 말 요약을 읽고, 정책 질문에 답하고, 결과를 눈으로 확인하는 일 — 업무를 아는 사람만 할 수 있는 일을 한다.
처음 하는 사람은 무엇이 실수인지 모른다. 규칙으로 적어 두면 숙련자는 지키지만, 처음 하는 사람도 AI 도 잊는다. standarda 는 실수가 일어나는 바로 그 순간에 멈추고, 왜 멈췄는지와 대신 무엇을 하면 되는지를 알려 준다.
Brie 는 AX 를 대신 해 주지 않는다. 고객이 스스로 하게 만든다.
— 그 네 번째 장치.
AI 와 함께 처음 무언가를 만드는 사람은 아래 일들이 문제라는 것 자체를 모른다. 화면은 멀쩡하게 돌아가므로, 문제는 한참 뒤 다른 사람이 이어받을 때나 무언가 어긋났을 때 드러난다.
규칙으로 적어 두는 것만으로는 안 된다
위 실수들은 모두 규칙집(CLAUDE.md)에 "하지 말라"고 적혀 있다. 그래도 일어났다 — 사람은 바빠서 잊고, AI 는 긴 대화 중에 놓친다. 그래서 규칙을 읽는 것이 아니라 통과해야 하는 것으로 바꿨다.
검사기(hook)는 정해진 순간에 자동으로 돌아 규칙에 어긋나면 그 동작을 멈춘다. 프로젝트를 만들 때 이미 설치돼 있어서, 쓰는 사람은 존재를 몰라도 보호를 받는다.
| 막는 실수 | 언제 | 막으면 알려 주는 것 |
|---|---|---|
| AI 가 명령을 실행하거나 파일을 쓰기 직전 — Claude hook 6개 | ||
| 오류를 고치고 원인 기록(이슈 문서)을 안 남김 | 커밋 직전 | 이슈 문서를 같은 커밋에 넣으라 |
| 기능을 만들고 스펙을 안 남김 | 커밋 직전 | 스펙 문서를 넣으라(/develop 이 만들어 준다) |
| 스킬·에이전트를 바꾸고 목록을 안 고침 | 커밋 직전 | 목록 갱신 스킬을 먼저 돌리라 |
| 오류의 흔적(추적 정보)을 지우는 코드 | 커밋 직전 | 문제의 파일·줄과 바꿀 방법 |
| 원격 서버에서 위치에 의존하는 명령 | 실행 직전 | 절대경로로 바꾸는 법 |
| 대충 쓴 스킬 이름표 | 파일 쓰기 직전 | 무엇을·언제 쓰는지, 비슷한 스킬과의 경계를 적으라 |
| git 이 커밋·올리기·되돌리기를 하는 순간 — git hook 5개 (사람이 직접 해도 막힌다) | ||
| 원인 기록 없는 오류 고침 커밋 | 커밋 | 이슈 문서를 넣으라 |
| 목록을 안 고친 스킬 변경 | 커밋 | 목록을 갱신하라 |
| 엉뚱한 저장소로 올리기 | 올리기(push) | 올리려던 곳과 원래 저장소, 고치는 명령 |
| 정본(main) 되돌리기·덮어쓰기 | 정본이 움직이는 순간 | 사라질 커밋 수, 대신 쓸 방법(git revert) |
| 정본 다시 쓰기(rebase) | rebase 시작 전 | 대신 쓸 방법(merge) |
Claude hook 과 git hook 이 같은 실수를 두 번 막는 곳이 있다 — AI 가 아닌 사람이 직접 커밋해도 git 단계에서 한 번 더 걸리게 하기 위해서다.
standarda 로 새로 만든 프로젝트(settle_helper)에서 실제로 시도한 결과다. 아래 출력은 손대지 않은 그대로다.
AI 가 명령을 실행하거나 파일을 쓰기 직전에 Claude Code 가 검사기에 넘기는 것과 같은 입력을 넣어 받은 응답이다. AI 는 이 응답을 읽고 스스로 고쳐 다시 시도한다.
여러 사람과 여러 AI 대화가 같은 정본에 작업을 합친다. 그중 하나가 정본을 되돌리면, 이미 "끝났다"고 보고된 다른 작업이 사라진다. 그래서 정본은 앞으로만 움직이게 했다.
| 장치 | 하는 일 |
|---|---|
| 정본은 앞으로만 | main·master(와 원격 기본 브랜치)가 뒤로 가는 순간만 막는다. 명령어를 금지하는 게 아니다 — 작업 브랜치의 되돌리기·다시 쓰기는 자유, 정본에 새 커밋·합치기·되돌리기 기록(revert)도 자유 |
| rebase 는 시작 전에 | 정본을 다시 쓰는 rebase 는 시작하기 전에 막아, 중간에 멈춘 뒷정리가 남지 않게 |
| 올리는 곳 확인 | 프로젝트를 만들 때 정해진 저장소가 아니면 올리기를 막는다 |
| 검사기가 지워지는 우회까지 | "되돌리기" 명령이 검사기 파일부터 지워 보호를 우회한 일이 있었다(점검 중 발견). 그래서 git 이 실제로 읽는 검사기는 작업 폴더 밖에 두고, 작업 폴더의 원본이 사라지면 설치 때 남긴 사본이 대신 지킨다 |
| 막는 쪽과 열어 두는 쪽 | 정본 보호 검사기는 고장 나면 막는 쪽(fail-closed), 문서 검사 같은 품질 검사기는 고장 나면 통과시키되 알리는 쪽(fail-open) — 설치가 깨져도 일이 멈추지 않게 |
권한을 뺏는 게 아니라 "실수로"를 "알고서"로 바꾼다
정말 되돌려야 하면 프로젝트 이름이 들어간 표시(SETTLE_HELPER_ALLOW_MAIN_REWIND=1)를 붙여 실행하면 된다. 목적은 금지가 아니라, 모르고 한 되돌리기를 알고 하는 되돌리기로 바꾸는 것이다.
검사기가 "하면 안 되는 것"을 막는다면, 기본값은 "해야 하는데 모르는 것"을 미리 해 둔다. 아래는 모두 누군가 한 번 겪은 일을 출발점의 기본값으로 바꾼 것이다.
| 모르고 하는 실수 | 실제로 겪은 일 | 지금 출발점의 기본값 |
|---|---|---|
| 날짜를 그냥 저장 | 저장한 시각과 화면에 보이는 시각이 9시간씩 어긋남 | 시간대를 지켜 저장하고 서울 시각으로 보여 준다(설정과 규칙) |
| 계정에 딸린 정보를 빠뜨림 | 관리자 도구로 만든 계정으로 로그인하자 오류 — 교육 리허설에서 세 번 반복 | 계정이 어떤 방법으로 생기든 프로필이 함께 만들어진다 |
| 등록 화면만 만들고 끝 | 견본에 등록 기능 하나뿐이라 AI 가 그대로 따라 만듦 | 견본 업무 앱이 목록·상세·등록·수정·삭제를 모두 갖춤 |
| 화면과 서버가 다른 규칙 | 화면이 안내한 비밀번호 Abcd-1234 를 서버가 거부 | 같은 규칙을 쓰고, 둘이 같은지 자동 테스트가 확인 |
| 개발·운영 설정을 섞음 | 운영 설정 파일이 늦게 읽혀 개발 값으로 돌던 함정 | 서버가 스스로 판단해 맞는 설정 파일을 먼저 읽는다 |
| 관리자 계정을 손으로 | 셋업 중 입력에서 멈추고, 팀마다 관리자 아이디가 제각각, 운영 서버엔 0명 | 개발·운영 서버 모두 관리자 계정이 자동으로 만들어진다 |
| 파일을 엉뚱한 곳에 | 작업 공간에서 서버를 띄우면 올린 파일이 다른 폴더에 쌓이고 합친 뒤 사라짐 | 파일 위치를 "어느 환경으로 실행했나" 기준으로 계산 — 어디서 띄워도 같은 곳 |
검사기와 기본값은 짝이다 — 기본값은 처음부터 맞게 해 두고, 검사기는 그 기본값에서 벗어나려는 순간을 잡는다.
실수를 막는 장치가 있어도, 그 장치가 고장 난 걸 아무도 모르면 없는 것과 같다. standarda 는 검사기 자체도 검사한다.
처음 하는 사람에게 규칙집을 다 읽고 기억하라고 할 수 없다. 대신 실수하는 순간에 멈추고, 그 자리에서 이유와 고칠 방법을 알려 준다. 앞 쪽 장면들의 메시지는 모두 "무엇이 문제인지 → 대신 어떻게 하면 되는지"로 되어 있다. 사람이든 AI 든 그 메시지를 읽고 바로 고칠 수 있다.
시작하는 사람에게는 — 규칙을 몰라도 규칙대로 하게 된다.
2026년 9월, 서버 정리 중 검사기들이 쓰던 도구 하나(jq)가 지워졌다. 그 뒤로 모든 검사기가 아무것도 막지 않고 통과했고, 이 상태가 두 달간 이어졌다 — 오류 메시지도 없었다. 발견한 뒤 검사기가 그 도구 없이 돌게 바꾸고, 그 도구를 일부러 가린 채 검사기들을 시험하는 회귀 테스트를 만들었다. 지금 22개 시험이 모두 통과한다.
시작하는 사람에게는 — 보이지 않는 보호가 실제로 켜져 있다는 것을 믿을 수 있다.
검사기가 엉뚱한 것을 막으면 일이 멈춘다. 그래서 오탐이 나오면 그것도 개선 거리로 모아 고친다(예: 문서만 바꾼 커밋의 메시지에 "수정"이 들어가 막히는 경우).
처음 하는 사람이 혼자 해도 되는 이유
모르는 실수는 조심해서 피할 수 없다. 출발점의 기본값이 미리 맞게 해 두고, 검사기가 그 순간에 잡고, 그 검사기가 켜져 있는지까지 확인한다 — 처음 하는 사람이 혼자 일해도 실수가 쌓이지 않는 이유다.
Claude hook 6개는 AI 가 명령을 실행하거나 파일을 쓰기 직전에, git hook 5개는 커밋·올리기·정본이 움직이는 순간에 돈다. 다음 세 쪽에서 하나씩 — 언제 돌고, 무엇을 검사하고, 막으면 무엇을 알려 주고, 왜 생겼는지 — 를 본다.
| 위치 | 내용 |
|---|---|
.claude/hooks/ | Claude hook 6개 + 입력 읽기 도우미 + 검사기 회귀 테스트(test-hooks.sh, 22건) |
.githooks/ | git hook 5개 + 설치 스크립트(install.sh — 작업 폴더 밖에 설치하고 사본을 남김) |
.claude/settings.json | 어느 Claude hook 이 어느 순간에 도는지 연결 |
git commit 을 실행하기 직전docs/issues/ 문서가 들어 있는지git commit 을 실행하기 직전docs/specs/)가 없으면/develop 이 만들어 준다/develop 을 거치지 않은 직접 커밋에서도 스펙이 빠지지 않게 하는 마지막 문git commit 을 실행하기 직전docs/skill_agent_list/)가 같이 바뀌었는지git commit 을 실행하기 직전logger.error)만 남기는지 — 코드 구조를 분석해 정확히 판단logger.exception 으로 바꾸라ssh 명령을 실행하기 직전git 을 쓰거나, 상대 경로(source bin/activate, ../)에 기대는지 — 원격 셸은 늘 홈 폴더에서 시작한다git -C 로 바꾸는 법, 그리고 "같은 오류가 났다면 명령이 실제로 바뀌었는지 확인하라"SKILL.md 를 쓰거나 고치기 직전hook_input.py — Claude Code 가 넘기는 입력을 외부 도구 없이 읽는다test-hooks.sh — 막아야 할 입력은 막고 통과시킬 입력은 통과하는지 22건을 시험한다. 일부러 jq 를 가린 채 돈다docs/issues/ 가 있는지merge 를 쓰는 법| 항목 | 내용 |
|---|---|
| 일시·장소 | 2026-11-14, Brie 개발 서버(brie-box) |
| 프로젝트 | standarda-template 최신판(2026-11-13 #47 기준)으로 만든 새 프로젝트 settle_helper. git 저장소를 만들고 .githooks/install.sh 로 검사기를 설치 — 실제 프로젝트 생성 때와 같다 |
| git hook 장면 | 실제 git 명령을 실행하고 출력을 그대로 옮겼다. "다른 팀 저장소"는 외부에 올리지 않도록 서버 안의 빈 저장소로 만들었다 |
| Claude hook 장면 | AI 가 명령·파일 쓰기를 하려 할 때 Claude Code 가 검사기에 넘기는 것과 같은 형식의 입력을 넣고 응답을 옮겼다. "AI 가 하려던 일" 줄은 그 입력을 사람 말로 적은 것 |
| 결과 | 시도 9가지 모두 실행되지 않았다. 정본 되돌리기 시도 뒤 정본의 커밋은 그대로였다. 검사기 회귀 테스트 22건 통과 |
| 뒷정리 | 시연 프로젝트는 서버 임시 폴더에서만 만들었고 GitHub·DNS 등 바깥에는 아무것도 만들지 않았다 |
개발 서버에서 돌아가는 앱을 동료와 고객이 매일 쓰게 하려면 운영 서버에 올려야 한다. 처음 하는 사람에게 이 일은 서버·DB·도메인·인증서를 모두 알아야 하는 벽이다. standarda 에서는 "배포해 줘" 한 마디로 올리고, 실패하면 스스로 되돌아오며, 여러 사람이 한 서버를 써도 서로의 것을 보지 못한다.
Brie 는 AX 를 대신 해 주지 않는다. 고객이 스스로 하게 만든다.
— 그 다섯 번째 장치.
개발 서버에서 잘 돌아가는 것과 동료·고객이 매일 쓰는 것은 다른 일이다. 운영에 올리는 순간 아래 질문들에 답해야 한다. 대부분 서버 관리자의 경험으로 답하던 것들이다.
보통은 이 질문마다 서버 관리자에게 부탁한다. 그러면 관리자가 병목이 되고, 처음 하는 사람은 "내가 만든 것을 내가 올리는" 경험을 하지 못한다.
서버는 두 대다. 개발 중에 DB 구조를 바꾸거나 서버를 다시 켜도 운영 중인 앱과 데이터에는 아무 영향이 없다. 두 서버 모두 사람마다 자기 계정으로 들어가 자기 앱만 다룬다.
| 개발 서버 (brie-box) | 운영 서버 (brie-prod) | |
|---|---|---|
| 용도 | 만들고 시험한다 | 동료·고객이 매일 쓴다 |
| 주소 | 이름-dev.brie.co.kr | 이름.brie.co.kr |
| 여는 법 | /dev — 주소·인증서·웹서버 연결을 헬퍼 한 줄이 처리 | /release — 처음 한 번 자리를 만들고, 그다음부터 배포 한 줄 |
| DB | 자기 이름의 DB 를 직접 만든다 | 배포 헬퍼가 무작위 비밀번호로 만들고 본인만 읽을 수 있게 보관 |
| 앱 실행 | 개발 서버(작업 중) 또는 본인 계정의 상시 서비스 | 본인 계정으로 도는 서비스, 재부팅되면 자동으로 다시 켜짐 |
| 자원 | 사람마다 메모리 상한 3GB | 앱마다 메모리 상한 512MB, 서버 전체 용량 감시 |
| 접속 | 바깥에는 HTTPS(443)만 열려 있음 | 관리용 접속은 개발 서버에서만 가능 |
사람이 하는 일
개발 서버: "서버 켜 줘" → 확인 한 번. 운영 서버: "배포해 줘" → 상태 확인이 실패했을 때만 판단. 서버 설정 파일을 직접 고치거나 관리자에게 부탁할 일이 없다.
운영 배포는 /release 스킬이 이끌고, 실제 작업은 서버의 배포 헬퍼(brie-prod-deploy)가 한다. 헬퍼는 정해진 순서를 매번 똑같이 밟고, 중간에 문제가 생기면 스스로 직전 상태로 돌아간다.
운영 서버 접속 확인 → 코드 받기·설치 → brie-prod-init(DB·서비스·주소·인증서·등록을 한 번에, 실패하면 만든 것을 스스로 정리) → 운영 설정 파일 자동 생성 → 운영 관리자 계정 생성(비밀번호는 한 번만 보여 줌)
배포·정지·삭제는 모두 운영 서버의 기록(로그)에 누가·언제·무엇을 남긴다. 다음 쪽의 기록이 그것이다.
셀프 배포를 만들며 테스트 계정으로 시험한 운영 서버의 실제 배포 기록이다(가독성을 위해 칸만 맞췄다).
| 기록 | 무엇을 보여 주나 |
|---|---|
FAILED rolled-back | 일부러 깨뜨린 배포(snaptest)가 상태 확인에서 실패하자 직전 버전으로 스스로 돌아가 다시 켜졌다 — 사람이 손대지 않았다 |
바로 다음 줄 OK | 고친 버전은 같은 명령 한 줄로 정상 배포 |
snap=….dump | DB 구조가 바뀌는 배포에서 바꾸기 직전 스냅샷이 자동으로 찍혔다 |
방치 앱 자동 정지 | 오래 안 쓴 앱(idletest)이 자동으로 멈추고 알림이 갔다 → 다시 켜기 → 정리까지 본인이 직접 |
기록의 devtest·sergei 는 팀원 권한을 시험하는 테스트 계정이다 — 관리자가 아니어도 이 모든 것을 본인이 직접 했다는 뜻이다.
여러 사람이 각자 만든 앱이 한 운영 서버에 모인다. 한 앱이 문제를 일으켜도 다른 앱이 함께 쓰러지지 않게, 그리고 잊힌 앱이 자원을 계속 차지하지 않게 했다.
| 장치 | 하는 일 |
|---|---|
| 앱마다 메모리 상한 | 운영 서버의 앱 하나는 512MB, 개발 서버의 사람 한 명은 3GB 까지. 한 앱이 메모리를 다 써도 다른 앱은 영향을 받지 않는다 |
| 서버 용량 감시 | 남은 메모리가 400MB 아래거나 상한 합계가 75% 를 넘으면 경고하고 관리자에게 메일 — 작업은 멈추지 않는다. 서버를 키우는 일은 관리자 담당 |
| 내 앱만 조작 | 배포·재시작·정지·삭제 명령은 등록부에 적힌 본인 앱만 받아 준다 |
| 방치 앱 자동 정리 | 실제 사용(사람의 접속·입력)이 30일 없으면 경고, 44일이면 자동 정지 — 코드·DB·주소는 남겨 두어 한 줄로 다시 켠다. 검색 로봇의 방문은 사용으로 치지 않는다 |
| 개발 서버 야간 정지 | 밤에 아무도 쓰지 않으면 백업 후 서버를 끈다. 밤샘 작업은 "켜 둠" 표시로 막는다 |
| 매일 DB 백업 | 전체 DB 를 7일치 보관하고 서버 바깥(S3)에도 사본을 둔다 |
| 지울 때도 남긴다 | 운영 앱을 지워도 DB 와 코드는 남긴다. DB 삭제는 관리자에게 따로 요청 |
여러 사람이 한 서버에서 일하면 실수로라도 남의 비밀번호·키·데이터를 볼 수 있으면 안 된다. standarda 의 서버는 사람마다 따로 들어가고, 할 수 있는 일을 검증된 명령으로만 제한하고, 비밀 파일은 주인만 읽게 한다.
| 장치 | 하는 일 |
|---|---|
| 사람마다 자기 계정 | 공용 계정을 나눠 쓰지 않는다. 누가 무엇을 했는지 계정 단위로 남는다. 새 사람은 관리자의 명령 한 줄로 개발·운영 계정이 함께 만들어진다 |
| 관리자 권한 대신 검증된 명령 | 팀원은 서버 전체 관리자 권한이 없다. 대신 주소 열기·운영 배포 같은 검증된 헬퍼 몇 개만 쓸 수 있다. 헬퍼는 입력을 검사하고, 남의 것이면 거부하고, 실패하면 원래대로 돌려놓는다. 파일 쓰기·셸 실행·임의 인자를 허용하는 명령은 넣지 않는다는 원칙 |
| 남의 폴더·DB 는 닫힘 | 각자의 홈 폴더는 다른 사람이 들어갈 수 없다. 기존 DB 는 소유자 외 접속을 막았다 |
| 새 파일은 처음부터 나만 | 새로 만드는 파일은 기본으로 다른 사람이 읽을 수 없다(접속·예약 작업 모두에 적용) |
| 웹서버도 필요한 곳만 | 웹서버는 사람들의 그룹에 넣지 않고, 정적 파일 폴더만 읽게 한다 |
| 비밀 파일 매시간 점검 | 설정 파일(.env)·토큰·키·DB 덤프가 주인 외에게 읽히면 매시간 자동으로 바로잡고 기록한다 — 파일 복사·압축처럼 기본 설정을 거치지 않는 경로의 안전망 |
| 문은 최소로 | 개발 서버는 바깥에 HTTPS 만, 운영 서버의 관리 접속은 개발 서버에서만 |
점검에서 실제로 찾아 고친 것 (2026-10)
팀원 권한을 시험하는 테스트 계정으로 확인해 보니, 오래된 파일 중 다른 사람이 읽을 수 있는 것이 있었다. 개발 서버 75만여 건·운영 서버 7만여 건의 권한을 한꺼번에 정리하고, 비밀 파일 96건을 주인만 읽게 바꾼 뒤, 다시 생기지 않도록 위의 "새 파일은 처음부터 나만"과 "매시간 점검"을 넣었다. 모든 장치는 같은 테스트 계정으로 막혀야 할 것이 막히는지 다시 확인했다.
처음 하는 사람을 배포하게 만드는 것은 서버 지식이 아니다. "잘못돼도 되돌릴 수 있다"는 사실이다.
예전에는 배포 중 "DB 구조를 바꿀까요? (y/N)"를 물었다. 이 질문은 아무것도 되돌려 주지 못하고 배포만 멈췄다 — 처음 하는 사람은 무엇을 기준으로 답할지 모른다. 그래서 질문을 없애고, 바꾸기 직전에 스냅샷을 찍게 했다. 스냅샷을 못 찍으면 그때만 멈춘다.
시작하는 사람에게는 — 판단할 수 없는 질문 대신, 잘못돼도 돌아갈 곳이 있다.
주소 열기·DB 만들기·인증서·배포를 관리자에게 부탁하던 일을 각자 검증된 명령으로 직접 한다. 관리자는 서버를 키우거나 정책을 정하는 일에만 남는다. 10월 기록의 배포·정지·재시작은 모두 관리자가 아닌 계정이 직접 했다.
시작하는 사람에게는 — 내가 만든 것을 내가 올리고, 내가 고치고, 내가 정리한다.
자원은 앱마다 나뉘고, 데이터와 비밀은 주인만 본다. 한 사람의 실수가 다른 사람의 앱과 데이터로 번지지 않는다.
시작하는 사람에게는 — 다른 사람에게 피해를 줄까 봐 망설이지 않아도 된다.
사람과 AI 가 서버에서 쓰는 명령은 모두 brie- 로 시작하는 헬퍼다. 원본은 팀 wiki(scripts/devteam/)에 있고 서버에 설치된다 — 문서와 실행 코드가 한곳에 있어 서버를 다시 세워도 같은 결과가 나온다. 다음 세 쪽에서 하나씩 본다.
create-project)--next 로 비어 있는 포트 하나를 고른다(개발 8000~8199, 운영 9000~9499)/dev 가 처음 서버를 켤 때brie-keep) 표시로 밤샘 작업을 지킨다, 켜질 때도 알림/release 첫 배포 때/release 할 때마다--yes) 필수혼자 만들면 시행착오는 그 사람 머릿속에만 남는다. 다음 사람은 같은 곳에서 또 넘어지고, AI 는 대화가 끝나면 잊는다. standarda 는 한 프로젝트에서 배운 것을 기록하고, 모으고, 다음 작업이 시작될 때 자동으로 꺼내 주고, 기본값으로 올린다.
Brie 는 AX 를 대신 해 주지 않는다. 고객이 스스로 하게 만든다.
— 그 여섯 번째 장치.
여러 사람이 각자 업무 자동화를 만들기 시작하면 같은 함정이 프로젝트마다 반복된다. 시행착오는 쌓이는데 지식은 쌓이지 않는다.
개인의 경험은 팀의 자산이 되지 않는다 — 장치가 없으면
처음 하는 사람이 스스로 해내려면, 앞 사람들이 이미 겪은 일을 공부하지 않아도 갖고 시작할 수 있어야 한다. 그러려면 배운 것이 저절로 도는 고리가 필요하다.
오류를 고친 순간부터 그 교훈이 다른 프로젝트의 출발점이 될 때까지, 각 단계를 맡는 장치가 있다. 사람이 기억해서 챙기지 않아도 고리가 돈다.
/develop 이 큰 작업을 시작하면 lesson-finder 가 이번 작업에 맞는 교훈만 골라 온다| 교훈이 가는 곳 | 언제 | 효과 |
|---|---|---|
| 이슈 문서(이 프로젝트) | 모든 비자명한 오류 고침 | 이 프로젝트의 다음 사람·다음 AI 가 읽는다 |
| wiki 교훈 + 색인 | 다른 프로젝트도 겪을 만한 것(공통·분야별) | 다른 프로젝트의 lesson-finder 가 찾아 준다 |
| 규칙집·검사기 | 모든 프로젝트가 반드시 지켜야 할 것, 재발 2회 | 모든 AI 가 처음부터 따르고, 어기면 막힌다 |
| 출발점·공용 부품 | 코드로 해결할 수 있는 것 | 새 프로젝트는 처음부터 갖고, 기존 프로젝트는 버전을 올려 받는다 |
standarda 로 만든 새 프로젝트에서 실제 lesson-finder 에이전트(가장 가벼운 모델)에게 작업 하나를 주고 결과를 받았다. 걸린 시간 103초. 아래는 돌려준 10개를 한 줄씩 옮긴 것이다(원문은 교훈마다 "이번 작업에 적용할 방법"과 원문 경로가 함께 온다).
| # | 분야 | 골라 온 교훈 | 처음 겪은 프로젝트 |
|---|---|---|---|
| 1 | sheets | 업로드 엑셀은 구형 .xls 도 받아야 한다 — openpyxl 단독은 실서비스에서 깨짐 | receipt-tracker |
| 2 | sheets | 엑셀 열기 실패(BadZipFile 등)를 사용자용 오류로 바꿔라 — 파일 앞머리 검사만으론 부족 | cp_revshare |
| 3 | sheets | 사용자가 올리는 엑셀은 열 위치가 아니라 머리글 이름으로 매핑하라 | cp_revshare |
| 4 | general | 건당 비용이 드는 AI 처리 대상은 와일드카드가 아니라 허용 목록으로 | knowclaw |
| 5 | general | 사용자가 다시 만들 수 없는 입력(올린 파일)은 외부 호출 전에 먼저 저장하라 | english_study |
| 6 | general | AI 에 표를 넘길 땐 구조(머리글·행·열)를 살려 보내라 | codepresso_marketing_agent |
| 7 | llm | 여러 행을 한 번에 보내고 되돌릴 때 개수·번호가 어긋나면 묶음 전체를 버려라 — 한 칸씩 밀려 조용히 저장된다 | english_study |
| 8 | llm | 출력이 상한에 닿으면 잘린 것 — 정상 종료로 보고되니 직접 감지하라 | golden |
| 9 | general | AI 답의 JSON 해석 실패는 정상 케이스 — 정해진 방식으로 복구하고 부분 성공을 버리지 마라 | codepresso_marketing_agent |
| 10 | 구글 토큰 경로를 설정에 명시하라 — 안 하면 프로세스마다 다른 계정으로 시트에 쓴다 | popax |
에이전트는 끝에 "보류한 후보 5개"와 "제목 훑기로 좁혔으므로 누락 가능성이 있다"까지 밝혔다. 처음 하는 사람은 이 10가지 중 대부분을 문제가 생긴 뒤에야 알았을 것이다.
render_email_html④는 고리가 끊긴 사례다. 고리도 끊길 수 있다 — 그래서 끊긴 곳을 찾는 일(수집·정리·대조)까지 장치로 만들었다.
처음 하는 사람이 혼자 해낼 수 있는 이유는 그가 특별해서가 아니라, 앞 사람들의 시행착오를 갖고 시작하기 때문이다.
앞의 시연에서 "엑셀을 AI 로 분석하는 기능"을 시작하자 7개 프로젝트의 교훈 10개가 103초 만에 따라왔다. 처음 하는 사람이 혼자 겪으며 알았다면 몇 주가 걸렸을 것들이다. 이 교훈들은 사람에게 읽히려고가 아니라 AI 가 작업에 반영하도록 쓰여 있다.
시작하는 사람에게는 — 53개 프로젝트의 시행착오가 내 첫 작업에 들어온다.
AI 는 대화가 끝나면 잊는다. 그래서 기억을 AI 에게 맡기지 않고 이슈 문서·교훈·규칙집·출발점·공용 부품에 남긴다. 다음 대화의 AI 는 그것부터 읽는다.
시작하는 사람에게는 — 어제의 AI 와 오늘의 AI 가 같은 것을 안다.
교훈을 적어 놓고 색인에 안 올리면 아무도 못 찾는다(이 장을 쓰다 11개를 발견해 백로그에 올렸다). 고친 것이 이전 중에 빠지기도 한다(사례 ④). 그래서 개선 거리를 한곳에 모으고, 매주 금요일 정리하고, 완료 기준에 "기존 프로젝트까지 판단"을 넣었다.
시작하는 사람에게는 — 누군가 겪은 일은 결국 내 출발점까지 온다.
다음 세 쪽에서 고리의 각 단계를 실제 문서 모양으로 본다 — 이슈 문서와 전파 4층, 교훈 파일과 색인, 그리고 출발점·공용 부품으로 올라가 기존 프로젝트까지 가는 길.
비자명한 오류를 고치면 같은 커밋에 docs/issues/번호_제목.md 를 넣는다(빠지면 검사기가 막는다 — 벽 4). 형식은 정해져 있다.
| 층 | 기준 | 교훈이 가는 곳 |
|---|---|---|
| 1 코드 규칙 | 모든 프로젝트가 반드시 지켜야 하는 것 | 규칙집(CLAUDE.md)의 코드 규칙 — 필요하면 검사기로 강제 |
| 2 공통 교훈 | 분야와 상관없이 다른 프로젝트도 겪을 것 | wiki lessons/general/ + 색인 한 줄 |
| 3 분야 교훈 | 엑셀·메일·AI 대화·배포 등 특정 분야에서 겪을 것 | wiki lessons/<분야>/ + 색인 한 줄 |
| 4 이 프로젝트만 | 이 프로젝트의 업무에만 해당 | 이슈 문서에만 남긴다 |
wiki 는 관리자만 고친다. 팀원 프로젝트에서 2·3층이 나오면 이슈 문서에 "wiki 교훈 후보"로 남기고 관리자에게 알린다 — 관리자가 옮긴다.
| 분야 | 교훈 수 | 분야 | 교훈 수 |
|---|---|---|---|
| general(공통) | 350 | llm-chat(AI 대화) | 26 |
| deploy(배포) | 24 | llm(AI 호출) | 13 |
| sheets·google·audio | 5·4·4 | 그 밖 5개 분야 | 10 |
합계 436개 · 출처 프로젝트 53개(가장 많은 곳 popax 45개)
교훈마다 색인(lessons/INDEX.md)에 분야 · 제목 · 적용 조건 · 출처 · 경로 한 줄이 붙는다. lesson-finder 는 가장 가벼운 모델로 돌며 ① 색인만 읽고 ② 공통 + 이번 작업 분야 행 중 적용 조건이 맞는 것만 골라 ③ 걸린 교훈의 본문만 열어 ④ "이번 작업에 적용할 방법"으로 바꿔 돌려준다. 색인은 늘, 본문은 걸린 것만 — 교훈이 늘어도 비용이 폭주하지 않는다.
그래서 색인 한 줄이 빠지면 그 교훈은 영영 안 찾힌다 — 이 장을 쓰며 11개를 찾아 정리 거리로 올렸다.
| 경로 | 무엇을 |
|---|---|
| 프로젝트 → 출발점 | /sync-to-template — 한 프로젝트에서 좋아진 규칙·스킬·검사기·공통 코드를 출발점과 비교해 항목별로 골라 올린다(프로젝트 고유값은 자리표시로) |
| 프로젝트 → 공용 부품 | 검증된 기능을 core 로 — 받아쓰기·슬라이드·결과 검증·메일 HTML 이 이렇게 올라왔다(벽 2) |
출발점 93 · 공용 부품 20 · 서버 헬퍼 1. "무엇이 바뀌었나"뿐 아니라 "왜·무엇을 배웠나"를 남겨 리뷰와 교육 자료의 원천이 된다.
| 경로 | 무엇을 |
|---|---|
| 출발점 → 기존 프로젝트 | /sync-from-template — 네 등급으로 골라 가져온다: 일하는 방식·도구(적극) / 환경 파일(판단) / 규칙집 공통 부분(줄 단위로 합침) / 데이터 구조(절대 덮지 않음) |
| 공용 부품 → 기존 프로젝트 | core 버전 번호만 올린다 — 쓰는 쪽 코드는 그대로(벽 2) |
| 끊긴 곳 잇기 | 개선 거리를 한곳(standarda 백로그)에 모으고, 매주 금요일 정리, 완료 기준 5가지 중 하나가 "기존 프로젝트 반영 판단" |
여기까지 본 출발점·공용 부품·일하는 방식·검사기·서버 헬퍼·교훈은 Brie 의 서버에서만 도는 것이 아니다. 회사마다 다른 값은 값 파일 하나에 모으고, 코드는 하나로 둔다. 그래서 고객 회사가 자기 명의의 AWS·GitHub·도메인 위에 같은 체계를 세우고, 업데이트를 계속 받으며, 혼자 운영한다.
Brie 는 AX 를 대신 해 주지 않는다. 고객이 스스로 하게 만든다.
— 그 일곱 번째 장치.
업체의 서버와 계정 위에서 만든 업무 자동화는 업체와의 관계가 끝나는 날 같이 멈춘다. 그렇다고 우리 서버에 옮겨 세우려면 또 다른 전문가가 필요하다.
"스스로 하게"는 서버까지 우리 것이어야 끝난다
앞의 여섯 장치가 아무리 좋아도 남의 서버에서만 돈다면 고객은 그 업체를 떠날 수 없다. 체계 전체가 고객의 인프라로 옮겨 갈 수 있어야 고객이 스스로 하는 것이다.
회사마다 달라야 하는 것은 전부 박스마다 한 파일(/etc/brie/site.env)에 모았다. 출발점·개발 도구·서버 헬퍼는 모두 이 파일을 읽는다. 다른 회사에 세울 때 바꾸는 것은 이 파일뿐이다.
| 장치 | 하는 일 | 그래서 |
|---|---|---|
① 값 파일 하나site.env | 회사 이름, GitHub 조직, 도메인, 서버 주소, 알림 받을 곳, 밤에 끌지 늘 켤지 — 20개 값. 비밀값은 넣지 않는다 | 코드를 고치지 않고 값만 바꿔 다른 회사에 선다. 값이 비면 추측하지 않고 멈춘다 |
② 공용 자산 받기brie-upstream-mirror | 15분마다 Brie 의 출발점·공용 부품·개발 도구를 고객 조직으로 그대로 가져온다(기본 브랜치와 버전 태그만, 덮어쓰기 없이) | 옮겨 간 뒤에도 개선이 계속 온다. 고객 쪽 값은 값 파일에 있으니 받는 코드를 손볼 필요가 없다 |
③ 같은지 검사brie-parity-check | 박스의 작동 방식(권한·계정·메모리 상한·헬퍼·예약 작업·웹서버·DB)을 회사 값과 무관한 목록으로 뽑는다. 두 박스를 나란히 비교한다 | "돌아간다"가 아니라 "같다"를 확인한다. 다른 줄은 의도한 차이인지 하나씩 본다 |
| ④ 세우는 절차 FDE 온보딩 플레이북 | 고객 명의의 AWS·GitHub·도메인 위에 세우는 순서. 고객이 할 일 6가지와 우리가 할 일을 나누고, 실제로 겪은 함정 16개를 단계마다 붙였다 | 처음 하는 회사도 정해진 순서대로 간다. 같은 함정에 두 번 빠지지 않는다 |
brie · 도메인 brie.co.krbrie-org · 밤에 자동 정지dawel · 도메인 dawelservice.com두 박스의 프로그램은 같다. 위 값만 다르다.
다웰은 자기 AWS 계정에 개발 서버와 운영 서버를 두고 standarda 로 일한다. 2026-08 첫 구축 때는 회사 값을 코드에 직접 바꿔 넣는 방식이었다. 10월에 값 파일이 생기자, Brie 와 같은 체계로 하루 만에 다시 맞췄다.
2026-11-14 다웰 개발 서버 실측. 오늘 기준 그 회사 조직의 출발점·공용 부품·개발 도구는 Brie 의 최신과 같은 버전이다.
맞추기를 끝낸 뒤 Brie 와 다웰의 박스에서 같은 검사(brie-parity-check)를 돌려 나란히 비교했다(2026-10-27). 다른 줄은 하나씩 이유를 확인했다.
| 비교 | 검사 항목 | 완전히 같은 줄 | 다른 줄은 무엇이었나 |
|---|---|---|---|
| 개발 서버 ↔ 개발 서버 | 84 | 56 | 밤 정지(Brie) vs 늘 켬(다웰)에 딸린 도구·예약 작업, 받아 오기 도구(다웰에만), 팀원 이름, 메모리 상한, 앱 수 |
| 운영 서버 ↔ 운영 서버 | 84 | 72 | 팀원, 알림 경로, 등록된 서비스 수 |
다른 줄은 전부 "회사 사정"이었다
서버 헬퍼 프로그램은 두 박스에서 지문(해시)까지 같았다. 남은 차이는 값 파일로 고른 운영 방식(밤에 끌지 늘 켤지)과 그 회사 사람·서비스 수뿐이다. 빠진 장치가 없다는 것을 눈대중이 아니라 검사로 확인한 것이다.
이 체계 자체도 2026-09 다른 회사의 인프라에서 Brie 의 AWS·도메인·GitHub 로 통째로 옮겨 왔다. 코드와 데이터는 다 왔는데, 옮긴 직후 DB 백업이 0개였다. 백업·자동 서버 이미지·권한 역할 같은 클라우드 쪽 자동화는 복사로 따라오지 않는다. 문서에는 백업 절차가 있어 "있다"고 착각하기 쉬웠다.
그래서 — 옮긴 뒤 "다시 만들어야 하는 것" 체크리스트와 같은지 검사가 절차에 들어갔다.
고객이 스스로 하려면 도구뿐 아니라 그 도구가 도는 자리까지 고객의 것이어야 한다.
AWS 계정·GitHub 조직·도메인·결제는 처음부터 고객이 만들고, 구축하는 쪽을 초대한다. 구축이 끝나면 초대받은 쪽이 조직에서 빠지기만 하면 된다 — 옮겨 줄 것이 없다.
고객에게는 — 업체와의 관계가 끝나도 서버·코드·데이터는 그대로 우리 것이다.
값과 코드를 나눴기 때문에, Brie 가 출발점과 공용 부품을 고치면 15분 안에 고객 조직에 들어온다. 앞 장의 교훈 고리(벽 6)가 고객 회사까지 이어진다.
고객에게는 — 혼자 운영해도 다른 회사들의 시행착오가 계속 들어온다.
비용을 아끼려 밤에 서버를 끌지, 교육이 많아 늘 켜 둘지, 알림을 어디로 받을지 — 코드를 고치지 않고 값 파일에서 고른다. 고객이 직접 바꿔도 다른 곳이 깨지지 않는다.
고객에게는 — 우리 회사에 맞게 바꾸는 일도 전문가 없이 할 수 있다.
다음 세 쪽에서 값 파일의 20개 값과 그것을 읽는 곳, 공용 자산을 받아 오는 방식과 같은지 검사, 그리고 고객 인프라 위에 세우는 순서와 실제로 겪은 함정을 본다.
| 값 | 뜻 |
|---|---|
SITE_ID · BOX_ROLE | 회사 짧은 이름 · 개발/운영 서버 구분 |
ALERT_TAG · SNS_TOPIC_ARN | 알림 메일 제목 표시 · 알림 보낼 곳(비면 다른 경로로) |
RUN_MODE | 밤에 자동 정지 / 늘 켬 |
GITHUB_ORG · UPSTREAM_GITHUB_ORG | 이 회사의 GitHub 조직 · 공용 자산을 받아 올 상위 조직(비면 받아 오지 않음) |
ADMIN_GITHUB_USER · ADMIN_LINUX_USER | 관리자 GitHub 계정 · 서버 관리자 계정 |
DEV_DOMAIN · PROD_DOMAIN · DEV_CERT_NAME | 개발 주소 <앱>-dev.도메인 · 운영 주소 <앱>.도메인 · 개발 인증서 이름 |
ROUTE53_ZONE_ID · DNS_AWS_PROFILE | 도메인을 관리하는 곳 · 그곳을 고칠 때 쓰는 AWS 프로필 이름 |
DEV_IP · PROD_IP · PROD_ADMIN_SSH_KEY | 서버 주소 · 개발 서버에서 운영 서버로 접속하는 키의 위치 |
AWS_REGION · AWS_ACCOUNT_ID · DB_BACKUP_S3_BUCKET | AWS 지역 · 계정 번호 · DB 백업을 서버 밖에 보관할 저장소 |
비밀값(키·비밀번호)은 넣지 않는다 — 누구나 알아도 되는 공개 정보만. 비밀은 관리자만 읽는 파일과 서버 권한 역할에 따로 둔다.
| 읽는 곳 | 어떻게 |
|---|---|
| 출발점(새 프로젝트 만들기) | GitHub 조직을 값 파일에서 읽어 공용 부품 주소와 새 저장소 위치를 채운다. 비어 있으면 만들기를 멈춘다 |
| 개발 도구 | 프로젝트 만들기·지우기·가져오기가 조직·도메인을 값 파일에서 읽는다. 없으면 "값 파일 없음"으로 멈춘다 |
| 서버 헬퍼 | 개발 주소 열기·운영 배포·알림·백업이 첫 줄에서 값 파일을 읽고 필요한 값이 비었는지 검사한다 — 기본값으로 조용히 넘어가지 않는다 |
brie-upstream-mirror고객 서버의 관리자 예약 작업으로 15분마다 돈다. 상위 조직(Brie)의 출발점·공용 부품·개발 도구·인프라 안내서에서 기본 브랜치와 버전 태그만 고객 조직으로 옮긴다. 앞으로만 나아가고 덮어쓰지 않는다 — 고객 쪽이 갈라져 있으면 멈추고 알림 메일 한 통, 복구되면 한 통.
출발점 안의 모든 회사 값은 값 파일에서 오므로, 받아 온 코드를 고객 쪽에서 고칠 일이 없다 — 그래서 "그대로 옮기기"만으로 충분하다.
brie-parity-check박스의 작동 방식을 항목=값 목록으로 뽑는다. 회사 이름·주소 같은 값은 빼고 "어떻게 도는가"만 남기므로, 같은 역할의 두 박스는 목록이 같아야 한다.
| 검사 묶음 | 무엇을 보나 |
|---|---|
| 값 파일 | 20개 값이 다 있는가(값 자체는 비교하지 않음) |
| 서버 설정 · 계정 · 권한 | 새 파일 기본 권한, 팀원 그룹, 허용된 관리 명령 목록, 사람마다 메모리 상한 |
| 서버 헬퍼 | 설치된 헬퍼 프로그램과 지문(해시) — 같은 버전인가 |
| 예약 작업 · 웹서버 · DB | 백업·권한 점검·정리 작업, 웹서버 종류와 주소 수, DB 버전 |
| 운영 서버 | 배포 도구·알림 경로·등록된 서비스 |
| 순서 | 고객이 하는 것 | 세우는 쪽이 하는 것 |
|---|---|---|
| 1 | 회사 영문 이름(조직·도메인의 뿌리) 철자 확정 | 후보 이름이 GitHub·도메인에서 비어 있는지 미리 조회 |
| 2 | AWS 계정 만들고 관리 권한 위임, 팀원 GitHub 계정 이름, AI 좌석·키 — 한 번에 회신 | 안내서 묶음을 회사 값으로 채워 전달 |
| 3 | 확정한 이름으로 GitHub 조직을 만들고 초대 | 팀·저장소·팀원 초대 세팅 |
| 4 | 팀원 각자 초대 수락 + 2단계 인증 | 서버 생성 → 계정·권한·DB → 값 파일 설치 → 공용 자산 받아 오기 |
| 5 | 도메인 구매 + 알려 준 네임서버 4개 입력 | 도메인 관리 영역 생성, 개발 주소용 와일드카드 연결 |
| 6 | 각자 로그인해서 첫 프로젝트 만들기 | 검사 통과 확인 → 인수인계(조직에서 빠지기, 권한 축소) |
| 겪은 일 | 지금 절차 |
|---|---|
| 회사 이름 철자 미확정(다웰) | 조직·도메인·서버·문서를 전부 다시 만들었다 → 철자부터 확정하고 시작 |
| "비어 있음" 확인했는데 생성 때 이미 선점 | 확인과 생성 사이에 틈을 두지 않는다 — 확정 즉시 조직 생성 |
| 새 AWS 계정은 무료 플랜이라 서버가 안 뜸 | 유료 전환을 첫 단계로 |
| 새 계정의 서버 크기 한도(5 vCPU) | 큰 서버가 필요하면 첫날 한도 증설 요청, 작은 서버로 먼저 시작 |
| 새 계정은 AWS 에서 도메인 등록이 막힘 | 국내 등록처에서 고객 명의로 사고 네임서버만 연결 |
| 교육생 여럿이 AI 를 동시에 돌리자 메모리 부족으로 서버가 멈춤 | 교육용은 큰 서버 + 사람마다 메모리 상한 |
| Windows 담당자의 접속 키 권한 오류 | Windows 를 먼저, 창 여는 법부터 안내 |
7개의 장치는 따로 도는 것이 아니라 한 흐름으로 이어진다. 업무 앱 하나가 생겨서 동료가 매일 쓰기까지, 사람이 하는 일과 시스템이 하는 일을 나란히 놓았다.
이 과정에서 겪은 일은 다음 사람에게 간다
오류를 고치면 이슈 문서와 교훈이 남고(벽 6), 같은 일을 두 번 겪으면 출발점·부품·검사기로 올라가 다음 프로젝트의 기본값이 된다. 이 모든 것은 고객 회사의 서버·계정 위에서도 같은 모양으로 돈다(벽 7).
아래 숫자는 이 자료를 쓰며 실제 서버·저장소에서 다시 센 것이다(2026-11 기준). 자세한 근거는 각 장에 있다.
| 무엇 | 숫자 | 뜻 |
|---|---|---|
| 교훈 | 436개 · 53개 프로젝트 | 각 프로젝트가 겪은 일을 일반화해 남긴 것. 작업 시작 때 관련된 것만 골라 온다 (벽 6) |
| 기본값으로 올라간 변경 | 114건 | 출발점·공용 부품·서버 도구가 바뀐 기록. 건마다 "무엇을 배웠나"가 붙어 있다 (벽 6) |
| 개발 요청 흐름 | 7단계 · 승인 1번 | 모든 "만들어 줘·고쳐 줘"가 같은 순서로 돈다 (벽 3) |
| 검사기 | 11개 | 실제 차단 장면 9건을 이 자료에 그대로 실었다 (벽 4) |
| 배포 안전장치 | 스냅샷 · 상태 확인 · 자동 되돌리기 | 실제 운영 로그로 실패 → 자동 되돌리기를 확인했다 (벽 5) |
| 다른 회사 인프라 | 2박스 · 값 20개 | 개발·운영 서버를 하루 만에 같은 체계로 맞췄고, 15분마다 최신을 받는다 (벽 7) |
standarda 는 한 번에 설계된 것이 아니다. 실제 프로젝트에서 넘어진 자리마다 장치를 하나씩 세웠고, 그 기록이 이 자료의 근거다.
전문가의 머릿속에 있던 것을 시스템에 옮겨 담았기 때문에, 처음 하는 사람이 혼자 만들고, 올리고, 운영할 수 있다. 그리고 그 사람이 겪은 일은 다시 시스템에 담겨 다음 사람의 출발점이 된다.
Brie 는 AX 를 대신 해 주지 않는다.
고객이 스스로 하게 만든다.