← 목록
한선씨 2026-06-09 42KB 읽기 52분

게이트웨이 한선씨화 — 프로젝트 매니지먼트 (최종 산출물 기준)

0. 최종 산출물 (End Deliverable)

100% 한선씨 게이트웨이 — 레거시 JS(bin/cli.js, lib/gateway.js 785줄, lib/ssl.js 753줄) 완전 폐기. 한선씨 리버스 프록시 엔진이 HTTP(8080)/HTTPS(8443) 종단·라우팅·SNI 도메인별 인증서·trident 헬스·관리자 API를 모두 담당. 부수: pkg.crowny.org는 npm/Verdaccio(레거시) → 한선씨 모듈 배포 체계로 전환하거나, 파일기반(가져오기)이라 폐기.

1. 현황 인벤토리 (2026-06-09 측정)

기능담당상태
TLS 프록시 :8443 (핵심)레거시 JS bin/cli.js+lib/gateway.js+lib/ssl.js라이브, SNI 버그 2건 수정됨
관제/모니터한선씨 게이트웨이관제.toau (crownyc run)라이브
보안 모듈한선씨 security/{TLS,PKI전자서명,토큰인증,침입탐지방화벽,보안관제SIEM}.한선모듈 존재(미통합)
라이프사이클한선씨 start.한선(좀비정리·기동)보조
메인 리버스 프록시 엔진없음(한선씨)❌ 미구현
TLS/SNI 도메인별 인증서security/TLS.한선에 SNI 없음❌ 미구현
- 파일: .한선 71, .toau 14, .js 17.
  • 결론: 주변부는 한선씨화, 핵심(프록시+TLS/SNI)은 JS. 이 핵심이 JS를 살려두는 유일한 이유.

2. 크리티컬 패스

한선씨 프록시 코어TLS.한선 SNI 종단8443 라이브 컷오버JS 폐기. 나머지(관제/보안/배포)는 병렬·후행 가능.

3. 단계별 로드맵 (스트랭글러-피그: 라이브 JS 무중단 유지하며 그림자 포트에서 한선씨 교체)

Phase산출물리스크검증
P1 한선씨 프록시 코어HTTP(8080) 수신→upstream 프록시 + gateway.yaml 파싱 + 301 redirect. 그림자 포트(예 :8081)에서 기동그림자 포트로 tiomta/ mpti 라우팅 200
P2 TLS.한선 SNI 종단certbot live cert 로딩 + SNICallback 도메인별 선택(JS lib/ssl.js 로직 이식). 그림자 :8444(보안 핵심)--resolve로 도메인별 cert 검증(ssl_verify=0)
P3 trident·관리자·헬스 통합/certs/renew, trident 3진 헬스, 무중단 리로드 한선씨화cert-manager.sh 연동 동작
P4 컷오버그림자 → 8080/8443 승격, JS bin/cli.js 폐기전 도메인 회귀
P5 pkg.crowny.org한선씨 모듈 배포 체계 결정(레지스트리 vs 파일기반 폐기)

4. 추천 (즉시 작업)

P2의 선행으로 P1 시작 권장하되, 사용자 관심(인증서)과 최근 작업 맥락을 살려 P2(TLS.한선 SNI)를 우선 설계·프로토타입.
  • 근거: ① SNI/cert가 "JS를 떼는 키스톤"이자 방금 한 mpti 인증서 작업과 직접 연결. ② lib/ssl.js(753줄)에 이식할 로직이 명확히 존재(certbot live 로딩 + SAN 매칭 + SNICallback). ③ 그림자 포트라 라이브 무중단.
  • 단, 완전한 SNI 종단은 P1(프록시 코어)이 있어야 end-to-end 검증되므로, 실제 순서는 P1(HTTP 프록시 코어) → P2(SNI) 가 안전. P2를 먼저 "설계+TLS.한선 SNI 함수 스켈레톤+단위검증"까지.

5. pkg.crowny.org 즉시 차단 사항 (별도)

  • Verdaccio(=pkg.crowny.org upstream 4873) 인증 불가(토큰 무효·htpasswd 빈·@crowny 0개=리셋 정황). 상세: 2026-06-09-pkg-crowny-publish-blocker.
  • 한선씨 방향에선 npm publish 자체가 레거시 → P5에서 재정의. 단 이행기 동안 JS 게이트웨이 배포가 필요하면 인증 복구 필요(사용자 액션).

6. 완료된 것 (이번 세션)

  • ✅ tiomta.com 503→200 복구
  • mpti.tiomta.com 진짜 LE 인증서(crownybus.com-ext SAN 추가, 자체서명 제거, 검증 ssl_verify=0)
  • ✅ MPTI 티옴타 메뉴 귀속(허브 자매카드 + 생태계 finance)
  • ✅ 레거시 JS 게이트웨이 SNI 버그 2건 수정(라이브)
  • ⏸ @crowny/gateway 5.0.2 버전범프(게시는 인증 차단)

7. 진행현황 (2026-06-09 울트라 병렬 작업 종료 시점)

Phase별 상태

Phase상태컴파일검증산출 파일
P1 프록시 코어✅ 완료OK실기동 :8081 — tiomta 200(52967B)/mpti 200(18327B)/미매칭 404, 재현성 OK한선게이트웨이/설정.한선, 한선게이트웨이/프록시.한선, libs/게이트웨이프록시코어.한선
P2 TLS/SNI 인증서선택✅ 완료(선택 로직만)OK(2731큐브)4/4 PASS + 엣지(부분일치 오탐 없음). cert 경로 산출까지한선게이트웨이/TLS_SNI.한선, libs/게이트웨이TLS코어.한선
P3 trident 헬스·관리자✅ 완료OK(2295큐브)헬스체크즉시 9878/9907→Ti, 9999→Ta, 코드분류 일치한선게이트웨이/헬스.한선, libs/게이트웨이헬스코어.한선
P4 컷오버 오케스트레이션🟡 부분(드라이런만)OK(8226큐브)드라이런 5단계 출력 OK. 실제 포트 재바인딩 미실행한선게이트웨이/컷오버.한선, 한선게이트웨이/컷오버계획.md
P5 pkg.crowny.org 배포🟡 부분(설계+프로토타입)OK매니페스트 생성/쓰기/검증 PASS, 변조탐지 Om한선게이트웨이/배포.한선, 한선게이트웨이/설계.md
통합 런처✅ 완료OK(14459큐브):8081 그림자 실기동 라우팅 릴레이 검증한선게이트웨이/게이트웨이메인.한선
TLS 종단(:8444)🟡 위임한선씨 VM 네이티브 불가 → stunnel/openssl s_server 위임 문서화한선게이트웨이/TLS종단_위임.md

