HAL 0.4.0: 통합 설정 관제 — Webmaker·AriMail·Agent 서버 단위 설정을 HAL 이 관리(설정 목록·범위 global/server·비밀값 Vault·유효값 hash, /ops/api/settings·재인증, settings.apply → settings.apply.target → Agent module.configure(HMAC 설정 받기·hash 확인·hal-managed.json 0600·재시작·모듈 적용 확인), /ops/settings 화면·운영 현황 "설정 적용 필요", AI 도구 hal_settings_get/set/apply(비밀값 거부)), 도입 모듈 Webmaker 1.9.0·AriMail 1.1.0(HAL 0.4.0 대응 halCompat, hal-managed 적용·관리 항목 409 managed_by_hal 잠금·"HAL 관리" 표시) 재도입(pin 8f8716c·f959b65, import-sources 미수정 파일 갱신), Agent heartbeat 관리, module-as-user write --mode 600, 개발 지시 v0.4.0(Oz)·docs/HAL-SETTINGS.md·VERSION_HISTORY 0.4.0 — test/hal-040.test.mjs RED → GREEN 5/5, agent 11/11, 전체 31파일 통과

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
zzabisagent-lab
2026-10-29 06:46:45 +00:00
co-authored by Claude Opus 5.5
parent 54db663531
commit 9f1e490b51
44 changed files with 1075 additions and 82 deletions
+1
View File
@@ -29,6 +29,7 @@ Dev-Order §5(아키텍처)·§28·§29·§32·§33·§34 의 백엔드 구현.
| `POST jobs/:id/progress {progress, steps, log}` → `{cancelRequested}` / `POST jobs/:id/result {status: done\|failed\|needs_user, result, error, errorCode, userMessage}` | |
| `GET releases/:version/artifact?module=` | tar.gz 스트리밍, `X-Sha256` |
| `POST/GET transfers/:id` | HAL 경유 파일 전송(이전·원격 백업), 24시간 보관 |
| `GET settings/:module` | [0.4.0] 자기 서버 범위의 HAL 관리 설정(유효값·비밀값·hash). 작업 `module.configure` 가 부른다 — docs/HAL-SETTINGS.md |
## 4. 포털 API(`/portal/v1`, 키 `portal`) — docs/HAL-JOBS.md
+3
View File
@@ -77,3 +77,6 @@ HAL 서비스와 같은 SQLite 를 WAL 로 함께 읽는다. 읽기 도구만
- 원인: 단말 영역이 모든 키를 셸로 보내 Ctrl+C 가 복사 대신 ^C 가 되었고, 긴 인증 주소가 줄 끝(열 수)에서 끊겨 두 줄로 보여 통째로 고를 수 없었다.
- `term.mjs`: `joinedLines`(꽉 찬 줄은 다음 줄과 이어 붙임) · `plainText` · `extractUrls`(스크롤백·대체 화면 포함, 상자 문자 제외, 꼬리 구두점 제거, 중복 제거) · `copyDecision`(선택이 있으면 Ctrl+C=복사, Ctrl+Shift+C·Ctrl+Insert=항상 복사, Ctrl+V/Shift+Insert=붙여넣기, 나머지=전송).
- 화면(`ai-render.shellModalHtml`·`shellUrlsHtml`, `ai.js`): "감지된 주소" 목록(복사·열기 — 새 탭, noopener), "전체 출력 복사", "선택 복사", "텍스트로 보기"(선택 가능한 textarea), 단말 드래그 선택 가능(`user-select:text`). 복사는 Clipboard API → 실패 시 숨은 textarea+execCommand → 안내.
## 10. 0.4.0 — 통합 설정 관제 도구
- `hal_settings_get`(읽기: 저장 값·비밀값 설정 여부 `confidential[]`·서버 범위 유효값·적용 상태) · `hal_settings_set`(고위험 — 비밀값은 받지 않음 `secret_not_allowed`) · `hal_settings_apply`(고위험 — 작업 `settings.apply`). 스킬 문서 §4.1. 자세한 계약은 docs/HAL-SETTINGS.md.
+54
View File
@@ -0,0 +1,54 @@
# HAL 통합 설정 관제 (Ariweb Suite 0.4.0)
HAL 이 도입 모듈·Node Agent 의 **서버 단위 설정**을 대신 관리한다. 개발 지시 `Ariweb-Suitle_Dev-Order_v0.4.0.md`(Oz).
## 1. 무엇을 관리하나
| 모듈 | 묶음 | 대표 항목 |
|---|---|---|
| Webmaker 1.9.0 | API 키·인증 | `auth.mode`·`auth.apiKey`·`auth.oauthToken`·`serviceApiKey`·`backlogKey`·`mail.apiKey`·`source.token`·`ariweb.secret`·`mail.adminPassword` |
| | 마진·가격 정책 | `marginPct`·`fx.mode/manualRate/spreadPct`·`signupCredit`·`maxEdits`·`defaultTier`·`tiers.*`·`signupApproval` |
| | 모델 | `internalRef`·`defaultModel`·`claudeModels`·`ai.*MaxTurns`·`ai.maxJobMinutes`·`ai.maxConcurrentJobs`·`ai.codexSandbox` |
| | 전체 적용 서비스 | `service.allowSignup`·`letsEncryptEmail`·`mail.fromName/defaultDomain/formBase`·`ariweb.portalUrl`·`endpoints.*`·`limits.*`·`ssl.acmeWaitMin` |
| | 서버별 설정(서버 범위만) | `service.publicBaseUrl/formBaseUrl/siteOrigin/trustedProxies/internalAllow`·`ai.claudeBin/codexBin`·`source.*`·`mail.provider/url/apiUrl/domain/adminLogin/nickname/ip`·`ssl.acmeDir` |
| AriMail 1.1.0 | 서버 단위 | 수·발신 방식, Resend, DNS 제공자, SMTP 중계, 내장 Haraka(서버 범위), 표시·동기화, 사용량 API, Ariweb SSO |
| Node Agent 0.4.0 | Agent | `heartbeatMs` |
- **관리하지 않는 것**: AriMail 도메인별 관리(추가 도메인 설정·`LIMIT_*`·계정·메일함 — 메일 서버 사용자가 직접), Webmaker 사이트·회원·템플릿·테마 등 콘텐츠.
- 목록 정의: `hal/settings/catalog.mjs`(형식 text·int·number·bool·enum·list·url·path·secret, 범위, 재시작 필요).
## 2. 저장·유효값
- `managed_settings(scope, module, key, value_json, is_secret)` — scope `global` | `server:<서버 id>`. 비밀값은 HAL Vault `managed:<scope>:<module>:<key>` 에만, 행에는 참조만(마이그레이션 `hal_0010_managed_settings`).
- 유효값 = 전체 ← 서버 덮어쓰기. hash = `sha256:` + 모듈·유효값(비밀값 포함)의 정규 JSON sha256.
- `managed_settings_state(server_id, module, applied_hash, applied_at, status, error, job_id)` — 적용 상태. `upToDate` = 마지막 적용 hash 가 지금 유효값 hash 와 같음.
## 3. API(운영자 세션·CSRF)
| 경로 | 설명 |
|---|---|
| `GET /ops/api/settings` | 모듈 목록·설정 목록·모듈별 개요(배치 서버·적용 상태·적용 필요 수) |
| `GET /ops/api/settings/:module?scope=` | 저장된 값(비밀값은 있음/없음), 서버 범위면 유효값·적용 상태 |
| `PUT /ops/api/settings/:module {scope, values}` | 저장(재인증 10분). null·빈 값 = 지정 삭제. 형식 오류·모르는 항목 400 `bad_setting` |
| `DELETE /ops/api/settings/:module/:key?scope=` | 지정 삭제(재인증) |
| `POST /ops/api/settings/:module/apply {serverIds, restart}` | 적용 작업(재인증). 대상 비우면 배치 서버 전체, 없으면 400 `no_targets`, 배치 안 된 서버 400 `not_placed` |
| `GET /agent/v1/settings/:module` | Agent HMAC. 자기 서버 범위의 유효값(비밀값 포함)·hash |
감사 기록(`settings.set`·`settings.apply`)에는 키 이름만 남는다.
## 4. 적용 흐름
`settings.apply`(부모) → 서버마다 `settings.apply.target` → Agent `module.configure`:
1. 작업 payload 에는 hash 만(비밀값 없음). Agent 가 `/agent/v1/settings/:module` 에서 직접 받고 hash 가 다르면 `settings_hash_mismatch`(그 사이 설정이 바뀜).
2. `<configDir>/hal-managed.json`(0600) 원자 교체. 실행 계정이 다르면 `module-as-user.sh write --mode 600`. configDir: Webmaker `/data/webmaker`(DATA_ROOT), AriMail `<appDir>/data`(설정 파일 옆), Agent `<dataDir>`. 서버 facts `configDirs` 로 바꿀 수 있다.
3. `restart` 면 서비스 재시작·건강 확인(Agent 자신은 결과 보고 뒤 재시작).
4. 모듈이 파일을 적용하고 `hal-managed.applied.json`(hash·시각·항목·오류, 비밀값 없음)을 남기면 Agent 가 기다려(최대 45초) 결과에 싣는다. 모듈이 다른 hash·오류를 보고하면 `module_apply_failed`.
## 5. 모듈 쪽(HAL 0.4.0 대응)
- Webmaker 1.9.0 `lib/hal-managed.js`: 기동·파일 변경(10초 확인) 때 settings/config/보관소에 적용(auth·fx·tiers·mail 은 묶음 저장). 관리자 콘솔 설정·보관소·설정 페이지에서 관리 항목 409 `managed_by_hal`, 설정 탭 "HAL 관리" 안내.
- AriMail 1.1.0 `server/hal-managed.mjs`: 기본 도메인(서버) 설정에만 적용, `LIMIT_*`·설치 항목 제외. 설정 페이지에서 관리 항목 값 변경 409, 사용량 키 생성 잠금, "HAL 관리" 카드.
- 두 모듈 `package.json` 에 `ariwebSuite.halCompat = "0.4.0"`. 파일이 없으면 동작 변화 없음(단독 운영).
## 6. 화면·AI
- 운영자 콘솔 `/ops/settings` "통합 설정": 모듈 탭 → 범위(전체/서버) → 묶음별 입력 → 저장 → "서버에 적용"(서버 선택·재시작) → 서버별 적용 상태. 운영 현황 서버 카드에 "설정 적용 필요".
- AI 도구: `hal_settings_get`(읽기) · `hal_settings_set`(고위험, 비밀값 거부 `secret_not_allowed`) · `hal_settings_apply`(고위험).
## 7. 알려진 제한
- HAL 에서 지정을 지워도 모듈에 이미 적용된 값은 그대로 남는다(잠금만 풀린다). 되돌리려면 HAL 에서 원하는 값을 지정해 다시 적용한다.
- Webmaker 의 등급·내부 호출 모델은 그 서버에서 "사용 가능"인 모델만 저장된다 — 아니면 `module_apply_failed` 로 보고된다.