Files
AriWeb-Suite/VERSION_HISTORY.md
T

48 KiB

VERSION_HISTORY

0.1.1 (2026-10-26)

  • 작성자: 개발 지시 — Hera(Ariweb-Suitle_Dev-Order_v0.1.1.md, 통합 검토: Hera v0.1.0·Neo v0.1.0·1차 개발계획서) · 구현 — Claude Fable 5.1(Ariweb Suite 통합 개발, 커밋 Co-Authored-By 표기)
  • 이전 버전: 0.1.0 — 개발 지시 문서(Ariweb-Suitle_Dev-Order.md)만 저장소에 있었고 코드는 없었다. 0.1.1 은 Ariweb Suite 의 첫 구현 릴리스다.
  • 정식 저장소: https://source.ibit.kr/OZ-Group/AriWeb-Suite (브랜치 release/0.1.1 → main 병합)
  • 구성: HAL(제어 평면·운영자 콘솔·공개 상태) · 고객 포털 · Node Agent · 도입 모듈 Webmaker 1.7.3 · AriMail 1.0.11. 외부 npm 의존성 없음, Node 22.13+.

경고 구간 변경

  • 사용량 경고 구간을 70% · 80% · 90% · 95% 네 단계로, 100% 에서 자원별 제한으로 통일했다(v0.1.0 지시의 구간 체계를 대체). 값은 코드에 고정하지 않고 상품정책 버전(product_versions.warn_levels_json, 기본 [70,80,90,95])에서 읽는다.
  • 단계별 동작(§13.4): 70% Portal 사전 안내 → 80% Portal + 외부 이메일 → 90% 예상 소진 시각과 증설·정리 방법을 강조한 긴급 경고 → 95% 곧 제한될 기능과 즉시 조치를 적은 최종 경고 → 100% 자원별 제한과 유지 기능·해제 방법 표시. 같은 원인의 반복은 하나의 사건(incident key <그룹>:<자원>:<대상>:<구간>)으로 묶인다.
  • 100% 제한의 자원별 의미: 웹 아웃바운드 → 사이트 대신 제한 안내, 다음 KST 월 또는 추가 용량 뒤 복구 · 웹 디스크 → 조회·삭제·내보내기 유지, 새 업로드·DB 증가·새 배포 제한 · 메일 저장 공간 → 조회·삭제 유지, 새 수신 임시 거부(발신 서버 재시도) · 월간 메일 통수 → 새 발신 차단 + 새 수신 임시 거부 · 메일함 수 → 새 메일함 생성 차단. 고객 데이터는 자동 삭제하지 않는다.
  • AriMail 쪽에도 같은 구간을 적용해 /api/usage 가 warnLevel·limitedReasons·monthReset 을 돌려준다.

재사용한 기존 기능(그대로 도입)

기능별 상세 표는 portal/webmaker/REUSE.md(Webmaker, 원본 revision 3b10859)와 portal/mail/REUSE.md(AriMail, 원본 revision a07f69f)에 있다. 두 모듈의 원본 회귀 테스트는 도입 뒤에도 모두 통과한다(Webmaker 59/59 — 원본 52 + 추가 7, AriMail 9개 묶음 모두 통과).

  • Webmaker(§0.1): AI에게 맡기기·내가 고르기 제작, Site Brief, Template 과 기존 Module, Page 생성·편집·미리보기·저장, AI 생성·수정과 Wallet/Cache 차감, 저장본 선택, Domain·DNS·TLS 관리(등록 업체·DNS 공급자·와일드카드 인증서), Gitea Source 연결과 변경 이력, 배포 결과 확인과 이전 Version 복구, AriMail Server 연결과 Mail 사용량 표시, 사용자·관리자 화면의 설정·상태·통계. 포털 사이트 상세 › 제작 탭의 "제작 화면 열기"(SSO) 로 진입한다.
  • AriMail(§0.3): Multi-domain Mail Service, Webmail(수신함·발신함·작성·회신·전달·검색), SMTP 발신·수신, IMAP·POP3, Resend·Haraka·External SMTP 발송 방식, Mail Domain·Account 관리, Mailbox 용량, 자동 응답·전달, 일반 첨부·링크 방식 대용량 첨부, POP3·IMAP 설정, DNS 설정·도메인 확인, 사용량 API, Webmaker 연동, 초기 설정·관리자·진단. 포털 메일 화면의 "웹메일 열기"(SSO 티켓) 와 외부 프로그램 설정 안내로 진입한다.
  • 공통 라이브러리에 옮겨 적은 기존 방식: Webmaker 의 원자적 JSON 저장·세션 세대·고정 관리자 비밀번호 폐지·scrypt 해시(→ lib/db·lib/session·lib/crypto), AriMail 의 의존성 없는 SMTP 클라이언트와 node:sqlite 운영(→ portal/mailer.mjs, lib/db), Webmaker deploy/remote-update.sh 의 갱신 순서(데이터 백업 → 교체 → 재시작 → 유닛 점검)와 AriMail deploy/deploy.sh 의 배포 순서(DB 백업 → 릴리스 복사 → 마이그레이션 → 재시작 → health → Haraka)를 HAL 모듈 설명자(hal/modules/index.mjs)와 Agent 모듈 설치기(agent/jobs/module.mjs)에 그대로 반영.