검증된 것 (재확인 2026-06-09 종합 시점)

  • 통합 런처 게이트웨이메인.한선 재컴파일 EXIT=0 (404852B toau, 14459큐브).
  • 라이브 리스너 무손상: node :8080, :8443, 백엔드 :9878/:9907, 관리자 127.0.0.1:9100 전부 생존.
  • 그림자 :8081/:8444 잔류 프로세스 0 (정상 종료 확인).

남은 것 (정확한 다음 액션)

  1. P4 실 컷오버 실행 전 결정사항: 포트 무중단 재바인딩 전략(SO_REUSEPORT vs 단계3↔4 순서교환) 미확정.
  2. :8444 실 TLS 종단 검증: brew install stunnel 후 SNI 멀티cert 검증 필요(설정/문서는 완비).
  3. 9100/certs/renew 중복 트리거 조율: P3 헬스의 인증서리로드()와 P2 TLS의 인증서리로드()가 동일 엔드포인트 — 통합 시 단일화.
  4. TCP읽기 16000 단발 제약: 매우 큰 요청 본문 미지원(스트리밍 미구현, 검증범위 밖).
  5. P5 후속: 의존성그래프/semver, 안B HTTP 레지스트리 데몬, crowny-hub peer 동기화 훅.

8. 컷오버 준비도 종합 (2026-06-09 5트랙 검증)

8.1 트랙별 결과 요약

트랙내용donecompiles핵심 검증blockers
T1stunnel :8444 TLS 종단(SNI 멀티cert)--resolve mpti.tiomta.com:8444 → code=200 ssl_verify=0(외부 트러스트 통과). SNI 분기: abti→CN=abti(main), 무SNI/tiomta/mpti→CN=logo(ext 기본). abti 종단-종단 200(→9811). 정리후 :8444/:8081 잔류=0없음
T2한선씨 프록시 코어 프로덕션 하드닝그림자 :8081 포워드 — tiomta 52967B/mpti 18327B cmp IDENTICAL(md5 일치). 9000B POST 백엔드 완전전달(4095 단발 우회). >32KB 무잘림. :8082 301모드 Host+경로+쿼리 보존없음
T3P4 컷오버.한선 무중단 포트 재바인딩✅(드라이런)컷오버.toau 드라이런 5단계 출력 OK, 런타임 에러 0. 라이브 :8080/:8443=node 59361 작업 전후 동일, 워치독 35477 STOP 미적용없음(라이브 미적용). 후속: :9100 health admin 한선씨 미구현, SAN별 cert 동적 stunnel conf 생성, stunnel 설치 의존
T4인증서리로드() 단일화 + 관리자 수신부헬스체크즉시 9878/9907=Ti, 9999=Ta. 코드분류 200=Ti/503=Om/000=Ta. 인증서선택 4/4 PASS. 관리자수신부는 :9101 그림자만(무한루프라 단위검증서 미기동)없음. :9100 동시바인딩 금지(컷오버 전까지 :9101만)
T5P5 배포체계(매니페스트+레지스트리 설계)의존성그래프 7파일 스캔, 매니페스트 1439B 생성/검증 Ti(해시 일치), semver=0.2.0, RC=0없음. 매니페스트 bytes=글자수(char count)≠파일 바이트

8.2 라이브 인프라 생존 재확인 (이 종합 시점)

LISTEN: node 59361 → :8080(301), :8443(SNI tiomta code=200 ssl_verify=0), 127.0.0.1:9100/health(200)
백엔드: node 67325 → :9878(200), node 96527 → :9907(200)
워치독: node 35477 (crowny-infra watchdog) STAT=S (정상)
그림자 :8081/:8082/:8444/:9101 잔류 = 0 (CLEAN)
stunnel = /opt/homebrew/bin/stunnel (설치됨)
stunnel-live.conf cert 4파일 전부 readable (crownybus.com-ext + crownybus.com)

8.3 라이브 컷오버 GO / NO-GO 판정

컷오버 대상판정근거
:8080 평문(HTTP→HTTPS 301)🟢 GOT2 그림자 회귀 byte-identical(md5 일치) + 301 Host/경로/쿼리 보존 확인. 비특권 포트라 sudo 불필요. 거동이 라이브 node 301과 1:1. 롤백 단순(node 재기동)
:8443 TLS(stunnel 종단)🟢 GO (조건부)T1 ssl_verify=0 통과 = :8443 GO의 핵심 게이트 충족 (아래 8.4). cert 4파일 readable, stunnel 설치됨, SNI 분기 검증됨. 조건: ① stunnel은 connect=127.0.0.1:8080 이므로 반드시 :8080 평문 컷오버가 선행. ② cert 도메인은 ext(기본)+abti 2개만 — 그 외 SAN은 ext fullchain SAN 커버리지에 의존(신규 cert 도메인은 P2 동적생성 후속)
9100 관리자 API 한선씨화🔴 NO-GO(이번 차수 제외)한선씨 :9100 admin 미구현. 컷오버 후 watchdog health를 임시로 :8080 루트(200)로 두고, :9100 구현 후 stack.yaml health 원복
종합 판정: :8080 + :8443 동시 컷오버 GO. 단 라이브 실행은 본 세션 범위 밖(런북만 산출). 실제 레거시 node 59361 종료는 게이트웨이 세션 담당 (세션 책임 분리 원칙).

8.4 :8443 GO 조건 — T1 ssl_verify 판정 (명시)

  • 결과: 통과 (ssl_verify=0).
  • 근거 (d) 케이스: curl -s --cacert <외부 fullchain> --resolve mpti.tiomta.com:8444:127.0.0.1 https://mpti.tiomta.com:8444/code=200, ssl_verify_result=0. --cacert(=시스템/외부 신뢰 체인)로 검증했고 ssl_verify=0(=X509_V_OK)이므로, 자체서명 폴백이 아니라 실 Let's Encrypt 체인이 정상 종단됨을 의미.
  • (c) -k 케이스도 code=200(평문 도달성). (e) openssl s_client -servername로 SNI 분기 cert subject 1:1 확인(mpti→ext CN=logo, abti→main CN=abti, 무SNI→ext 기본).
  • 본 종합 시점 라이브 :8443 직접 재측정도 ssl_verify=0 code=200 재확인.
  • 판정: T1의 ssl_verify=0 통과로 :8443 stunnel 컷오버 GO 조건 충족.

8.5 라이브 컷오버 런북 (메인루프 실행용 — 단계별, 롤백 포함)

