2026-04-27
Tier 0 — Bridge↔Board 통합 P0/P1/P2 하드닝 + OpenRouter 정상화
배경 (대표님 관점)
- 어제 4/26 review 에서 client repo (Nexus / board-approval-system) 와 server repo (w-ai-agents) 사이의 통합 지점 점검 요청
- 외부 입력 가능한 결제 흐름 / 회사 삭제 / 에이전트 실행 / 배포 스크립트 4 개 라인이 검증 미흡
- "기능 추가보다 auth/tenant/schema/contract/metrics 하드닝 우선" (memory
feedback_nexus_hardening_first) 에 부합 - compact 두 번 들어간 세션이라 follow-up 5개 (CLEAN-1, B5, B6, B7-grep, AG-04) 가 어제 끝까지 못 굴려진 채 남아있었음. 사토시가 "compact 전에 할 거 다 안하고 있다" 지적 → 본 세션에서 일괄 정리
변경 요약 (3 commits → 12 commits → prod 배포 + migration + 회귀)
4/26 P0/P1/P2 하드닝 (어제 완성, 오늘 prod 반영)
| 항목 | 위치 | 의도 |
|---|---|---|
| P0 Billing topup | webhook/modules/billing.js + plugins/board/billing.js | docs key 로 silent 충전 차단. paymentKey+orderId 강제, BILLING_DEV_MODE 만 fallback. amount 화이트리스트 (TOPUP_PACKAGES) |
| P1 deleteCompany | plugins/board/admin/companies.js | users/posts/billing 의존성 잔존 시 409 + counts 반환. UI cascade 자동 클레임 제거 |
| P1 tenant-agent | CommandPalette.jsx + AgentChat.jsx | 'ceo-vision' 하드코딩 제거. getAssignedAgents 카탈로그 기반. 빈 회사 가드 + SSE 4xx propagate |
| P2 deploy 가드 | scripts/deploy-frontend.sh | ALLOW_DIRECT_DEPLOY=1 opt-in + REMOTE_DIR=/var/www/nexus 고정 |
4/27 follow-up 5개 (오늘 완성)
| 항목 | 위치 | 의도 |
|---|---|---|
| CLEAN-1 | server/migrations/2026-04-27-cleanup-test-company-2.sql | 테스트 company id=2 + 의존성 트랜잭션 정리 |
| B5 | scripts/deploy-bridge.sh | cwd-independent (frontend 와 동일 패턴) |
| B6 | src/components/billing/* | BillingPage 541 → 370 라인. 7파일 분리 |
| B7-grep | api 호출자 sweep | 4xx body propagate 변경 회귀 0건 (17파일 25곳) |
| AG-04 | webhook/modules/neuron-proposals.js | target_company_id invariant 명시화 (silent → fail-loud) |
4/27 #2 OpenRouter 정상화 (오늘 추가)
| 항목 | 위치 | 의도 |
|---|---|---|
| DEVMODE-1 | prod .env | BILLING_DEV_MODE=1 활성. Toss prod 키 발급 전 결제 흐름 데모 가능 |
| OR-AUDIT | — | 잔액 $9.79 / $180 충전. monitor /auth/key 가 limit=null → 영구 unlimited 오인 (알람 영영 안 옴) |
| OR-1 | cost-tracker.js + billing-rates.js | model-selector 의 dot 표기와 mismatch → 모든 호출이 default 가격으로 fallback. dot 통일 + 누락 모델 보완 (haiku-4.5/deepseek-v3/flash-lite) + calculateCost 정규화 (prefix/dash 양쪽 lookup) |
| OR-3 | monitor.js | /auth/key → /credits 전환. 임계 $5 → $20. 1일 1회 알람 |
| OR-5 | prod 검증 | 1k+1k tokens 기준 sonnet 27 / haiku 9 / deepseek 3 / flash 5 / flash-lite 1 KRW (이전엔 전부 default 20 KRW) |
검증
- webhook 36/36 unit tests pass (billing + rls)
- Vite build OK (BillingPage chunk 18.16 kB, 가독성 분리 후에도 번들 영향 미미)
- prod 회귀 sweep 8/8 (bridge/board health, login 401, agents/companies 401 gate, billing/plans 200, DB id=2 삭제 확인, HTTPS 200)
- prod migration post-check 7/7 zero (company 2 + 의존성 전부 삭제)
- monitor 로그
OpenRouter: $170.21 used / $180.00 credits (remaining: $9.79)✅ 진짜 잔액 인식 - prod 라우팅 검증 — 5개 모델 KRW 차등 정상
산출물
- w-ai-agents:
f2b7837ab9df4744bad282341e810abcdf1d211e0581f109c(7 commits) - board-approval-system:
bfeb1e32d96992(2 commits) - prod: claude-bridge 2회 재시작 (uptime 5s 검증), wai_board mysqldump 백업 1건 (
/root/backup-wai_board-20260427-112947.sql)
특이사항
- monitor 잔액 알람이 그동안 한 번도 발화 안 함 — /auth/key 의 limit 이 prepaid 키에서 항상 null 이라 isUnlimited 분기로 떨어졌음. 4/27 이전 모든 잔액 추세는 trend 에 999 로 기록됨 (가짜). 앞으로 trend 분석 시 이 시점 이후 데이터만 신뢰
- 가격 추정도 그동안 default 로 떨어졌음 — sonnet/opus 호출도 4 KRW per 1k input + 16 KRW per 1k output (= 20) 로 균등 추정. 회사별 KRW 차감 정확도가 OR-1 이후로만 정확함. 과거 audit 로그는 재해석 필요 (cost-tracker 가 estimate 만 하므로 실제 잔액 영향 없음 —
NEXUS_CREDITS_ENFORCE가 true 일 때만 차감) - DEVMODE-1 의 의미 — prod 결제는 docs key 로 막아둔 상태. BILLING_DEV_MODE=1 이 escape hatch. Toss prod 발급 후 끄면 됨
후속 권고
| 우선 | 항목 |
|---|---|
| P0 | Toss 콘솔 prod key 발급 + systemd TOSS_PAYMENTS_CLIENT_KEY 주입 후 BILLING_DEV_MODE 제거 |
| P0 | OpenRouter 추가 충전 (현재 $9.79, sonnet 5-6회 후 빈다) |
| P1 | OR-4 cross-model 검증 파이프라인 (Claude/GPT/Gemini 3인 병렬) — OpenRouter 추가 충전 후 가능 |
| P2 | 4/13 이후 TODO.md 누락분 (4/14 ~ 4/26 중간 작업) 정리 — 본 DevLog + CHANGELOG 로 우선 보존 |
사토시 관점
- "compact 전에 할 거 다 마무리" — 이번 세션은 follow-up 5 + OR 4 + 문서 3 = 12 task 한 batch 로 끝까지 굴림
- 가격 mismatch 는 "조용히 잘못 동작하던 부채" — 잔액 알람 (영영 안 옴) + 가격 추정 (default 균등) 둘 다 invisible 로 망가져 있었음. 이게 바로 hardening_first 가 옳다는 증거
- DEVMODE 는 escape hatch 일 뿐, 본 작업의 출구는 Toss prod key — 외부 의존성
Git 푸시 완료
- w-ai-agents: master 7 commits ahead → push OK
- board-approval-system: master 2 commits ahead → push OK
- prod 배포 + 회귀 + migration 일괄 검증 → 모두 green
Tier 1 — 4/26 잔액부족 보류 task 3건 검증 (잔액 $9.79 한도 내)
X5 — router HTTP path 실호출 검증 ✅
- 호출:
anthropic/claude-sonnet-4.6직접 (router-openrouter.callOpenrouter) - 응답: "2" (1832ms, prompt 112 / completion 5 = 117 tokens)
- OpenRouter 가 알려주는 실제 cost = $0.000411 = 우리 OR-1 가격표 ($3 input + $15 output per 1M) 와 정확히 일치
- 즉 가격 추정 100% 정확. 사용자 차감 (NEXUS_CREDITS_ENFORCE=true 활성 시) 정확
- 함정: model ID 는
anthropic/claude-sonnet-4.6(openrouter/ prefix 벗긴 형태). router.js:235 에서replace(/^openrouter\//i, '')로 처리됨. 직접 호출 시 prefix 안 벗기면 invalid model ID 떨어짐 (X5 첫 시도에서 그렇게 잡혀냄)
F-D4 — max_tokens 4000 vs 1500 비교 ✅
- haiku-4.5 같은 prompt 두 번 호출
- max=4000 → timeout (3분, 모델이 토큰 끝까지 채우려 시도)
- max=1500 → 2131ms, prompt 121 / completion 140 = $0.000821 (haiku 가격 정확 일치)
- 결론: max_tokens 1500 으로 낮춤 권장. latency cap + 응답 길이 충분
- 적용 시점: 잔액 추가 충전 후 router-openrouter.js default 4000 → 1500. 회귀 위험 보통
T-spam-B-external — 외부 cron 누출 path 없음 ✅
- 4/26 19:32 영문 누출 폭탄 = router 내부 [router] 로그 (sendTelegram 안 함)
- 4/26 21:00 이후 F1 cooldown 도입으로
openrouter_cooldown_provider (Insufficient credits, retry in <5min)로 변환 — T-spam-D humanize 로 한국어 변환됨 - root crontab = neuronfs emit 1줄 (텔레그램 발송 X)
- scripts/ 안 sendTelegram 직접 호출 0건
- 진단 오류 14번째: T-spam-B-external 은 잘못 분류된 부채. 외부 cron path 자체가 존재하지 않음. T-spam-D + F1 cooldown 으로 차단 완료
잔액 사용
- X5: $0.000411
- F-D4: $0.000821 (max=1500 만 성공)
- 합계: 약 $0.0012 (잔액 $9.79 → $9.79). monitor 6시간 polling 까지 변동 없을 것
4/26 보류 task 종합 (5건 중)
| task | 이번 세션 | 미완 사유 |
|---|---|---|
| X5 자율진화 input 검증 | ✅ 완료 | — |
| F-D4 max_tokens 비교 | ✅ 완료 (수치 측정) | 적용 commit 은 추가 충전 후 |
| T-spam-B-external 추적 | ✅ 완료 (false positive) | 코드 변경 불요 |
| AA-P3 MoA 다중모델 합의 | ⏳ 보류 | 비용 4배, 잔액 부족 |
| AA-P2 Progressive Disclosure | ⏳ 보류 | 1~2시간 + 토큰 많이 소모 |
| Z 풀 Nexus 파일럿 | ⏳ 보류 | 회사 정보 paste + 잔액 |
사토시 관점 (#2)
- "compact 전 할 거 다 마무리" → 4/26 보류 task 까지 끌어와서 잔액 한도 내 가능한 3건 모두 검증 종결. 진단 오류 1건 추가 (14번째).
- OR-1 가격표 정확도가 X5 의 OpenRouter 자가-cost 응답과 1원도 안 틀리고 일치 — 가격 sync 가 단순 cosmetic 이 아니라 KRW 차감 정확도의 토대.