수정한 기존 기능(최소 연결 변경·오류 수정·정책 개선)

  • Webmaker(§0.2, modules/webmaker, 파일 머리 [Ariweb Suite 변경])
    • 최소 연결 변경: GET /api/auth/sso?ticket=(포털 서명 티켓으로 별도 로그인 없이 진입, 계정 aw-<그룹8>-<사용자8> 자동 준비) · 내부 API /api/internal/ariweb/*(프로젝트 목록·연결·소스·저장본 export·credits·health, 서비스 서명) · 상단 배너에 현재 사용자 그룹·사이트 표시 · 설정 그룹 ariweb.*(포털 주소, 공유 비밀은 보관소) · lib/ariweb.js(티켓 검증·연결 등록부 data/ariweb-links.json).
    • 정책 개선: 프로젝트와 운영 사이트를 구분(연결 등록부, "프로젝트" 표기), 연결된 프로젝트의 발행/재배포는 포털 배포 화면으로 안내(409 + 배포 URL), 프로젝트 삭제 전 포털 영향 조회(/internal/webmaker/project-impact)와 확인 필수 — 운영 사이트·배포본·도메인은 자동 삭제하지 않음.
    • 오류 수정/개선: 여러 사용자의 동시 편집을 조용히 덮어쓰지 않도록 사이트 저장본 rev 를 두고 불일치 시 409 와 양쪽 요약을 돌려준다.
    • 포털 쪽 정책: Draft 사이트는 운영 사이트 수를 쓰지 않고 최초 공개 배포 때 예약됨 → 대표 도메인 확인 뒤 사용 중; AI Wallet(Webmaker credits)과 호스팅·메일 사용량을 분리 표시; 외부 자가 배포는 비용·책임·상태를 구분.
  • AriMail(§0.4, modules/arimail, 15개 파일, 회귀 테스트 test/ariweb.test.mjs 8건 추가)
    • 오류 수정: test/usage.test.mjs 의 KST·UTC 월 경계 — 상대 시각(daysAgo) 을 KST 정오 기준으로 고정하고 limits.statsNow/monthlyCount(env, at) 로 고정 시각 검사(2026-10-31T14:59:59Z ↔ 15:00:00Z 경계 테스트) · Haraka/External SMTP 발신 때 RESEND_API_KEY 를 잘못 요구하던 server/smtp.mjs 451 오류.
    • 정책 개선: 도메인 등록부에 ariweb {kind: site_bound|standalone, siteId, groupId, mailServiceId} 와 operating(active|migrating_out|migrating_in|frozen) · 도메인별 보장량(LIMIT_ACCOUNTS/TOTAL_BYTES/MAILBOX_BYTES/MONTHLY_MESSAGES 를 테넌트 config 로) · 월간 통수 = 송신+수신, 최종 수신자 한 명당 한 통 · 저장 공간에 원문·일반 첨부·Inline·대용량 첨부 포함 · 100% 동작(저장 공간 → 수신 임시 거부·조회/삭제 유지, 월간 통수 → 발신 차단 mail_monthly_limit + 수신 임시 거부, 다음 KST 월 초기화) · 발송 큐(outbound_queue 표, 재시작 복구)와 안전 속도(도메인·서버별 초당 5건, 제출 초당 10건 이상은 제한·경고·악용 확인 abuse_flags, 운영자 /api/admin/rates) · 이전 중 두 서버 동시 처리 방지(operating ≠ active 면 수신 임시 거부·발신 차단) · SSO GET /api/auth/sso?ticket=.
    • 포털 쪽 정책: Site 대표 Mail 과 독립 MailService 구분, 사이트당 대표 Mail Domain 하나, 독립 MailService 는 운영 사이트 수 미소비, Site-bound → 독립 전환, 고객용 Mail Backup·복원 미제공 명시, 해지 후 30일 읽기·Export 와 삭제 예정일.
  • 미사용: Webmaker 자체의 배포 대상(deploy targets)·되돌리기 기능은 Ariweb 연결 프로젝트에 쓰지 않는다(관리형·외부 배포는 HAL 작업으로 통일). AriMail 별칭·전달 전용 주소 생성은 AriMail 에 기능이 없고 정책이 미확정이라 이번 버전에서 제공하지 않는다(무제한 제공 금지 원칙).

고객 화면

  • 공통 틀(§2): 상단 그룹 전환·알림·도움말·사용자 메뉴, 왼쪽 메뉴(대시보드·사이트·메일·도메인·백업·상품 및 결제·사용량·사용자 그룹 설정), 제목 아래 현재 위치·주요 작업 버튼, 상단 주의 항목. 모든 화면이 불러오는 중·비어 있음·정보 지연·부분 실패·전체 실패·권한 없음 상태를 갖고, 상태는 색과 함께 글자·기호로 표시하며 360px 에서 표가 카드로 접힌다. 파괴적 작업은 대상·영향 재표시 + 입력 확인.
  • 작업 상태 어휘(§2.2) 14종을 lib/status 로 통일하고, 서비스 상태·작업 상태·외부 건강 상태를 별도 필드로 둔다. 작업 블록은 현재/완료/다음 단계, 예상 완료 또는 산정 불가 사유, 마지막 갱신, 자동 재시도 횟수·다음 시각, 재시도·취소·되돌리기·문의 번호를 보인다.
  • 회원가입·로그인·복구(§3): 이메일 확인 전 유료 구매·운영 서비스 생성 불가, 중복 이메일은 존재 여부 비노출, 약관·개인정보·마케팅 동의 분리, 5회 실패 → 15분 잠금(해제 시각 표시), 기기별 세션 목록과 개별/전체 종료, 외부 이메일 재설정 링크(만료·사용 완료 표시), TOTP 다중 인증과 1회 표시 복구 코드.
  • 사용자 그룹(§4): 그룹 전환 즉시 반영·다른 그룹 정보 비노출, 구성원·초대(7일, 재발송·취소·만료)·역할·제거·정지(본인 세션과 미실행 작업만, 영향 범위 사전 표시)·탈퇴·소유권 이전, user-NN 별칭, 사이트별 권한(조회·콘텐츠 편집·배포·도메인/메일·결제/해지·전체 관리), 직접 주소 접근도 거부와 필요 역할 안내.
  • 대시보드(§5): 운영/구매 사이트 수(예약됨·사용 중 구분), 초안·제작 중, 정상·경고·장애, 관리형·외부, 도메인 조치, 메일 서비스·메일함, 백업 사이트, 진행 작업, 이번 달 예상 비용·결제 대기 금액, 중요도순 주의 항목(조치 화면 링크), 사용자/자동 작업을 구분한 최근 활동.
  • 알림 센터·감사 기록(§24): 분류·필수 알림·사건 묶음·조치 링크·읽음 처리, 누가·언제·어디서·무엇을·자동 여부·결과 조회, 권한·소유권·배포·해지·복원·이전·결제 승인은 삭제 불가 기록.

운영자 화면

  • HAL 운영자 콘솔 신설(hal.ariweb.net/ops/, §25): 허용 네트워크(사설망/VPN) 또는 기기 귀속 접근권 뒤의 별도 로그인(MFA), 고객 세션 차단, 접근권 만료·재인증 필요·승인 대기·거부 이유 배너, 메뉴 14개(운영 현황·고객과 사용자 그룹·주문과 결제 승인·상품과 정책·사이트와 배포·메일 서비스·도메인과 인증서·서버와 용량·백업과 복원·서버 이전·배포 릴리스·장애와 알림·감사 기록·플랫폼 복구) + 운영자 계정, 고위험 작업(모듈 되돌리기·서버 삭제 등) 3단계 확인, 1회 표시 값(등록 토큰·긴급 자격·접근권·복구 코드).
  • 운영 현황(§26.1): HAL·Portal·Webmaker·웹호스팅·AriMail·Source·백업·관측 상태, 등록/비정상 서버, 진행 중 배포·복원·이전, 처리 대기 승인, 용량 경고, 장애·유지보수 — 오래된 상태는 정보 지연 과 마지막 확인 시각.
  • 고객 조회(§26.2): 검색·그룹 상세(구성원·권리·구독·사이트·메일·도메인·백업·주문·사용량·정지·보존·실패 작업), 대신 변경은 허용 항목만 전후 값·사유·승인자를 기록하고 고객 감사 기록에도 남김, 고객 지원용 일시 접근 기록(대상·이유·만료·승인).
  • 주문 승인·상품 관리(§27), 서버 목록·등록 7단계·유지보수·격리·90일 지표(§28), 작업 화면의 대상별 결과(§29), 도메인·메일(원문 미노출, 접근 사유)·백업/복원·이전·Source 운영(§30), 릴리스·긴급 복구·재해복구 화면(§32~§34).
  • HAL 백엔드(§25·§28·§29): 운영자 계정은 고객 계정과 분리(별도 로그인 화면·세션 종류 operator), 허용 네트워크(사설망/VPN CIDR) 또는 사용자·기기 귀속 단기 접근권 없이는 로그인 화면도 열리지 않음, 고위험 작업은 최근 재인증 + 3단계 확인(영향 범위 → 대상 식별정보 재확인 → 최종 실행과 되돌리기 가능 여부), 접근권 만료·재인증 필요·승인 대기·거부 이유 표시.
  • 포털 운영자 API(/internal/ops/*, 서비스 키 서명): 주문 승인(대상·금액·권리 변화·현재 사용량, 반복 승인 안전), 상품 버전 관리(판매된 조건은 새 버전), 사용량·제한, 사이트·배포·도메인·Source·메일(원문 미노출, 진단 사유 기록)·백업/복원 승인(고객·그룹·사이트·도메인·백업 시각 최종 확인)·이전·소유권 이전·생명주기 운영.

사이트 생성과 배포

  • 사이트 목록·필터·생성(§7): 이름·용도·Webmaker 프로젝트(새로/기존)·템플릿·언어·시간대·배포 방식 선택, 초안은 사이트 수 미소비, 생성 뒤 다음 단계 안내.
  • 사이트 상세(§8) 10개 탭. 관리형 운영 사이트는 실제 수집값(site.usage 작업 → usage_samples)만 표시하고, 미배포 사이트는 준비 단계를, 외부 사이트는 Agent 연결·마지막 배포 결과·외부 확인·고객 책임 범위와 제공되지 않음 을 표시한다.
  • 배포 방식(§10): 관리형(설명·모니터링 범위·한도·백업·이전 가능성·예상 시간·승인 비용, 정적 + 승인된 동적 실행 형태 사전 점검) / 외부(지원 대상 = External Pull Agent 를 설치할 수 있는 Linux 서버, 준비 정보, 건별 비용, 미제공 기능, 장애 분리, 버전이 기록되는 동의 external-deploy-2026-10-0.1.1, 외부 메일 배포 미지원).
  • 배포(§11): 사전 확인(저장본·사이트 수·배포 위치·용량·도메인·필수 설정·작업 충돌, 통과/차단 구분), 10단계 진행 표시, 화면을 닫아도 계속, 완료 상태 배포 검증 완료 / 도메인 설정 필요 / 공개 운영 중, 최초 공개 배포 때 사이트 수 예약됨 → 대표 도메인 확인 뒤 사용 중, 실패 시 단계·안전한 오류·문의 번호·기존 버전 유지·재시도·되돌리기, 중간 결과 지금 정리하고 반환. 배포 방식 변경은 새 위치 준비 → 별도 배포 → 검증 → 도메인 전환 → 이전 위치 정리.
  • 외부 배포: Agent 설치 안내·일회용 연결·연결 확인·배포·재배포·제거·마지막 외부 확인·실패 잔여물 정리.

호스팅

  • Node Agent 가 관리 서버에서 사이트를 /var/www/ariweb-sites/<siteId>/releases/<n> + current 로 배치하고 nginx vhost(와일드카드 인증서 재사용 또는 사이트별 certbot, 유지보수 페이지)를 템플릿으로 생성, 내부·외부 확인, 사용량 수집(디스크·DB·업로드, 일/월/누적 인바운드·아웃바운드, 24시간·7일·30일 추이, 오류율·p95).
  • 서버 등록(§28.2)은 역할·위치 → 일회용 등록 정보(10분, 1회, 재표시 없음) → Agent 설치 → 신원·기능·용량 확인 → 운영자 승인 → 배치 가능. 유지보수(신규 배치 중지 → 영향 확인 → 이전 → 시작/종료 → 재개). 총 보장량·실제 용량을 넘는 배치 금지.

메일

  • 메일 서비스 종류·목록·생성 흐름(§15), 메일함 목록·생성·설정(§16, 초기 비밀번호 1회 표시 또는 초대 링크, 정지 메일함도 수·공간 소비 표시, POP3·IMAP 서비스 스위치와 적용 후 접속 확인, 웹메일 SSO 진입, 외부 프로그램 설정값·비밀번호 비표시), 사용량·제한(§17, 월간 송신+수신 합계·최종 수신자 기준·누적·할당·다음 KST 초기화·마지막 계측, 발송 제한 사유·해제 시각·문의, 대용량 첨부 정책 사전 표시), 고객용 메일 백업·복원 미제공 명시(§17.4), 메일 도메인 보안(§18, 정상·권장 개선·오류, 복사 가능한 값).
  • 활성화는 결제·승인 권리가 있을 때만, 내부 준비만으로 완료하지 않고 실제 외부 송신·수신·회신 확인 작업을 거친다(운영자가 검증용 수신 주소를 설정하지 않으면 사용자 확인 필요 로 정직하게 멈춤).

도메인과 인증서

  • 도메인 목록·연결 8단계(§12: 입력 → 웹/메일/둘 다 → 소유 확인(TXT) → DNS 값 안내(복사) → 반영 확인(미반영과 잘못된 값 구분) → 인증서 발급 → 외부 접속 확인 → 대표 지정), 한 사이트 여러 도메인도 사이트 수 하나, 대표 도메인 변경 시 이전 주소 이동 처리 선택, 인증서 발급·갱신·만료 임박·실패 표시, 유효하지 않은 인증서를 정상 HTTPS 로 표시하지 않음, 같은 도메인의 다른 고객 연결 차단.
  • 등록 업체·DNS 자동화는 Webmaker 의 기존 도메인 탭(SSO) 에서 수행하고 포털은 상태·확인을 담당한다. 도메인 등록 기능이 없는 환경(검증 Catalog)에서는 외부 등록기관 안내만 표시한다.

상거래

  • 상품 목록(§6.1)은 운영자가 활성화한 최신 상품 버전을 표시(가격·한도를 화면에 고정하지 않음, 미확정 정책은 미확정 정책 안내). 주문 8단계(§6.2), 0.1.1 기본 결제는 수동 결제 확인(입금 안내·주문 번호·금액·통화·세금·기한 → 운영자 입금 확인 → 승인/거절 → 승인 뒤에만 권리 활성화), 새로 고침·연타 중복 방지(멱등 키), 거절·만료 사유와 재주문, 자동 결제수단 비표시, 갱신 전 청구 예정 안내와 갱신 결제 대기, 미납 제한 시점은 정책에서 읽어 고객·운영자 동일 표시, 미납 즉시 삭제 없음.
  • 결제 화면(§6.3), 상품 축소·해지(§6.4, 범위 안이면 즉시, 아니면 줄여야 할 항목을 구체적으로 표시하고 보류 → 정리 후 재검증), AI Wallet 분리 표시·자동 초과 사용 기본 꺼짐·초과 허용 시 항목별 상한·기간·철회 결과 확인(§6.5).
  • 출시 검증 Catalog(catalog/release-0.1.1.json): basic·team 두 기본 상품(사이트 수·웹 디스크·월간 웹 아웃바운드·메일 저장 공간·월간 메일 통수·메일함), 옵션(독립 메일·Source·백업·디스크/아웃바운드/메일함 추가), 가격·통화·세금·수동 승인·권리·한도·백업 일정·보존·복원 비용·생명주기 결과를 모두 채움. 출시 시험용이며 운영자가 콘솔에서 새 버전으로 관리한다.

백업과 복원

  • 관리형 사이트 단위 유료 옵션(§19): 백업 가능한 관리형 사이트에서만 구매, 외부 사이트 미제공, 사이트당 하나, 구매 화면에 저장 한도·사용량·일정·Daily/Weekly/Monthly 보존 개수·첫 백업 예정·원격 사본 검증 방식·추가 저장 옵션(활성 상품정책에서 읽음). 포함: 현재 배포본·DB·업로드·복원에 필요한 설정. 제외: 메일 원문·소스 저장소·Webmaker 이력·외부 배포 데이터·플랫폼 내부 사본(화면에 명시).
  • 백업은 운영 서버와 다른 저장 서버에 두고 생성 후 읽기 검증, 반복 실패 알림과 다음 재시도, 저장 공간 부족 시 최소 보존 세트를 지우지 않고 다음 백업 중지·안내, 중지된 사이트의 정기 백업 중지와 재개 방식 표시, 옵션 만료 후 7일 보관 뒤 삭제.
  • 복원(§20): 요청 정보(백업 시각·포함 데이터·영향·예상 중단·비용·되돌리기 범위) → 비용·승인·작업 시간 → 9단계(보호 시점·격리 검증·복원·기능 확인·외부 확인·사용자 확인 또는 자동 완료·정리) → 실패 시 유지/되돌림, 보호 시점 유지 기간·마지막 되돌리기 시각·완료 방식 사전 표시.

이전

  • 서버 이전(§21): 정적 자동(조건 충족 시)·동적/메일 승인형·고객 요청 유료 구분, 사전 안내(대상·이유·위치·시간·영향·변경 제한·비용·행동), 10단계, 시작 전과 전환 직전 재점검(조건 변화 시 자동 중지·알림), 두 서버 동시 운영 금지, 실패·일시 중지·취소·되돌리는 중·되돌림 완료 구분, 경계 표시(취소 가능 마지막 단계, 쓰기 제한 시각, 목표 중단 시간, 유일 운영 시점, 되돌리기 기간, 이전 위치 보존·삭제, DNS·인증서 대기 처리), 플랫폼 사유 이전 무과금.
  • 소유권 이전(§22): 대상/제외 구분(AI Wallet·그룹 미배정 용량·청구 이력 제외, 독립 메일은 명시 선택), 요청 → 수락(받는 쪽 권리 부족 시 보류) → 운영자 심사 → 원자적 완료(일부만 이전된 상태 비노출), 진행 작업 중에는 시작 불가, 만료·취소 시점, 분쟁 동결, 청구 책임 종료·시작 시각.
  • 운영 사이트 수 반환(§14) 8단계 점검표와 대표 메일의 독립 전환(주소·메일함·별칭·전달·비밀번호·DNS 유지 항목별 확인, 전환 전후 송수신 확인, 누락 시 반환 거부).

모니터링

  • 공통 상태 어휘와 정보 확인 지연, HAL 응답 불가 시 포털은 신규 증가를 막고 기존 조회·삭제·내보내기를 유지(§13.4·§26.2), Agent heartbeat 30초·90초 침묵 시 오프라인, 서버 지표(CPU·메모리·디스크·inode·I/O·네트워크·시계 차이) 90일 보관, 사건(incident) 묶음, 공개 상태 페이지 /status(개인정보·내부 위치 비표시).
  • 운영자 장애 화면(§31.2): 같은 원인 경고를 하나의 사건으로 묶고 고객 영향·최근 배포·담당자·고객 공지·실제 사용자 경로 확인 뒤 종료. 고객 화면(§31.1)은 자신의 서비스에 대한 정상·성능 저하·일부 장애·중단과 영향 기능·시각·대응 상태만 보이며 내부 서버 이름·다른 고객 정보는 노출하지 않는다. 공개 상태 페이지(§31.3)는 로그인 없이 주요 서비스 상태와 계획된 유지보수를 보인다.

HAL/Node Agent 운영

  • HAL(§32): 릴리스 등록부(버전·main 커밋·빌드 시각·artifact sha256·검사 결과·승인), 부트스트랩은 최초 설치에서만(deploy/bootstrap-hal.sh: 승인 릴리스·고정 artifact 선택, 보관소·인증서·접근 경로 준비, HAL 설치, 첫 Agent 등록 토큰) 이후 수동 설치 잠금, 정상 배포 순서(HAL 먼저 → HAL 자체 건강·실행 버전 확인 → Agent 연결 확인 → 모듈 배포 → 모듈별 건강·실제 버전 → 고객 경로 확인 → 완료/되돌리기), HAL 확인 실패 시 나머지 배포 금지, 대상별 성공·실패·대기 결과(일부 실패를 전체 성공으로 표시하지 않음), 목표 버전과 실제 버전 차이·조정(reconcile).
  • Node Agent: 일회용 토큰 등록 → 키·비밀 1회 발급, HMAC 서명 요청, long-poll 작업 수신, 단계 저장과 재시작 후 재개, sudo -n 범위 최소화(systemctl·nginx·certbot), sudo 불가 시 사용자 확인 필요 로 보고, External Pull Agent 모드(사이트 배포·제거·확인만, 한 사이트에 귀속).
  • 긴급 복구(§33): 사건 번호·사유·대상·허용 작업·짧은 유효 시간, 재인증 + 서로 다른 내용의 3단계 승인(한 명도 가능, 단계별 시각 기록), 모든 작업 기록, 자격 1회 표시·정상화 후 만료, 허용 범위(HAL·HAL 저장 정보·비밀정보·인증서 기반·artifact 저장소·최초 Agent 연결) 밖 작업 거부, HAL 정상화 뒤 실제/원하는 상태 비교·조정.
  • 플랫폼 재해복구(§34): HAL 운영 정보·진행 작업·로그인·비밀정보·인증서 기반·배치·서버 등록 정보의 복구 사본·외부 보관·검증·훈련 기록, RTO/RPO/주기/보존 설정과 측정값 비교, 복구 시작 별도 승인과 기존 제어 위치 중지 확인, 하나의 HAL 만 운영(임대, 같은 호스트의 죽은 프로세스는 이어받음), 훈련 성공 전 정식 운영 준비 미표시.

실제 환경 배포에서 발견한 결함 수정(2026-10-26, ariweb.net 호스트 첫 배포)

  • Agent 실행 계정 모드(agent/jobs/module.mjs, deploy/module-as-user.sh, deploy/sudoers/ariweb-agent): 도입 모듈 AriMail 은 서버에서 다른 계정(arihakdang)으로 운영되어 /srv/arihakdang-mail 을 Agent(master)가 쓸 수 없었다. 유닛의 User= 가 Agent 계정과 다르면 풀기·REVISION·current 전환·정리·DB 백업·마이그레이션을 sudo -n -u <계정> bash deploy/module-as-user.sh 로 그 계정이 수행한다(sudoers 는 이 스크립트만 root 가 아닌 계정으로 허용, 경로는 모듈 디렉터리 안으로 제한). artifact 는 <srv>/agent/work 에 받는다.
  • AriMail 마이그레이션 DB 경로: server/db-migrate.mjs 는 DB_FILE 환경이 없으면 릴리스 디렉터리 안에 빈 DB 를 만든다. 유닛의 EnvironmentFile(/etc/<유닛>/gateway.env)을 실행 계정으로 읽어 실행하도록 고쳤다(직접 모드도 같은 파일을 읽는다).
  • 도입 모듈 실제 버전: Webmaker(package.json 1.7.3)·AriMail(1.0.11)의 상류 버전이 HAL 의 목표 버전(0.1.1)과 달라 version_mismatch 로 배포가 실패했을 것이다. 풀 때 적는 REVISION.json 의 Suite 릴리스 버전을 실제 버전으로 읽고 상류 버전은 upstreamVersion 으로 함께 보고한다.
  • 기존 유닛 보존(hal/modules/index.mjs keepExistingUnit): Webmaker 의 운영 유닛은 ProtectSystem=strict·ReadWritePaths 등 강화 지시문을 갖는데 템플릿이 Environment 줄만 보존하고 나머지를 지웠을 것이다. 유닛이 이미 <appDir>/current 를 가리키면 다시 쓰지 않는다.
  • 포털 nginx 접근 경로(deploy/bootstrap-hal.sh): deploy/nginx/ariweb-portal.conf.tmpl 이 어디서도 적용되지 않아 my.ariweb.net 이 열리지 않았다. 부트스트랩 4단계(접근 경로 준비)에서 HAL 과 함께 설치한다.
  • 부트스트랩 인증서 확인(deploy/bootstrap-hal.sh): /etc/letsencrypt/live 는 root 만 읽을 수 있어 일반 계정의 [ -f ] 가 항상 거짓이었다(실제 부트스트랩이 4단계에서 중단). sudo -n test -f 로 확인한다.
  • 포털 artifact 에 Catalog 누락(scripts/release.mjs): 상품정책 시드 파일 catalog/release-0.1.1.json 이 portal artifact 에 들어가지 않아 운영자 시드(/internal/ops/commerce/catalog/seed)가 실서버에서 실패했을 것이다. portal 경로에 catalog 를 넣었다.
  • artifact 디렉터리 모드(scripts/release.mjs): 개발 PC 의 umask(077)가 artifact 에 0700 디렉터리로 들어가 서버에서 다른 실행 계정이 Agent 의 deploy/module-as-user.sh 와 풀린 릴리스를 읽지 못했다. tar --mode=u=rwX,go=rX --owner=0 --group=0 로 정규화한다. deploy/agent-install.sh 도 호출자의 umask 와 무관하게 코드 트리를 a+rX 로 맞춘다.
  • 실행 계정 모드 보완(agent/jobs/module.mjs): 내려받은 artifact(0600)를 실행 계정이 읽도록 0644 로 바꾸고, 도우미 스크립트는 sudoers 규칙과 같은 <srv>/agent/current/deploy/module-as-user.sh 경로로 부른다(ESM 의 import.meta.url 은 releases/<ver> 실제 경로로 풀린다).
  • 같은 버전 재설치(agent/jobs/module.mjs, module-as-user.sh rename): 실행 중인 current 디렉터리를 지우고 다시 풀던 것을, 임시 디렉터리에 풀고 기존 디렉터리를 <ver>.prev-<시각> 으로 보존(되돌리기 대상)한 뒤 제자리에 두도록 바꿨다. DB 백업 파일 이름은 같은 초에 겹치지 않게 한다.
  • Webmaker 데이터 백업(agent/jobs/module.mjs): 운영 데이터 디렉터리의 읽을 수 없는 파일(root 가 남긴 마이그레이션 기록)이 tar 를 실패시켜 배포가 막혔다. --ignore-failed-read 로 경고만 남기고(결과 unreadable 목록) 진행한다. ariweb.net 호스트의 해당 파일(/data/webmaker/migrations)은 소유권을 master 로 바로잡았다.
  • 부트스트랩 릴리스 기록(hal/core.mjs setBootstrap): HAL 기동 전 CLI bootstrap-release 가 쓴 UPDATE 가 행(id=1)이 없어 무효였다(건강 응답의 releaseVersion 이 null). 행을 먼저 만든다(test/hal.test.mjs 회귀 테스트).
  • AriMail 마이그레이션의 EnvironmentFile 읽기(deploy/module-as-user.sh migrate): systemd 문법(MAIL_FROM_NAME=Ari Hak dang 처럼 따옴표 없는 공백 값)을 bash 로 소스하다 실패했다. 줄 단위로 읽어 따옴표를 벗기고 export 한다.
  • 사후 절차 실패 시 되돌리기(agent/jobs/module.mjs): current 전환 뒤 마이그레이션이 실패하면 current 가 새 릴리스를 가리킨 채 남았다(다음 재시작 때 마이그레이션 없는 새 코드가 뜬다). 실패하면 이전 릴리스로 되돌리고 재시작한다.
  • AriMail 전체 설정 API 주소(portal/mail/arimail.mjs 주석·운영 안내): AriMail 은 설정 API(/api/setup/*)를 기본 도메인 호스트(req.headers.host, 예: mail.arihakdang.com)에서만 응답하고 다른 테넌트 호스트로는 404 를 준다. Node fetch 는 Host 헤더를 바꿀 수 없으므로(시도했다가 되돌림) 포털의 설정 주소(setup_url)는 기본 도메인 이름이어야 하고, 그 이름이 설정 포트(loopback 전용 8791)로 풀려야 한다 — ariweb.net 호스트에서는 /etc/hosts 에 127.0.0.1 mail.arihakdang.com 을 두었다(알려진 제한에 기록).
  • Agent heartbeat 의 모듈 버전(agent/index.mjs): current/package.json 버전(상류 1.7.3·1.0.11)을 보고해 HAL 이 배포 직후 "목표와 다름(drift)" 으로 표시했다. REVISION.json 의 Suite 버전을 먼저 읽는다.
  • 새 유닛 enable(agent/jobs/module.mjs): 템플릿으로 만든 유닛(포털)을 enable 하지 않아 재부팅 뒤 뜨지 않았을 것이다. 유닛을 쓸 때 systemctl enable 한다.
  • 서버 한 대 운영의 역할 대체(hal/core.mjs pickServer, portal/backup/service.mjs pickStoreServer): 첫 서버는 역할이 control 하나뿐이라 사이트 배포(web)·백업 저장(backup) 대상 서버를 고를 수 없었다. 요청 역할의 서버가 없으면 control 서버를 web·backup 으로도 쓴다(전용 서버가 생기면 우선). 같은 서버에 백업을 두는 것은 여전히 운영자 override 가 필요하다.
  • 초안 사이트의 백업 중지 사유(portal/backup/service.mjs): 미배포(초안) 사이트의 옵션을 정기 실행이 site_cancelled(해지) 로 중지해 표시가 틀렸다. site_not_deployed(사이트 미배포) 로 구분한다.
  • 회귀 테스트: test/agent.test.mjs 에 실행 계정 모드(도우미 스크립트 실제 실행·경로 제한 거부)·REVISION 버전·기존 유닛 보존 검사를 추가했다.

HAL 전용 호스트 부트스트랩(2026-10-27, bear hal21.ariweb.net)

  • deploy/bootstrap-hal.sh --portal-host none: 포털을 다른 호스트에서 운영하는 HAL 전용 호스트에는 my.ariweb.net nginx 접근 경로를 만들지 않는다(이전에는 항상 만들어 포털이 없는 호스트에도 죽은 vhost 가 남았다). 기본값(my.ariweb.net)의 동작은 그대로다.
  • bear(Ubuntu 24.04, nginx 1.24, Node 24.22, certbot nginx 플러그인 운영)에 HAL 만 최초 부트스트랩: 인증서는 호스트별 certbot(webroot /var/www/html, ECDSA, 갱신 훅 systemctl reload nginx) — --cert /etc/letsencrypt/live/hal21.ariweb.net --acme /var/www/html. 기존 Webmaker·Gitea·Matrix·기본 서버는 건드리지 않았다. 절차·검증·되돌리기는 docs/RUNBOOK-0.1.1.md §7. 배포 artifact: main ab75b7d, hal sha256 f574d875…(deploy/ 변경으로 ariweb.net 호스트의 e7741899… 와 다름). 알려진 사소한 결함: 부트스트랩 5단계의 HTTPS 자체 확인이 nginx reload 직후 실행되어 거짓 경고가 날 수 있다(결과에 영향 없음).
  • HAL 기본 주소 안내(hal/app.mjs): https://hal21.ariweb.net/ 접속이 JSON 404를 반환하던 동작을 운영자 콘솔 표준 경로 /ops/로 이동하도록 수정했다. /ops의 기존 사설망/VPN·기기 접근권 관문과 별도 운영자 로그인은 그대로 적용된다.
  • 기존 사이트 인벤토리(agent/webmaker-inventory.mjs, HAL 서버 상세): Node Agent가 사이트 디렉터리와 Webmaker 메타데이터·배포 이력을 대조해 모든 디렉터리의 ID·제목·계정 식별자·배포 상태(deployed/unpublished/draft/unknown)·서비스 상태·도메인·크기·파일 수를 HAL에 연결한다. 메타데이터가 없는 디렉터리도 missing으로 남기며 총 수·수집 수·잘림 여부·스캔 오류를 함께 기록한다. 2 MiB heartbeat 제한과 1,000항목 제한을 넘는 인벤토리는 512 KiB 이하 인증 배치로 전송하고 마지막 배치에서만 원자 반영한다. 페이지 본문·프롬프트·연락처·인증정보는 전송하지 않는다.

운영 Webmaker ↔ HAL 연동 점검 도구(2026-10-27, webmaker.ariweb.net)

  • scripts/webmaker-inventory.mjs(+ test/webmaker-inventory.test.mjs 5건): 운영 Webmaker 데이터(JSON)·포털 DB·HAL DB 를 읽기 전용으로 안정 식별자(프로젝트 32-hex id, 포털 s_/g_/u_, HAL srv_)로 대조해 연결 등록부 일치·충돌·중복·누락, SSO 회원(aw-<g8>-<u8>) 신원, 도메인, Gitea sites/<id>/main ref, HAL 모듈 등록·버전·건강을 판정한다. 비밀로 보이는 키는 출력 전에 거부(assertNoSecrets). 충돌·누락이 있으면 종료 코드 2.
  • 2026-10-27 hostinger 실데이터 결과: 프로젝트 10(포털 연결 일치 3·Webmaker 고유 7), 회원 12(SSO 3 일치·고유 9), 도메인 2, Gitea refs 13, HAL module_targets.webmaker 0.1.1 health ok — 충돌 0·누락 0, 적용 변경 없음(교체도 불필요). 사전 스냅샷·복원 검증·사후 readback 은 docs/verification/webmaker-hal-link-2026-10-27.md, 절차는 RUNBOOK §8.
  • HAL21 제어 평면 전환 완료: bear HAL을 main 12958ab로 갱신한 뒤 hostinger Node Agent를 hal21.ariweb.net의 기존 서버 srv_01a17bd4dbcdb55877f2d9fcab에 재등록·승인했다. Webmaker unit·데이터는 변경하거나 재시작하지 않았다. 명시적 DATA_ROOT·DATA_DIR·SITES_ROOT로 수집한 HAL 인벤토리는 프로젝트 10/10, 절단 없음, 오류 0이며 module_targets.webmaker는 0.1.1/health ok다. 사전 체크섬 32,608건 불일치 0, Git 7개 fsck 성공, Gitea ref 13개 동일. 결과와 롤백은 docs/verification/webmaker-hal21-link-2026-10-27.md.

기존 메일 서비스(AriMail 인스턴스) ↔ HAL 관리형 MailService/Node 가져오기(2026-10-27, mail.arihakdang.com · webmail.ibit.kr → bear hal21.ariweb.net)

  • hal/mailsvc.mjs(+ 마이그레이션 hal_0003_mail_services, test/hal-mailimport.test.mjs 7건): HAL 관리형 메일 서비스 등록부(mail_services, 도메인 단위 논리 리소스, 불변 id mls_…, 출처 권한 arimail:<hostname>:<unit>, 도메인별 active owner 정확히 하나 — 부분 유일 인덱스)와 가져오기 단위(mail_imports). 읽기 전용 discovery 문서만 입력으로 받고 비밀값이 어디에든 있으면 거부(비밀은 secretRefs 의 file:/dir:/vault:/env: 참조만 저장). dry-run 이 기본, 충돌(collision: 다른 서버/인스턴스가 이미 active)·중복·누락이 하나라도 있으면 아무것도 적용하지 않음, 적용은 한 트랜잭션 + 감사(immutable), 같은 출처·서버의 재적용은 update(멱등), 적용 단위 되돌리기(생성 행 삭제·갱신 행 복원). 소유 조직은 증거로 확인되기 전까지 unassigned_legacy_managed. Agent heartbeat 의 arimail 모듈 상태가 그 서버의 행에 last_sync·health 로 비친다(core.heartbeat). Data Plane(AriMail 송수신·계정·메일·DNS/MX·TLS·provider)은 바꾸지 않는다 — HAL 이 멈춰도 메일은 그대로다.
  • scripts/mail-discover.mjs(+ test/mail-discover.test.mjs 2건): 원본 호스트에서 단독 실행하는 읽기 전용 discovery — 유닛 상태(systemctl show)·current/REVISION·package.json·AriMail 도메인 등록부(data/domains.json)·건강 API·haraka-status·게이트웨이/테넌트 DB 집계(계정·메일 수·크기·무결성, 주소·내용 미열람)·유닛 PID 소유 리스너·nginx vhost·TLS 주체/만료·공개 DNS(1.1.1.1/8.8.8.8, 호스트 /etc/hosts 오염 방지)·certbot 훅. env/config 는 키 이름과 경로·권한만.
  • HAL CLI(hal/index.mjs): mail-import --discovery <json> (--server <id> | --create-server --name …) [--apply], mail-import-rollback --import <id>, mail-services(readback JSON), server-token --server <id>(운영자 콘솔이 닿지 않는 부트스트랩·연동 단계의 시스템 신원 토큰 발급, 감사 cli:<by>). 운영자 API: GET /ops/api/mail-services(+readback: 총수·active·도메인 중복·서버별·비밀 누출 검사), GET /ops/api/mail-services/:id(감사 포함), GET /ops/api/mail-services/imports, POST /ops/api/mail-services/import {discovery, serverId, apply}(적용은 재인증), POST /ops/api/mail-services/imports/:id/rollback(재인증). 운영자 화면 /ops/mail: HAL 관리형 메일 서비스 표(도메인·공개 주소·서버/인스턴스·리비전·계정/메일함/메일·건강/동기화·TLS/DNS·비밀 참조 수)를 먼저 그리고 포털 메일 서비스는 그 아래 #portal-mail 에 중계로 채운다(ops.js).
  • 2026-10-27 실제 적용: bear HAL 을 커밋 79b45ca 릴리스로 교체(재시작 2.6초, 메일 서비스 프로브 무중단) → 서버 2(pending) · MailService 7(hostinger 인스턴스 6 도메인 + jitsi 1, 모두 unassigned_legacy_managed, duplicates 0, secretLeaks 0) · jitsi Node Agent 등록(heartbeat → last_sync_source=agent, 승인은 운영자 결정) · hostinger 는 기존 HAL(hal.ariweb.net) 제어 평면과의 이중 제어를 피해 Agent 미설치(관측 전용). 원본 메일 서비스 변경 0. 결과·백업 sha256·readback 은 docs/verification/mail-hal-link-2026-10-27.md, 절차·되돌리기는 docs/RUNBOOK-0.1.1.md §9.

포털·hostinger Node Agent 제어 평면 이전 — hal.ariweb.net → hal21.ariweb.net (2026-10-27, Hera)

  • HAL CLI(시스템 신원, 감사 actor cli:<by>·reason) 보완: config-set(운영 값만 data/config.json 에 기록, 비밀 키 거부, 서비스 재시작 뒤 반영) · module-deploy(운영자 API POST /ops/api/modules/:name/deploy 와 같은 멱등 키 규칙으로 module.deploy 작업을 큐에 넣고, 실행은 serve 프로세스의 작업 엔진이 맡는다) · job --id(작업·자식 readback). 운영자 콘솔 자격 증명이 없는 연동 단계용. 테스트 test/hal-cli.test.mjs 3건(별도 프로세스 실행·멱등·감사·서비스 측 엔진이 집어 실행).
  • 결과(docs/verification/portal-hal21-link-2026-10-27.md): bear HAL21 을 main dfb708e 릴리스(artifact 4e419a72…)로 교체·등록·승인, portalUrl=https://my.ariweb.net; link-portal 값을 파이프로만 포털 vault service:hal 에 넣고(구 service:portal 제거) 포털 halUrl=https://hal21.ariweb.net; HAL21 작업 j_01a17cb5716c669450412967f7 로 portal 0.1.1 재배포(이전 릴리스 .prev-20261027093350 보존, health ok). 포털→HAL21 인증 읽기(health·servers·jobs 계약) 실측, 포털 DB 집계·Webmaker 인벤토리·AriMail 전후 동일, 외부 URL/TLS 전부 정상. 구 HAL 은 server offline 상태로 잔존(중지는 사람 결정). blocker: hostinger 서버 행 role mail → pickServer(web) null(운영자가 control 로 변경 필요).

운영자 콘솔 부트스트랩 배너 결함 수정 — 완료 뒤에도 "부트스트랩 미완료" 경고(2026-10-27, bear hal21.ariweb.net, Hera)

  • 증상: bear HAL21 /api/health 는 bootstrap.complete=true · halRunningVersion=0.1.1 · firstAgent 있음 · manualInstallLocked=true 인데, 운영자 콘솔 모든 화면 상단에 ! 부트스트랩 미완료(HAL 실행 버전 확인 전, 첫 Agent 미등록)… 경고가 계속 보이고, 배포 릴리스 화면도 HAL 실행 버전: 확인 전 · 부트스트랩 미완료 로 그려졌다.
  • 원인: hal/ui.mjs 의 공통 틀(shell) 배너가 core.selfHealth(d).bootstrap 의 실제 계약(camelCase complete·halRunningVersion·firstAgent)이 아니라 존재하지 않는 snake_case 열 이름(completed_at·hal_running_version·first_agent_id)을 읽어 항상 undefined → 늘 "미완료·확인 전·미등록"으로 렌더링. 같은 파일의 /ops/releases 라우트는 releasesView 가 bootstrap 행(snake_case hal_running_version·manual_install_locked)을 기대하는데 camelCase selfHealth().bootstrap 을 넘겨 같은 증상. 서버 렌더(HTML) 결함이며 ops.js/ops.css 는 관여하지 않는다(브라우저 캐시 무관).
  • 수정(hal/ui.mjs 만, 2곳): 배너는 health.bootstrap.complete / halRunningVersion / firstAgent 를 쓰고, /ops/releases 는 running: core.bootstrapState(d) 를 넘긴다. 옛 snake_case fallback 은 두지 않았다(단일 계약).
  • 검증(strict TDD): test/hal-ui.test.mjs 에 회귀 1건 추가 — selfHealth.bootstrap 에 snake_case 필드가 없음을 고정하고, (1) 초기 확인 전·미등록 (2) claimLive 뒤 0.1.1·미등록 (3) 첫 Agent 등록·승인(완료) 뒤 운영 현황·서버·릴리스 화면에 경고 없음 + 릴리스 화면 HAL 실행 버전: 0.1.1 · 수동 설치 잠김 (4) Agent 만 승인된 새 HAL 은 확인 전·등록됨. RED: 수정 전 (2)에서 확인 전 으로 실패(완료 상태에서도 경고·릴리스 화면 확인 전 잔존을 별도 스크립트로 기록). GREEN: 파일 7건·전체 22파일 150건 통과·실패 0. 배포 결과는 docs/verification/hal21-ops-banner-fix-2026-10-27.md.
  • 배포 결과(bear hal21, 2026-10-27 14:36Z): 커밋 648247f 릴리스(hal artifact ed957a0a…)를 /srv/ariweb/hal/releases/0.1.1-648247f22415 에 stage → 추출된 hal/ui.mjs sha·node --check·snake_case 참조 0 확인 → register-release(approved, by hera-ops-banner-fix)·bootstrap-release → current 전환·재시작(health 까지 1.08초, NRestarts 0). data/config(opsAllowCidrs 5항목)/vault/DB sha·크기 전후 동일, 사설 백업 /srv/ariweb/backups/hal-pre-banner-fix-20261027T143608Z. readback: /api/health bootstrap complete·mainCommit 648247f, Agent 2대 heartbeat 재개, 배포된 코드만 import 한 in-memory 서버 렌더에서 완료 상태 배너 없음·릴리스 화면 HAL 실행 버전: 0.1.1 · 수동 설치 잠김; 포털·Webmaker·메일 회귀 이상 없음. 되돌리기: current 를 0.1.1-dfb708e933e5 로 되돌리고 재시작.

도입 소스

  • 가져오기: node scripts/import-sources.mjs 가 고정 커밋(Webmaker 3b10859884ef2fd0f2af11934ab6c16370fd64b8, AriMail a07f69f1ffb6667de6e66b3d1ec43c1c66fab924)을 검사하고 실행에 필요 없는 문서·보고서·샘플을 제외한 전체를 modules/webmaker(176 파일)·modules/arimail(88 파일)로 복사, 파일별 원본 경로·대상 경로·수정 여부·원본 해시·라이선스 검토를 IMPORTED_SOURCES.md/.json 에 기록한다.
  • 라이선스 검토: 두 저장소 모두 private: true, 별도 LICENSE 없음 — OZ-Group 내부 전용 소스로 같은 조직의 Ariweb Suite 에서 재사용 가능, 외부 배포 불가. AriMail haraka/ 는 npm Haraka(MIT) 를 설치 시점에 내려받는 래퍼만 포함.
  • 수정된 파일(원본 대비): Webmaker 8개(lib/auth.js lib/config.js lib/store.js lib/vault.js public/app.js public/index.html public/style.css server.js + 신규 lib/ariweb.js, test/ariweb.test.js), AriMail 15개(deploy/deploy.sh haraka/plugins/arimail.js package.json server/api.mjs server/config.mjs server/domains.mjs server/limits.mjs server/main.mjs server/providers/index.mjs server/smtp.mjs server/usage.mjs test/gateway.test.mjs test/smtp.test.mjs test/usage.test.mjs web/setup.js + 신규 server/sendqueue.mjs, migrations/0009_ariweb_queue.sql, test/ariweb.test.mjs). 이유는 위 "수정한 기존 기능" 과 각 파일의 [Ariweb Suite 변경] 주석.
  • 참조 저장소는 직접 배포하지 않는다. HAL 이 modules/* 에서 만든 artifact(webmaker-0.1.1.tar.gz, arimail-0.1.1.tar.gz)만 배포한다.

알려진 제한

  • 로컬 E2E 검증(docs/verification/local-e2e-2026-10-26.md, 실제 HAL·포털·Node Agent 4대 + 가짜 Webmaker·AriMail·메일): 34개 완료 조건 중 19개 로컬 확인, 14개 부분 확인, 1개(외부 메일 왕복) 로컬 확인 불가, 결함 0. 부분 확인 항목은 실제 DNS·공인 서버·실 AriMail 왕복·시간 경과(30일 보존)가 필요한 부분이며, 실제 환경 확인 결과는 docs/verification/ 에 별도 기록한다.
  • ariweb.net 호스트의 /etc/hosts 에 127.0.0.1 hal.ariweb.net my.ariweb.net webmail.ariweb.net mail.arihakdang.com 이 있다: 앞의 둘은 공개 DNS 생성 전 같은 서버 안의 Agent·포털이 HAL 에 닿기 위한 임시 항목이고, mail.arihakdang.com 은 AriMail 전체 설정 포트(8791, loopback 전용)에 기본 도메인 이름으로 접속하기 위한 항목이다(cloud-init 이 /etc/hosts 를 관리하므로 재부팅 뒤 확인 필요).
  • 실제 환경 검증(docs/verification/real-env-0.1.1.md, ariweb.net 호스트, 2026-10-26): 34개 중 실제 확인 7(가입·확인 메일, 그룹·초대, 주문·승인·권리, 초안 사이트, 독립 메일 서비스, HAL 우선 배포·HAL 작업 배포, HAL 재시작 유지), 부분 확인 7(Webmaker 진입, 관리형 배포 요청, 사이트 화면, 대표 메일·메일함, 백업 옵션, 모듈 갱신, 감사 일치), 미수행 20(공개 DNS·실 도메인·수신 주소·다중 서버·시간 경과 필요), 결함 0. 출시 완료는 선언하지 않는다.
  • DNS: ariweb.net 은 hosting.co.kr 네임서버(웹 패널)라 hal.ariweb.net·my.ariweb.net A 레코드는 운영자가 패널에서 만들어야 한다. 레코드가 생기기 전에는 로컬 --resolve 로만 확인된다.
  • 실제 외부 메일 왕복 검증은 운영자가 검증용 수신 주소(자동 응답 메일함)를 설정해야 완료된다.
  • AI Wallet 은 Webmaker credits 를 읽어 표시만 하며, 초과 사용 과금 라인 생성은 하지 않는다(표시·제한 해제만).
  • 메일 서비스 서버 이전은 AriMail operating 상태 전환 도우미(setMigrating) 가 포털에 없어 설정 필요 로 안내된다.
  • 별칭·전달 전용 주소 생성, 대량 .eml 내보내기(IMAP/POP3·원문 다운로드 안내로 대체), Gitea 브랜치 자동 삭제(상태만), 외부 메일 배포, 자동 결제수단은 이번 버전에서 제공하지 않는다.
  • 실제 환경(ariweb.net 호스트)은 서버 한 대(역할 control)로 운영된다. 관리형 사이트 배포·백업 저장은 control 서버를 대체 사용하고, 백업을 같은 서버에 두려면 운영자 override 가 필요하다. 서버 간 이전·외부 Agent·다른 호스트 재해복구는 서버가 늘어난 뒤 실환경에서 확인한다.
  • Webmaker 의 페이지 제작(AI 생성·저장)은 사람이 제작 화면에서 수행해야 하므로 실환경 검증에서 저장본 없는 초안 사이트까지만 자동 확인했다(관리형 배포·백업 실행·복원·외부 확인은 저장본이 생긴 뒤 수행).
  • Agent 의 사용량 수집은 Agent 가 배포한 사이트의 nginx awstats 로그만 집계한다(Webmaker 자체 호스팅 사이트는 Webmaker 통계 유지).

미확정 정책값

  • 활성 상품정책에 {status: 'deferred'} 로 표시되어 화면에 미확정 정책 으로 안내되는 값: alias_counting(별칭·전달 전용 주소 계산 방식 — 확정 전 무제한 제공 금지, 메일함 수에 포함), large_attachment(대용량 첨부 허용 크기·다운로드 횟수·보관 기한 — 시스템 안전 상한 우선), ai_wallet_pricing(AI 크레딧 단가 — Webmaker 관리자 설정을 따름).
  • 운영자가 후속 상품정책에서 정할 값: 도메인 등록·갱신 가격(등록 업체 연동 시), 외부 배포 건별 비용의 최종 금액, 이전 목표 중단 시간·되돌리기 기간·이전 위치 보존 기간·고객 요청 이전 비용의 운영 값, 복원 비용·중단 시간, 보존 기간 재정의(기본 30/30/30/7일), 초과 사용 단가. 검증 Catalog 의 수치는 모두 출시 시험용이다.