⚠️ 본 세션은 실행하지 않음. 아래는 메인루프/게이트웨이 세션이 그대로 실행할 명령. 무중단 윈도우 수 초. 전제: crownyc 바이너리는 /Users/ef/CrownyOS/crownyc/crownyc (게이트웨이 dir에 없음 → 절대경로 사용).

[사전빌드 — 1회, 라이브 무접촉]

bashcd /Users/ef/CrownyOS/crownyc && export CROWNY_STD=/Users/ef/CrownyOS/crownyc/libs
./hanseonc_high /Users/ef/crowny-gateway/한선게이트웨이/게이트웨이라이브.한선 \
  > /Users/ef/crowny-gateway/한선게이트웨이/게이트웨이라이브.toau 2>/dev/null
test -s /Users/ef/crowny-gateway/한선게이트웨이/게이트웨이라이브.toau && echo BUILD_OK

[단계 0 — 사전체크, 라이브 무접촉] (모두 통과해야 진행)

bashfor u in http://127.0.0.1:8080/ http://127.0.0.1:9878/ http://127.0.0.1:9907/ http://127.0.0.1:9100/health; do
  printf "%s -> " "$u"; curl -s -o /dev/null -w "%{http_code}\n" --max-time 4 "$u"; done
curl -sk --resolve tiomta.com:8443:127.0.0.1 https://tiomta.com:8443/ -o /dev/null \
  -w "8443 ssl_verify=%{ssl_verify_result} code=%{http_code}\n" --max-time 5
# 기대: 8080=301, 9878/9907/9100=200, 8443 ssl_verify=0 code=200

[단계 1 — 워치독 동결] (재기동 레이스 방지)

bashkill -STOP 35477          # crowny-infra watchdog (PID 재확인: ps aux|grep 'cli.js watchdog')
ps -p 35477 -o pid,stat=  # STAT=T 확인

[단계 2 — 레거시 JS 게이트웨이 종료] (← 게이트웨이 세션 담당)

bashfor p in $(lsof -ti :8080); do
  ps -p $p -o command= | grep -q 'bin/cli.js start' && kill -TERM $p; done
sleep 1
lsof -nP -iTCP:8080 -iTCP:8443 -sTCP:LISTEN   # 비어 있어야 함(:8443도 같은 node라 함께 해제됨)

[단계 3 — 한선씨 평문 :8080 재바인딩 + stunnel :8443 종단]

bashcd /Users/ef/crowny-gateway
GW_PORT=8080 GW_REDIRECT=1 CROWNY_STD=/Users/ef/CrownyOS/crownyc/libs \
  nohup /Users/ef/CrownyOS/crownyc/crownyc run 한선게이트웨이/게이트웨이라이브.toau \
  > /tmp/한선게이트웨이-라이브.log 2>&1 &
sleep 2
stunnel /Users/ef/crowny-gateway/한선게이트웨이/stunnel-live.conf   # accept :8443 → connect :8080
sleep 1
lsof -nP -iTCP:8080 -iTCP:8443 -sTCP:LISTEN   # 한선씨 + stunnel LISTEN 확인
# 참고: GW_REDIRECT=0 이면 백엔드 평문 포워드(301 없이). 라이브 동등 거동은 GW_REDIRECT=1(301).

[단계 4 — 헬스 재확인]

bashcurl -s -o /dev/null -w "8080=%{http_code}\n" --resolve tiomta.com:8080:127.0.0.1 http://tiomta.com:8080/
curl -sk --resolve tiomta.com:8443:127.0.0.1 https://tiomta.com:8443/ -o /dev/null \
  -w "8443 tiomta ssl_verify=%{ssl_verify_result} code=%{http_code}\n" --max-time 5
curl -sk --resolve mpti.tiomta.com:8443:127.0.0.1 https://mpti.tiomta.com:8443/ -o /dev/null \
  -w "8443 mpti  ssl_verify=%{ssl_verify_result} code=%{http_code}\n" --max-time 5
# --resolve 필수(-H Host 는 000). 기대: 8080 301/200, 8443 둘다 ssl_verify=0 code=200

[단계 5 — 워치독 stack.yaml 교체 + 재개]

bash# /Users/ef/crowny-infra/crowny-stack.yaml 의 crowny-gateway 편집:
#   command: "cd /Users/ef/crowny-gateway && CROWNY_STD=/Users/ef/CrownyOS/crownyc/libs \
#             GW_PORT=8080 GW_REDIRECT=1 /Users/ef/CrownyOS/crownyc/crownyc run 한선게이트웨이/게이트웨이라이브.toau"
#   health:  http://127.0.0.1:8080/      ← :9100 한선씨 admin 구현 전까지 임시(루트). 구현 후 :9100/health 원복.
kill -CONT 35477
ps -p 35477 -o pid,stat=   # STAT=S/R 확인

[롤백 — 어느 단계든 실패 시]

bashkill -STOP 35477 2>/dev/null
# 한선씨 + stunnel 종료
for p in $(lsof -ti :8080); do ps -p $p -o command= | grep -q crownyc && kill -TERM $p; done
[ -f /tmp/stunnel-live.pid ] && kill -TERM "$(cat /tmp/stunnel-live.pid)"
sleep 1
# 레거시 node 복귀
cd /Users/ef/crowny-gateway && nohup /opt/homebrew/bin/node bin/cli.js start > /tmp/gw-rollback.log 2>&1 &
sleep 2
curl -s -o /dev/null -w "rollback :9100/health=%{http_code}\n" http://127.0.0.1:9100/health  # 200 기대
# stack.yaml crowny-gateway 원복(command/health 원래값) 후:
kill -CONT 35477

8.6 잔여 후속(컷오버 무관, 별도 차수)

  1. 한선씨 :9100 관리자 API(/health, /certs/renew) 구현 → stack.yaml health 원복.
  2. ext fullchain SAN 미커버 신규 도메인용 stunnel conf 동적생성(P2 인증서선택() 산출 연동).
  3. T4 관리자수신부(:9101) 실 기동 검증 — 작업 후 반드시 종료.

9. 라이브 컷오버 최종 GO / NO-GO + 런북 (2026-06-09)

5트랙(G1 전lineage TLS · G2 :9100 admin · G3 워치독 안전 · G4 광범위 도메인 일치 · GO 그림자 admin)의 그림자 검증 결과를 종합한 메인루프 실행용 최종 게이트.

9.1 트랙별 게이트 결과 (요약)

