| name | manage-discord-sessions |
| description | Codex 또는 Claude로 실행되는 Discord 백그라운드 작업의 설정·상태·실시간 활동·재부팅 복구를 ADK 워크스페이스에서 관리합니다. |
Discord 세션 관리
Codex와 Claude가 함께 쓰는 관리 스킬입니다. 별도 제품 CLI나 naia-agent, naia-shell 없이 동일한 내부 스크립트로 로컬 상태를 읽습니다.
현재 구현된 범위
- SQLite 기반 작업·안전 이벤트 영속 기록
- 서비스 상태의 신선도와 작업 활동 상태 구분
- 사전에 선언한 완료 검사와 신뢰 가능한 검증 증거
status, jobs, job, watch, history, latest 조회, 해시 검증 첨부 복구, 명시적 reply
- 서로 독립적인 Codex
exec --json 및 Claude -p --output-format stream-json 실행 어댑터
- 실행별 격리 홈, 최소 인증 파일 복사, 안전 이벤트 변환, 시간 제한·취소·시그널 종료 처리
- 이전 권한 프로필 재사용 차단, 무승인 실행 강제, 승인 UI 감지 시 대기 대신 안전 실패 처리
- 무진행 감시의 1회 개입과 Discord 채널 첫 응답 기한 감시
- Discord REST 수신 폴링을 대신하는 Gateway 연결과 시퀀스·재개 상태 저장
- DM·서버 채널·스레드의 정확한 바인딩과 기본 거부 권한
- 사용자 systemd 자동 시작, 단일 실행 잠금, 끊김 후 제한된 지수 백오프 재연결
- 중단된 작업 ID를 보존하면서
recovery_review로 표시하는 재부팅 복구
- Discord 안의 범위 제한 명령:
!naia status, !naia jobs, !naia job <id>
이렇게 요청하면 됩니다
Discord 세션 상태 보여줘
현재 백그라운드 작업 보여줘
job <id>가 지금 뭘 하는지 보여줘
job <id>를 실시간으로 지켜봐
완료를 뒷받침하는 테스트 결과 보여줘
스킬은 내부적으로 다음 명령을 사용합니다.
scripts/manage-discord-sessions.sh status [--json]
scripts/manage-discord-sessions.sh jobs [--active|--failed] [--json]
scripts/manage-discord-sessions.sh job <job-id> [--events] [--json]
scripts/manage-discord-sessions.sh watch [--job <job-id>] [--jsonl]
scripts/manage-discord-sessions.sh history --channel <channel-id> [--author <user-id>] [--limit 20] [--json]
scripts/manage-discord-sessions.sh latest --channel <channel-id> [--author <user-id>] [--json]
scripts/manage-discord-sessions.sh attachment --channel <channel-id> --message <message-id> --attachment <attachment-id> --output <absolute-path> [--expected-sha256 <hex>]
scripts/manage-discord-sessions.sh reply --channel <channel-id> --content-file <소유자 전용 절대 경로> [--json]
scripts/manage-discord-sessions.sh service install
scripts/manage-discord-sessions.sh service status
scripts/manage-discord-sessions.sh service restart
watch는 로컬 SQLite 기록만 읽습니다. Discord REST 수신 폴링이 아닙니다.
history와 latest는 운영자가 명시적으로 한 번 실행하는 읽기 전용 조회입니다. read 역할과 유일한 운영 바인딩이 있어야 하며 수신 폴링으로 사용하지 않습니다. attachment는 정확한 메시지와 Discord CDN, 크기, 선택한 SHA-256을 검증한 뒤 소유자 전용 파일만 만듭니다. reply는 reply 역할과 유일한 운영 바인딩을 확인하고, 소유자 전용 파일의 내용을 멘션 없이 한 번 전송합니다. 결과가 unknown이면 자동 재전송하지 않습니다.
상태를 읽는 방법
progressing: 최근 구조화된 활동 증거가 있음
running_no_detail: 소유한 프로세스는 살아 있지만 백엔드가 세부 진행을 제공하지 않음
waiting: 승인·대기열·재시도처럼 명확한 기다림
suspected_stalled: 활동 없음 제한을 넘긴 경고이며, 설정된 감시기가 한 번 개입해 running 표기만 남지 않게 함
unresponsive: 하드 제한이나 객관적인 프로세스 실패
unknown: 증거가 낡거나 없거나 서로 충돌함
not_applicable: 이미 끝난 작업이라 활동 상태를 적용하지 않음
최근 출력이 있다고 결과가 옳은 것은 아닙니다. 요구사항·빌드·테스트·리뷰 증거와 완료 주장을 따로 보여줍니다. AI가 스스로 “테스트 통과”라고 말한 것만으로는 검증 완료가 되지 않습니다.
설정과 복구 상태
naia-settings/messenger-sessions/config.json
naia-settings/.sessions/messenger-sessions/runtime.sqlite3
실제 설정과 세션 상태는 Git에 올리지 않습니다. 설정에는 비밀값이 아니라 자격 증명 참조만 둡니다. Discord 토큰은 naia-settings/.keys/messenger-sessions/<credentialRef>에 권한 0600으로 두며, 설정 파일도 0600이어야 합니다. backend.selected를 codex 또는 claude로 선택하면 되고 naia-agent나 naia-shell은 필요하지 않습니다.
사람의 권한 설정이 바뀌면 runtime.permissionProfileEpoch도 바꾸고, Discord에서 사람이 없이 처리할 작업은 runtime.approvalPolicy를 never로 둡니다. 복구나 대기열 실행 때 이전 자식의 명령 옵션을 재사용하지 않고 현재 프로필로 새 자식을 만듭니다. 바뀐 무승인 프로필은 이전의 보호된 수정 작업도 새 자식으로 교체할 수 있지만, 바뀌지 않은 수정 작업 복구는 계속 검토가 필요합니다. noProgressInterventionSeconds는 소유한 자식이 무진행일 때 한 번 중단시키는 한계이고, operatorResponseSeconds는 Discord 채널에 안전한 접수 응답을 보내거나 recovery_review로 넘기는 기한입니다. 자식의 작업 위치는 반드시 절대 실제 디렉터리여야 하고 cwd와 Codex의 --cd로 함께 전달되므로 상대 경로나 상위 도구의 작업 위치 설정은 거부합니다.
가시성과 재부팅 복구
서비스는 재부팅 뒤 터미널이나 과거 AI 세션 화면을 자동으로 열지 않습니다. 화면이 떠 있다는 사실은 실제 작업 상태의 증거가 아니기 때문입니다. 대신 다음 정보가 SQLite 안전 이벤트 기록에 남습니다.
status: 서비스가 실제로 살아 있는지, heartbeat가 신선한지, Gateway 재개 상태가 있는지
jobs, job <id> --events: 작업 단계, 최근 안전 활동, 자식 프로세스 소유권, 전송 상태, 대기·멈춤 의심 이유
completionAssessment: 요구사항·빌드·테스트·리뷰 증거. 활동 중이라는 것과 결과가 올바르다는 것을 분리해 보여줍니다.
실시간 확인은 watch --job <id> 또는 Discord의 !naia 명령을 사용합니다. watch는 로컬 SQLite만 읽으며 Discord 수신 폴링이 아닙니다. systemd journal에는 안전한 서비스 사유 코드만 남고 프롬프트, 모델 원문 출력, 최종 답변, 토큰, 명령, 로컬 경로는 저장하지 않습니다.
service.startAt=login이면 로그인 뒤, boot이면 설치기가 사용자 linger를 활성화해 부팅 때 복구를 시작합니다. 프롬프트는 소유자 전용 로컬 복구 키로 인증 암호화한 암호문만 저장합니다. recovery.autoRetry=true일 때도 읽기 전용·계획 모드 작업만 같은 작업 ID의 새 실행으로 이어집니다. 쓰기 가능 작업, 자동 재시도 비활성화, 키·암호문 손상은 recovery_review가 됩니다. Discord 전송 여부가 불확실한 답변은 자동 재전송하지 않습니다.
service install은 설치 터미널의 PATH에서 선택한 Codex 또는 Claude 실행파일을 찾습니다. Linux는 사용자 systemd unit에 고정합니다. Windows는 소유자 전용 실행 파일과 제한된 ONLOGON 예약 작업을 설치하며, 로컬 정책이 예약 작업 생성을 거부하면 소유자 전용 숨김 시작프로그램으로 자동 대체합니다. service status, start, stop, restart, enable, disable은 실제 설치된 등록 방식을 검증한 뒤 제어합니다. naia.cmd도 함께 설치됩니다. backend.selected를 바꾼 뒤에는 단순 재시작이 아니라 service install을 다시 실행해야 새 실행 경로가 고정됩니다.
백엔드 완료 판정은 닫힌 방식입니다. 공급자가 결과를 unknown으로 표시하거나 명시적 성공 근거가 없으면 성공으로 올리지 않고 Discord에도 전달하지 않습니다.
검증 명령은 pnpm test:discord-sessions입니다. 상세 설계는 docs/design/discord-session-observability.md, 요구사항은 DSO-001~DSO-007이 정본입니다.