게이트범위결과핵심 증거
G1전 lineage TLS / SNI 슬레이브PASSlineage 4/4 커버, SNI 슬레이브 7(ext기본+main3+aimed2+real1). 단위 7/7, 런타임 TLS 6/6 도메인 ssl_verify=0(up 5건 http=200, down 1건 http=502 cert-only). LE 실인증서(issuer CN=YE1) 시스템 트러스트로도 ssl_verify=0
G2:9100 admin(그림자 :9101)PASS(GO)단위 6/6, 라이브 :9101 curl /health=200·/status=200·POST /certs/renew=200(위임)·/nope=404, certRenewRequests 0→1. 라이브 :9100/:8443 node PID 불변
G3워치독 pause/resume 안전성PASS부활 메커니즘 3종 식별(위험1/무해2). launchctl bootout→bootstrap 1사이클 실증(bootout rc=0·:9201 down·:9100 유지 / bootstrap rc=0·PID 36146 부활·services18·consecutiveDown0). repoint는 .proposed-han로만 제출(SSOT 보호)
G4광범위 도메인 served-cert 일치PASS표본 36도메인(ext17+abti19) TLS신뢰 36/36, 완전일치 32 + 백엔드다운동등 4. stunnel SNI 마스터=ext+19슬레이브=abti
GO그림자 admin 라이브 엔드포인트PASS:9101 4종 200/200/200/404, 카운터 증가, 라이브 무접촉

9.2 종합 판정 — GO

판정 규칙: G1(전lineage TLS) ∧ G2(:9100 admin) ∧ G4(광범위 도메인 일치) 모두 PASS → GO.

  • G1 = PASS, G2 = PASS, G4 = PASS → 세 조건 모두 충족 = GO.
  • 불일치 도메인 0건. 모든 그림자 검증에서 ssl_verify_result=0 전건.
  • 백엔드 다운 도메인(real.crowny.org / market:9733 / church:9310 / mind:7750 / aimed:9903 일부)은 task spec "백엔드 다운 도메인은 cert 핸드셰이크만 확인" 기준에 따라 cert-only PASS(http=502/000은 게이트웨이 무관, 별도 백엔드 복구 단계). → NO-GO 사유 아님.
  • G3 워치독 안전성: PAUSE는 반드시 launchctl bootout(kill 금지), RESUME은 launchctl bootstrap. 1사이클 실증으로 라이브 무중단 확인됨. repoint시 stack.yaml command에 'crownyc' 포함 → watchdog._probe(watchdog.js L143)가 :8443 TCP connect 프로브로 자동전환되어 한선씨 VM도 안전 감시.
NO-GO 조건(미해당): G1/G2/G4 중 하나라도 실패 또는 불일치 도메인 ≥1. — 현재 전부 미해당이므로 GO.

9.3 라이브 컷오버 운영 메모 (GO 전제 하 잔여)

  1. stunnel SNI 슬레이브 전수화: 현 구성은 표본(abti 19개)만 슬레이브. 전체 컷오버 시 crownybus.com cert 도메인 100개 전부 슬레이브 필요. 권장: 마스터 기본 cert를 도메인 수 많은 lineage로 두고 소수 lineage를 슬레이브화(ext 기본 + main/aimed/real 슬레이브, 또는 그 역).
  2. :9100 한선씨 admin API 구현: /health·/certs/renew 실구현 후 stack.yaml health 원복. 현재는 위임(legacy node가 보유).
  3. 백엔드 복구(컷오버 무관, 별도): real.crowny.org / market:9733 / church:9310 / mind:7750 / aimed:9903 upstream 가동.

9.4 메인루프 실행용 최종 라이브 컷오버 런북 (단계별)

불가침: 평상시 :8080/:8443/:9100/:9878/:9907 및 워치독 프로세스 kill 금지(일시중지는 bootout). 워치독 일시정지 없이 레거시 node 종료 시 자동 부활 → EADDRINUSE. 경로 변수: GW=/Users/ef/crowny-gateway/한선게이트웨이, CC=/Users/ef/CrownyOS/crownyc, LIVE=$GW/live/<lineage>/fullchain.pem (lineage∈{ext,main,aimed,real-crowny})

① 워치독 PAUSE (bootout — kill 아님)

bashlaunchctl bootout gui/$(id -u)/org.crowny.watchdog
# 검증:
launchctl list | grep -w org.crowny.watchdog            # 출력 없어야 함
curl -s -o /dev/null -w "legacy:9100=%{http_code}\n" http://127.0.0.1:9100/health  # =200 (레거시 생존)
롤백(이 단계 실패 시): launchctl bootstrap gui/$(id -u) /Users/ef/Library/LaunchAgents/org.crowny.watchdog.plist

② 한선씨 게이트웨이 :8081 그림자 기동 + 헬스 (레거시 무접촉)

bashcd $CC && ./hanseonc_high $GW/게이트웨이메인.한선 > /tmp/gwmain.toau 2>/dev/null && echo "compile=$?"  # =0
GW_PORT=8081 GW_REDIRECT=0 $CC/crownyc run /tmp/gwmain.toau & echo $! > /tmp/gw-han.pid
sleep 2
curl -s -o /dev/null -w "han:8081=%{http_code}\n" http://127.0.0.1:8081/health  # =200
롤백: kill -TERM $(cat /tmp/gw-han.pid) → 워치독 RESUME(⑧) → 종료.

③ 한선씨 admin :9101 그림자 준비 (아직 :9100 미점유)

bashcd $CC && ./hanseonc_high $GW/관리자.한선 > /tmp/관리자.toau 2>/dev/null && echo "compile=$?"  # =0
$CC/crownyc run /tmp/관리자.toau & echo $! > /tmp/admin-han.pid   # 마지막 줄 관리자수신부(9101) 상태
sleep 1; curl -s -o /dev/null -w "admin:9101=%{http_code}\n" http://127.0.0.1:9101/health  # =200

④ 레거시 node TERM (:8080+:8443+:9100 동시 해제 — 단일 프로세스)

bashLEGACY=$(lsof -ti :9100 | head -1); echo "legacy pid=$LEGACY"
kill -TERM "$LEGACY"
# 포트 해제 대기:
for i in $(seq 1 10); do lsof -ti :8443 >/dev/null || break; sleep 0.5; done
lsof -ti :8080 :8443 :9100 || echo "all-released"   # 셋 다 빈 상태여야 함
롤백: cd /Users/ef/crowny-gateway && nohup node bin/cli.js start >/tmp/gw-rollback.log 2>&1 & → 워치독 RESUME.

⑤ 한선씨 :8080 rebind + stunnel-live :8443 종단 기동

bash# 한선씨 게이트웨이를 :8080 평문으로 재바인드 (그림자 :8081 종료 후 정식 포트로)
kill -TERM $(cat /tmp/gw-han.pid); sleep 1
GW_PORT=8080 GW_REDIRECT=1 $CC/crownyc run /tmp/gwmain.toau & echo $! > /tmp/gw-han.pid
sleep 1; curl -s -o /dev/null -w "han:8080=%{http_code}\n" http://127.0.0.1:8080/health  # =200
# 한선씨 admin을 :9100으로 재바인드(관리자.한선 마지막 줄 관리자수신부(9100)) 
kill -TERM $(cat /tmp/admin-han.pid); sleep 1
$CC/crownyc run /tmp/관리자-9100.toau & echo $! > /tmp/admin-han.pid   # 9100판 사전컴파일본
sleep 1; curl -s -o /dev/null -w "admin:9100=%{http_code}\n" http://127.0.0.1:9100/health  # =200
# TLS 종단: stunnel accept :8443 → connect 127.0.0.1:8080
stunnel $GW/stunnel-live.conf
sleep 1; lsof -ti :8443 || echo "ERR:8443-not-listening"   # PID 있어야 함

⑥ 전 lineage 대표도메인 ssl_verify=0 / http 즉시 검증

bashdeclare -A REP=(
  [tiomta.com]=ext [mpti.tiomta.com]=ext
  [abti.crowny.org]=main [crowny.org]=main [crownybus.com]=main
  [aimed.crowny.org]=aimed [job.tiomta.com]=aimed
  [real.crowny.org]=real-crowny )
FAIL=0
for d in "${!REP[@]}"; do
  lin=${REP[$d]}
  r=$(curl -s -o /dev/null -w "%{ssl_verify_result}/%{http_code}" \
      --cacert $GW/live/$lin/fullchain.pem \
      --resolve $d:8443:127.0.0.1 https://$d:8443/)
  echo "$d ($lin) -> $r"   # ssl_verify_result=0 기대
  case "$r" in 0/*) : ;; *) FAIL=$((FAIL+1)); echo "  !! ssl_verify FAIL: $d" ;; esac
done
echo "ssl_verify failures=$FAIL"   # =0 이면 컷오버 성공 → ⑧ / >0 이면 → ⑦ 롤백
(http=502/000은 백엔드 다운 도메인 한정 허용 — ssl_verify=0이면 통과. ssl_verify≠0이 단 1건이라도 → ⑦.)

⑦ 롤백 (⑥ 실패 또는 어느 단계든 이상 시)

bash# 1) 한선씨 + stunnel 전체 종료
[ -f /tmp/gw-han.pid ]   && kill -TERM $(cat /tmp/gw-han.pid)   2>/dev/null
[ -f /tmp/admin-han.pid ]&& kill -TERM $(cat /tmp/admin-han.pid)2>/dev/null
[ -f /tmp/stunnel-live.pid ] && kill -TERM "$(cat /tmp/stunnel-live.pid)" 2>/dev/null
sleep 1; lsof -ti :8080 :8443 :9100 || echo "ports-clear"
# 2) 레거시 node 자동복원
cd /Users/ef/crowny-gateway && nohup node bin/cli.js start >/tmp/gw-rollback.log 2>&1 &
sleep 2
curl -s -o /dev/null -w "rollback :9100=%{http_code}\n" http://127.0.0.1:9100/health   # =200
curl -s -o /dev/null -w "rollback :8443=%{http_code}\n" -k --resolve abti.crowny.org:8443:127.0.0.1 https://abti.crowny.org:8443/  # =200
# 3) (stack.yaml repoint 했었다면) 원복
[ -f /Users/ef/crowny-infra/crowny-stack.yaml.bak ] && cp /Users/ef/crowny-infra/crowny-stack.yaml.bak /Users/ef/crowny-infra/crowny-stack.yaml
# 4) 워치독 RESUME (레거시 감시 복귀)
launchctl bootstrap gui/$(id -u) /Users/ef/Library/LaunchAgents/org.crowny.watchdog.plist
sleep 5; curl -s http://127.0.0.1:9201/health   # {"status":"ok"...}

⑧ 성공 시 — 워치독 repoint + RESUME

bash# (선택) stack.yaml의 crowny-gateway를 한선씨 스택으로 repoint (.proposed-han 검토 적용)
cp /Users/ef/crowny-infra/crowny-stack.yaml /Users/ef/crowny-infra/crowny-stack.yaml.bak
# crowny-gateway.command → 게이트웨이기동.sh (stunnel-live.conf + crownyc run), health → :9100/health
launchctl bootstrap gui/$(id -u) /Users/ef/Library/LaunchAgents/org.crowny.watchdog.plist
sleep 5
curl -s http://127.0.0.1:9201/health        # {"status":"ok","services":18}
launchctl list | grep -w org.crowny.watchdog # PID 부활 확인
# 최종 확인: 한선씨 스택이 워치독 감시 하 :8080/:8443/:9100 보유
repoint시 command에 'crownyc' 포함 → watchdog._probe(L143) :8443 TCP connect 프로브 자동전환(한선씨 VM 안전 감시). repoint 전제: $GW/게이트웨이기동.sh 작성(toau 산출물 459KB 존재 확인됨, 기동 스크립트는 컷오버 실행 세션이 작성).

9.5 라이브 생존 재확인 (이 종합 시점, 무중단)

:8080→16619  :8443→16619  :9100→16619  :9878→16619  :9907→96527   (node PID 16619 단일 / 9907 별도)
그림자 :8081/:8444/:9101 = free(잔류 0)
워치독 PID 36146 = launchd org.crowny.watchdog 등재·생존
legacy :9100/health=200, :8443 TLS handshake(abti)=200
라이브 미실행 — 본 작업은 런북 작성·검증만. 실제 컷오버는 메인루프 단계3에서 실행.


10. 최종 결론 — cert 키스톤 GO, 전체 컷오버는 기능패리티 차단 (2026-06-10)

✅ 입증된 것 (한선씨 게이트웨이 핵심 경로)

  • 프록시 코어 + stunnel TLS 종단 + admin(:9100) + trident 헬스 + 워치독 처리(launchctl bootout/bootstrap) 전부 그림자 검증.
  • cert/TLS 키스톤 100% GO: stunnel-live.conf 완성(master=ext 66 SAN + 슬레이브 97, hostname당 1개). 155 FQDN 전수 ssl_verify=0, cert SAN 매칭 155/155, 불일치 0.
  • 산출: 한선게이트웨이/{stunnel-live.conf, stunnel_conf_gen.py, 게이트웨이기동.sh, G_전수검증결과.md} + 5단계 한선씨 모듈.

⛔ 전체 라이브 컷오버 차단요소 = 기능 패리티 (cert 아님)

한선씨 프록시는 순수 리버스 프록시 → 레거시 게이트웨이의 다음 기능 미구현:
기능영향 도메인영향
websocket 업그레이드46 (websocket:true)WS 연결 끊김
SPA 폴백(404→index.html)157 (spa:true)딥링크 404(루트는 정상)
static-only 서빙1 (security.crowny.org)404
- 즉 지금 컷오버하면 WS 46 + SPA 딥링크 157 + static 1 도메인이 회귀. cert는 정상이나 기능 손실.

판정: cert 레이어 GO / 전체 컷오버 NO-GO (기능패리티 미완)

→ 무책임한 회귀 스왑 대신, 다음 단계로 기능 패리티 완성 권장:
  1. 한선씨 프록시에 websocket 업그레이드 릴레이 추가(Upgrade 헤더 감지→양방향 터널).
  2. SPA 폴백(upstream 404 + spa:true → index.html 서빙) — gateway.yaml spa 플래그 연동.
  3. static 서빙(security.crowny.org 등 static: 디렉토리).
  4. 그 후 전수 재검증 → 라이브 스왑.

운영 메모

  • 작업 중 레거시 게이트웨이가 1회 순간 재시작(워치독 자동복구, PID 46064). 백엔드 무손상. 한선씨 그림자가 라이브에 영향 주지 않도록 그림자 포트 격리는 유지됨.
  • 93/155 도메인 502(백엔드 다운) = 게이트웨이 무관, 별도 백엔드 복구 사안.

11. 기능 패리티 완료 + 무회귀 컷오버 판정 (2026-06-10)

§10에서 NO-GO 사유였던 기능 패리티 3종(WS / SPA / static) 을 한선씨 모듈로 구현·배선하고 통합 서버 게이트웨이통합.한선으로 전수 검증했다. 결과: 무회귀 컷오버 GO.

11.1 기능 패리티 — 4축 전수 결과

판정핵심 증거한계(빌드보고서 명시)
WS 웹소켓PASS(handshake)talk/code.crowny.org(:9900) 업그레이드 → HTTP/1.1 101 Switching Protocols 정확 릴레이(raw 소켓 probe). WS 종료 후 서버 정상 복귀(tiomta 200). 평문 GET→WS백엔드(:9767)는 5초 poll 가드로 503 graceful(서버 동결 없음)단일스레드 블로킹 → 장수명 풀듀플렉스 WS는 터널 중 서버 점유. 요청-응답형 ws/heartbeat에 적합(빌드보고서 한계 그대로)
static 정적PASSsecurity.crowny.org(static-only) :8444 200 + 본문 26011B 레거시(:8443)와 byte-identical. dd 16KB 청크 스트리밍으로 읽기() 16KB 캡 우회없음
SPA 폴백PASSstatic-only(security) 미존재 경로(/nonexist/deep123)→index.html 폴백 200(루트와 동일). upstream-backed spa:true(code.crowny.org 등)는 레거시 lib/proxy.js와 동일하게 백엔드 응답 그대로 패스(404=404). 정적 도메인만 SPA폴백, upstream은 백엔드 위임 — 레거시 동작 일치없음
보안 헤더PASS5개 보안헤더(X-Content-Type-Options/X-Frame-Options/X-XSS-Protection/Referrer-Policy/Strict-Transport-Security) + Vary: Accept-Encoding + X-Crowny-Service 부착, 멱등(중복 없음). upstream 응답 헤더영역에만 주입(본문 무손상). :8444/:8081 모두 5/5 확인없음

11.2 3대 근본문제 해소 (차단요인 제거)

근본문제증상해결입증
VM 문자열 concat 32KB 캡(STR_MAX_LEN2)응답 전체 누적 시 32KB 초과 잘림헤더만 누적 후 본문은 청크 직통 스트리밍main.crowny.org 319248B byte-identical
UTF-8 char≠byte 손상소켓받기 16KB 경계가 멀티바이트 글자 분할 → 부분()/글자수 재계산이 0xb0→0x00 손상바이트버퍼 릴레이(소켓버퍼수신/버퍼찾기/버퍼잘라/버퍼문자열, memcmp/memcpy/raw-len)tiomta 52967B byte-identical
keep-alive/침묵 백엔드 단일스레드 영구 블로킹응답 없는 백엔드가 서버 동결소켓폴링(소,5000/3000) poll 가드 + Content-Length 충족 종료caching :9884 200/29585 복구, talk-ws 503 graceful

11.3 무회귀 전수 매트릭스 — 170 upstream 도메인

  • 통합 자체 회귀: 0건. 동일상태 164/170, byte-identical 59건.
  • 플래그 8건은 전부 "레거시 라이브 프로세스 설정 드리프트" — 통합서버가 오히려 SSOT(현 gateway.yaml) 기준으로 더 정확함을 shadow==backend 직접 확인으로 입증:
  • monitor(200/2427)/projint(200/1033)/caching(200/29585)/reward-ui(200/9541): 통합=200(실 백엔드 byte-identical) vs 레거시=503(구 라우팅테이블 워치독 재기동 프로세스).
  • bank.crowny.org: 통합=348(실 :9400 JSON byte-identical) vs 레거시=29922(구 라우트 HTML). 통합이 SSOT 정확.
  • pkg.crowny.org: 통합=797(Verdaccio :4873 실응답 byte-identical) vs 레거시=833(레거시 trace/keepalive 헤더 추가분).
  • 진짜 차이 2건(둘 다 실패모드, 콘텐츠 무관): disk.crowny.org(통합 503 / 레거시 000=백엔드 완전 무응답), 티옴타작업소(통합 503 / 레거시 404, 비ASCII 도메인명). → 라우팅 회귀 아님.
  • 죽은 백엔드 ~94건: 통합 503 vs 레거시 503 — 상태코드 동일, 에러본문만 상이(통합 23B 평문 vs 레거시 error-pages.js HTML). 회귀 아님.
  • 동적 도메인(gateway/os.crowny.org): 동일크기 6912, 레거시 자기자신도 매 요청 상이 → 회귀 아님.
  • HTTP→HTTPS 301: 통합 :8082(redirect) vs 레거시 :8080 둘 다 301 + Location https + 쿼리스트링 보존 동일.
  • 풀 HTTPS 스택 :8444(stunnel TLS→:8081) vs 레거시 :8443: tiomta(52967)/mpti(23455)/security(26011)/crowny.org(98256) 전부 byte-identical.
  • 11.4 산출물 (게이트웨이통합.한선 배선)

    • W1(웹소켓)·W2(SPA정적)·W3(헤더) 3모듈을 통합 서버 게이트웨이통합.한선으로 배선·전수검증 완료. 컴파일 성공(775628B).
    • 가져오기 로컬제약은 libs/ 테스트제거 사본(게이트웨이웹소켓코어/SPA정적코어/헤더코어.한선)으로 해소.
    • 요청흐름: 수신→(리다이렉트모드?301)→(업그레이드?웹소켓릴레이 101)→(upstream매칭?청크직통프록시+보안헤더)→(static도메인?dd청크 정적스트리밍)→404/503.
    • 그림자 HTTP:8081 + stunnel TLS:8444 기동·검증 후 전부 종료(잔류 0).

    11.5 무회귀 컷오버 최종 판정 — GO

    판정 규칙: (WS ∧ static ∧ SPA ∧ 헤더 패리티 PASS) ∧ (통합 자체 회귀 = 0) → GO.

    • 4축 전부 PASS. 통합 자체 회귀 0건. blockers 없음(§10의 기능패리티 NO-GO 사유 해소됨).
    • 플래그 8건은 회귀가 아니라 레거시 설정 드리프트(통합이 SSOT상 더 정확, shadow==backend 입증).
    • 319KB까지 byte-identical 무손실 프록시 달성. → §10의 cert-only GO를 넘어 전체 무회귀 컷오버 GO로 격상.
    NO-GO 조건(미해당): WS/static/SPA/헤더 중 하나라도 FAIL, 또는 통합 자체 회귀 ≥1. 현재 전부 미해당이므로 GO.

    11.6 메인루프 실행용 — 최종 라이브 컷오버 런북 (재확정)

    불가침: 평상시 :8080/:8443/:9100/:9878/:9907 및 워치독 kill 금지(일시중지는 launchctl bootout). bootout 없이 레거시 종료 시 워치독 자동부활 → EADDRINUSE. 라이브 측정값(2026-06-10): 레거시 node PID 39859(단일, :8080+:8443+:9100), PPID 84742=org.crowny.watchdog. 워치독 라벨 = org.crowny.watchdog(PID 84742, 게이트웨이 감시). 백엔드 :9878(67325)/:9907(30405). 그림자 :8081/:8082/:8444/:9101 잔류=0. stunnel=/opt/homebrew/bin/stunnel(5.78). plist=/Users/ef/Library/LaunchAgents/org.crowny.watchdog.plist. 경로: GW=/Users/ef/crowny-gateway/한선게이트웨이, CC=/Users/ef/CrownyOS/crownyc, LIVE=$GW/live/<lineage>/fullchain.pem (lineage∈{ext,main,aimed,real-crowny})

    [사전빌드 — 1회, 라이브 무접촉]

    bashcd $CC && export CROWNY_STD=$CC/libs
    ./hanseonc_high $GW/게이트웨이통합.한선 > /tmp/게이트웨이통합.toau 2>/dev/null
    test -s /tmp/게이트웨이통합.toau && echo BUILD_OK   # 비어있으면 중단
    

    [단계 0 — 사전체크, 라이브 무접촉] (모두 통과해야 진행)

    bashfor u in http://127.0.0.1:8080/ http://127.0.0.1:9878/ http://127.0.0.1:9907/ http://127.0.0.1:9100/health; do
      printf "%s -> " "$u"; curl -s -o /dev/null -w "%{http_code}\n" --max-time 4 "$u"; done
    curl -sk --resolve tiomta.com:8443:127.0.0.1 https://tiomta.com:8443/ -o /dev/null \
      -w "8443 ssl_verify=%{ssl_verify_result} code=%{http_code}\n" --max-time 5
    # 기대: 8080=301, 9878/9907/9100=200, 8443 ssl_verify=0 code=200. 하나라도 불일치 → 중단.
    
    롤백: (라이브 무접촉 단계 — 롤백 불필요, 그냥 중단)

    [단계 1 — 워치독 PAUSE (bootout — kill 아님)]

    bashlaunchctl bootout gui/$(id -u)/org.crowny.watchdog
    launchctl list | grep -w org.crowny.watchdog            # 출력 없어야 함
    curl -s -o /dev/null -w "legacy:9100=%{http_code}\n" http://127.0.0.1:9100/health  # =200 (레거시 생존)
    
    롤백: launchctl bootstrap gui/$(id -u) /Users/ef/Library/LaunchAgents/org.crowny.watchdog.plist

    [단계 2 — 레거시 node TERM (:8080+:8443+:9100 동시 해제, 단일 프로세스)] (← 게이트웨이 세션 담당)

    bashLEGACY=$(lsof -ti :9100 | head -1); echo "legacy pid=$LEGACY"   # 기대 39859
    ps -p $LEGACY -o command= | grep -q 'bin/cli.js start' && kill -TERM "$LEGACY"
    for i in $(seq 1 10); do lsof -ti :8443 >/dev/null || break; sleep 0.5; done
    lsof -ti :8080 :8443 :9100 || echo "all-released"   # 셋 다 비어야 함
    
    롤백: cd /Users/ef/crowny-gateway && nohup node bin/cli.js start >/tmp/gw-rollback.log 2>&1 & → 단계1 워치독 RESUME.

    [단계 3 — 한선씨 통합 :8080 rebind + stunnel-live :8443 종단]

    bashcd /Users/ef/crowny-gateway
    GW_PORT=8080 GW_REDIRECT=1 CROWNY_STD=$CC/libs \
      nohup $CC/crownyc run /tmp/게이트웨이통합.toau > /tmp/han-gw.log 2>&1 & echo $! > /tmp/gw-han.pid
    sleep 2; curl -s -o /dev/null -w "han:8080=%{http_code}\n" --resolve tiomta.com:8080:127.0.0.1 http://tiomta.com:8080/  # 301
    stunnel $GW/stunnel-live.conf      # accept :8443 → connect 127.0.0.1:8080
    sleep 1; lsof -ti :8443 || echo "ERR:8443-not-listening"   # PID 있어야 함
    
    롤백: 단계7.

    [단계 4 — 전 lineage 8 대표 + WS/static 1 즉시검증]

    bashdeclare -A REP=(
      [tiomta.com]=ext [mpti.tiomta.com]=ext
      [abti.crowny.org]=main [crowny.org]=main [crownybus.com]=main
      [aimed.crowny.org]=aimed [job.tiomta.com]=aimed
      [real.crowny.org]=real-crowny )
    FAIL=0
    for d in "${!REP[@]}"; do
      lin=${REP[$d]}
      r=$(curl -s -o /dev/null -w "%{ssl_verify_result}/%{http_code}" \
          --cacert $GW/live/$lin/fullchain.pem --resolve $d:8443:127.0.0.1 https://$d:8443/)
      echo "$d ($lin) -> $r"
      case "$r" in 0/*) : ;; *) FAIL=$((FAIL+1)); echo "  !! ssl_verify FAIL: $d" ;; esac
    done
    # WS handshake (101 Switching Protocols 기대):
    printf 'GET / HTTP/1.1\r\nHost: code.crowny.org\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n' \
      | timeout 4 nc 127.0.0.1 8080 | head -1   # 기대: HTTP/1.1 101 Switching Protocols
    # static byte-identical (security.crowny.org):
    curl -sk --resolve security.crowny.org:8443:127.0.0.1 https://security.crowny.org:8443/ -o /dev/null \
      -w "static:8443=%{http_code} size=%{size_download}\n"   # 기대 200 / 26011
    echo "ssl_verify failures=$FAIL"   # =0 → 단계5 / >0 → 단계7 롤백
    

    [단계 5 — 헤더 멱등 확인 (선택, 무중단)]

    bashcurl -sk --resolve tiomta.com:8443:127.0.0.1 https://tiomta.com:8443/ -D - -o /dev/null \
      | grep -ciE 'X-Content-Type-Options|X-Frame-Options|X-XSS-Protection|Referrer-Policy|Strict-Transport-Security'  # =5(중복 없음)
    

    [단계 6 — 성공: 워치독 repoint + RESUME]

    bashcp /Users/ef/crowny-infra/crowny-stack.yaml /Users/ef/crowny-infra/crowny-stack.yaml.bak
    # crowny-gateway.command → $GW/게이트웨이기동.sh (stunnel-live.conf + crownyc run /tmp/게이트웨이통합.toau)
    #   GW_PORT=8080 GW_REDIRECT=1 CROWNY_STD=$CC/libs
    # health → http://127.0.0.1:8080/ (한선씨 :9100 admin 구현 전까지 임시 루트). 구현 후 :9100/health 원복.
    launchctl bootstrap gui/$(id -u) /Users/ef/Library/LaunchAgents/org.crowny.watchdog.plist
    sleep 5
    launchctl list | grep -w org.crowny.watchdog   # PID 부활 확인
    curl -s http://127.0.0.1:9201/health || true    # 워치독 헬스(있으면)
    # repoint command에 'crownyc' 포함 → watchdog._probe(L143) :8443 TCP connect 프로브 자동전환(한선씨 VM 안전 감시)
    

    [단계 7 — 롤백 (단계3~5 어느 지점이든 실패 시)]

    bash[ -f /tmp/gw-han.pid ]       && kill -TERM "$(cat /tmp/gw-han.pid)" 2>/dev/null
    [ -f /tmp/stunnel-live.pid ] && kill -TERM "$(cat /tmp/stunnel-live.pid)" 2>/dev/null
    sleep 1; lsof -ti :8080 :8443 :9100 || echo "ports-clear"
    # 레거시 node 자동복원
    cd /Users/ef/crowny-gateway && nohup node bin/cli.js start >/tmp/gw-rollback.log 2>&1 &
    sleep 2
    curl -s -o /dev/null -w "rollback :9100=%{http_code}\n" http://127.0.0.1:9100/health  # =200
    curl -sk --resolve abti.crowny.org:8443:127.0.0.1 https://abti.crowny.org:8443/ -o /dev/null -w "rollback :8443=%{http_code}\n"  # =200
    # stack.yaml repoint 했었다면 원복
    [ -f /Users/ef/crowny-infra/crowny-stack.yaml.bak ] && cp /Users/ef/crowny-infra/crowny-stack.yaml.bak /Users/ef/crowny-infra/crowny-stack.yaml
    # 워치독 RESUME (레거시 감시 복귀)
    launchctl bootstrap gui/$(id -u) /Users/ef/Library/LaunchAgents/org.crowny.watchdog.plist
    

    11.7 라이브 생존 재확인 (2026-06-10, 무중단 — 라이브 미실행)

    :8080→39859  :8443→39859  :9100→39859   (node PID 39859 단일, PPID 84742=org.crowny.watchdog)
    백엔드 :9878→67325  :9907→30405          (생존)
    워치독 org.crowny.watchdog PID 84742 = launchd 등재·생존(게이트웨이 부모)
    그림자 :8081/:8082/:8444/:9101 = free(잔류 0)
    :8080=301  :9100/health=200  stunnel=/opt/homebrew/bin/stunnel(5.78) 설치됨
    plist=/Users/ef/Library/LaunchAgents/org.crowny.watchdog.plist
    
    라이브 미실행 — 본 작업은 §11 패리티 검증·무회귀 판정·런북 재확정만. 실제 컷오버는 메인루프 단계3에서 게이트웨이 세션이 실행.


    12. ✅ 라이브 컷오버 실행 완료 (2026-06-10)

    • 한선씨 컷오버 도구로 실행(bash 아님): 컷오버실행.한선+검증/롤백/워치독제어 모듈 → /tmp/컷오버실행.toau, GW_CUTOVER_GO=1 crownyc run. 워치독bootout→레거시TERM→게이트웨이기동.sh go→lineage검증→실패시 자동롤백.
    • 1차 실패→자동롤백(무중단): 게이트웨이기동.sh가 GW_PORT 미설정→한선씨가 기본 :8081로 떠 stunnel :8443→:8080 불일치(6도메인 000)→자동롤백 레거시 복원. 수정: GW_PORT=8080.
    • 2차 성공(CUTOVER_OK): lineage 6/6 200/verify=0. :8080=crownyc(한선씨 게이트웨이), :8443=stunnel, 레거시 bin/cli.js 폐기. 광범위 10도메인 200/v0(academy 503=백엔드다운).
    • 워치독 repoint+bootstrap: crowny-stack.yaml crowny-gateway 블록을 command에 'crownyc'(TCP프로브)+port 8443+게이트웨이기동.sh go로 교체. 30초 모니터 무플래핑, 자동복구 활성. 백업 crowny-stack.yaml.bak-precutover-.
    • 잔여: 관리자.한선 자기검증 후 종료→:9100 admin 미상주(cert-reload 비동작, 비치명적). cert-manager periodic reload 영향 — 관리자.한선 서버상주화 수정 필요.
    • 검증 교훈: 게이트웨이 HTTPS는 curl --resolve <d>:8443:127.0.0.1(SNI). 워치독 한선씨 감시는 command에 'crownyc'+port→TCP프로브(HTTP 헬스 회피, watchdog.js L143).