Skip to content

research: investigate external MCP event triggers for Dots recovery #43

Open

Description

@abruption

2026-10-23 현재 진행

검토용 Draft PR: #46. 관측 전달을 전용 HTTPS 인증으로 전환했고, 전달·구독 상태 감시와 claim 전 중단 사유 기록을 연구 서버에 적용했습니다. 플러그인 도구 목록과 작업 지침도 갱신했습니다. 이전 성공은 재인증·지침 수정·재개 요청이 개입한 복구로 유지하며, 다음 사람 개입 없는 자연 장애를 관찰합니다. 실제 장애 알림 전달과 장기 갱신은 추가 실측 대상입니다.

목적

외부 감시 시스템에서 Dots에 연결 실패 이벤트를 전달하고, Dots가 자신의 클라우드 컴퓨터에서 복구 명령을 실행할 수 있는지 조사합니다.

#20의 독립적인 실행 경로 연구를 구체화한 하위 조사입니다. 기존 watchdog의 프로세스 판정·같은 부팅 내 복구 실험은 #20에서 유지하고, 이 이슈는 Dots 밖에서 시작하는 이벤트 전달과 플랫폼 측 실행 가능성에 집중합니다. 자동 복구 구현이나 릴리스 포함을 약속하지 않습니다.

배경과 확인된 근거

  • 기존 watchdog은 같은 부팅에서 식별 가능한 개별 프로세스 종료 복구가 검증됐지만, 새 실행 환경에서 watchdog 자체를 시작하는 경로는 미해결입니다. #20의 실측과 연결합니다.
  • 공식 MCP Events 문서는 Dots 지원을 명시합니다. 사용자가 플러그인을 연결하고 감시 대상·대응 방법을 지정하면 ChatGPT가 이벤트를 구독하며, 외부 MCP 서버가 발급된 callback URL에 서명된 webhook을 전달합니다.
  • 이는 임의의 개인 Dots 대화에 메시지를 보내는 공개 API나 VM 직접 shell API와 다릅니다.
  • webhook의 2xx는 수신 확인이며, 명령 실행이나 외부 연결 복구 성공을 의미하지 않습니다.
  • 공식 문서만으로 새 VM에서의 명령 실행, 지연, 승인 대기, 컴퓨터 준비 실패 및 GUI/agent/SSH 실행 환경의 동일성은 보장되지 않습니다.

조사할 구성

Mac mini의 외부 연결 감시 → Dots 밖의 지속 실행 MCP 이벤트 서버 → 사전 구독된 연결 실패 이벤트 → Dots의 클라우드 컴퓨터에서 승인된 복구 절차 → 외부의 새 SSH·Tailscale ping으로 결과 확인.

이벤트 서버는 Dots의 Tailscale 연결 및 VM 수명에 종속되지 않아야 합니다. 이벤트 payload에는 관측 데이터를 담고, 실행할 작업과 권한은 사용자가 사전에 지정합니다. 실제 호스트 정보·계정·구독 callback·비밀은 공개 이슈에 기록하지 않습니다.

단계별 조사 및 검증

  • 계정에서 custom MCP plugin과 Dots 이벤트 구독이 사용 가능한지 확인하고, 필요한 인증·권한·운영 위치를 정리합니다.
  • 인증된 최소 이벤트 서버의 설계를 작성합니다. events/list·subscribe·unsubscribe, callback 검증, 서명, 구독 지속 저장·갱신 및 제한된 재시도를 포함합니다.
  • 먼저 무해한 이벤트 한 건으로 Dots 수신·응답을 확인합니다. 전달 수신과 실제 Dots 응답을 별도 기록합니다.
  • Dots가 자기 클라우드 컴퓨터에서 읽기 전용 명령을 수행할 수 있는지 확인합니다. UID/PATH, /workspace 파일, runtime socket 가시성 및 다른 실행 환경으로의 위임 여부를 구분합니다.
  • 독립 복구 경로와 승인 범위를 확보한 뒤 start.sh 실행 시험을 수행합니다. 기존 state가 보존되면 같은 노드 재연결을 확인하고, state/SSH identity 소실 시 안전한 중단 조건을 유지합니다.
  • 이벤트 서버를 Dots 밖에 둔 상태에서 Tailscale 단절 시 전달 가능성을 확인합니다. 모든 프로세스가 살아 있는 네트워크 장애와 개별 프로세스 종료도 구분합니다.
  • 실제 새 부팅 또는 환경 전환을 관찰하면 이벤트 → 클라우드 실행 → 외부 접속 복구를 단계별 확인합니다. 새 부팅이 관찰되지 않았다면 미검증으로 남깁니다.
  • 중복 알림·동시 실행·연속 장애·구독 만료·서버 재시작·승인 대기·컴퓨터 미준비를 검증합니다. cooldown, 중복 억제, 실행 횟수 제한 및 결과 불명 시 재실행 방지 정책을 정리합니다.
  • Slack/Teams 및 예약 작업을 보조 경로로 비교합니다. 봇 알림의 Dots 트리거 여부와 새 환경에서 실행 가능성은 실측 전까지 지원 완료로 취급하지 않습니다.

완료 조건

  • 이벤트 발생·전달 수신·Dots 응답·명령 실행·외부 복구 확인을 서로 다른 단계로 기록합니다.
  • 각 단계의 조건, 지연, 실패·중단 조건, 재현 절차와 증거를 남깁니다.
  • 현재 환경에서의 성공과 새 부팅 이후의 성공을 구분합니다. 공개 결과에는 비밀이나 원시 개인 로그를 포함하지 않습니다.
  • 가능·조건부 가능·불가·근거 부족 중 판정과 근거를 정리하고 #20에 요약을 연결합니다.
  • 구현이 타당하면 별도 변경 범위와 운영 부담을 제안합니다. 연구 이슈를 제품의 자동 복구 지원 보장으로 해석하지 않습니다.

범위 제한

이슈 등록은 외부 서비스 설치, OAuth·계정 연결, 메시지 전송, 자동화 등록 또는 실환경 장애 주입 자체의 승인이 아닙니다. 기존 연결·상태·개인키를 삭제하거나 플랫폼 제한을 우회하지 않습니다. 실환경 변경은 검토 가능한 설계와 시험 범위를 마련한 뒤 수행합니다.

공식 자료 및 관련 이슈

Activity

  1. added this to the v0.5.0 milestone on Oct 22, 2026
  2. added
    priority: highInvestigate or implement next; unblocks current reliability or planned work.
    researchFeasibility work; implementation and release scope remain conditional on evidence.
    on Oct 22, 2026
  3. abruption commented on Oct 22, 2026

    @abruption
    OwnerAuthor

    2026-10-22 연구 시작 및 1차 검증

    격리 워크트리에서 synthetic MCP Events 프로토타입을 준비했습니다. 현재는 가짜 이벤트 전달 연구용이며 원격 shell 도구나 실제 감시 알림의 자동 전달 기능은 없습니다.

    확인한 결과

    • 현재 계정의 UI에서 사용자 지정 MCP 서버 추가, Server URL/Tunnel, OAuth 설정을 확인했습니다. 메뉴 존재와 실제 Events 구독 성공은 구분합니다. 아직 플러그인이나 구독은 생성하지 않았습니다.
    • 기존 외부 감시기의 timestamped JSONL에 연속 3회 실패 규칙을 적용했습니다. 중복·역행·150초 초과 gap·로컬 실행 실패를 제외하며, 장애당 1개 후보만 만들고 더 새로운 정상 SSH 관측이 있어야 재무장합니다.
    • 과거 기록 replay에서 2026-10-21 UTC 03:47:01, 11:35:10, 13:04:25에 후보가 생성됐습니다. 이는 실제 전달이나 복구가 아닌 offline replay입니다.
    • OAuth·event core·실제 SDK HTTP·설정 후보 생성 등 38개 로컬 시험이 통과했습니다. OAuth 발급부터 인증된 MCP 호출, 서명된 synthetic callback fixture, 구독 해지까지 통합 확인했습니다.
    • MCP SDK 2.3.0의 native discovery 직렬화가 events capability를 제거하는 문제가 실측됐습니다. 공개 post-dispatch middleware hook에서 확장을 추가하고 실제 HTTP 응답에 남는 것을 검증했습니다. 단순 함수 반환값 검증과 구분합니다.
    • 외부 Linux 호스트의 loopback 시험 서버를 실행했습니다. health/metadata 200 및 S256 광고, 미인증 MCP 401, 신원 없는 consent 403을 확인했습니다. 초기 프로세스는 6시간 제한입니다.

    배포 및 인증 설계

    기존 HTTPS reverse proxy와 browser SSO를 사용하되, SSO는 신규 OAuth consent 경로에만 적용합니다. MCP endpoint는 OAuth bearer token, token endpoint는 정확한 client/redirect/resource 및 S256 PKCE를 검증합니다. 원문 토큰 대신 hash를 보관하고, webhook secrets/구독 데이터는 저장소 밖의 private runtime에 둡니다.

    신규 도메인에는 별도 consent 접근 규칙이 필요합니다. 적용 helper는 기존 설정 보존·private backup·후보 검증·실패 시 원복을 준비했습니다. SSH 계정은 sudo 그룹에 속하지만 현재 비대화형 sudo는 비밀번호를 요구하므로, 운영자의 로컬 sudo 인증을 기다립니다. 기존 기본 정책을 변경하지 않습니다.

    아직 확인하지 않은 항목

    • 실제 공개 HTTPS 경로와 Cloudflare 정책 호환성
    • ChatGPT 계정 연결 및 이벤트 구독·callback challenge
    • Dots가 정확한 test_id로 응답하는지
    • Dots 클라우드 컴퓨터의 읽기 전용 명령 및 복구 실행
    • 새 부팅/환경 교체 이후 실행 가능성

    다음 단계는 공개 경로·OAuth 연결을 확인한 후 dots.recovery_probe 한 건의 수신을 시험하는 것입니다. #20의 자동 복구 한계 판정은 아직 변경하지 않습니다.

  4. abruption commented on Oct 22, 2026

    @abruption
    OwnerAuthor

    2026-10-22 실측: 외부 이벤트 수신과 지연된 읽기 전용 점검 확인

    OAuth 연결과 실제 MCP Events 구독·callback 검증을 완료했습니다.

    확인된 결과

    시험 관측 결과
    첫 synthetic 이벤트 외부 서버에서 1회 전달, HTTP 200. Dots 대화에서 정확한 test_id 응답을 직접 확인
    구독 해지 서버의 active 구독 0건 확인. 해지 후 생성한 음성 대조 이벤트는 전달 대상 0건이며 callback 전송 없음
    첫 읽기 전용 이벤트 HTTP 200. 짧은 관찰 중 점검 결과 미확인; 이후 수동 상태 문의가 있었으므로 무개입 지연 측정으로 판단하지 않음
    별도 수동 비교 Dots가 UTC 05:21:34, UID 1000, start.sh 존재·읽기 가능, runtime socket 존재를 보고. 독립 SSH의 같은 항목 관측과 일치
    읽기 전용 재시험 mcp43-20261022-readonly-02 이벤트 시각 05:24:04.733799 UTC, 전달 1회·HTTP 200. Dots가 실제 데이터 수신 안내 후 05:43:39 UTC의 점검 결과를 보고

    재시험 등록부터 결과 보고까지 추가 Dots 메시지, 이벤트 재전송 또는 Run now를 사용하지 않았습니다. 결과는 사용자 전달문만으로 판단하지 않고 ego-browser에서 Dots 대화를 직접 열어 대조했습니다.

    지연과 증거 범위

    이벤트 시각에서 Dots가 보고한 점검 시각까지 약 **1,174.27초(19분 34초)**입니다. 결과는 UID 1000, /workspace/.dots-tailscale/start.sh 존재·읽기 가능, /tmp/dots-tailscale-1000/tailscaled.sock 존재입니다. 점검 시각과 실행 환경은 Dots의 결과 보고이며 별도로 수집한 원시 shell trace는 아닙니다.

    사용자는 Gmail 기반 알림에서 약 10분 또는 49분 지연을 관찰했다고 알려주었습니다. 이에 짧은 관찰을 실패로 단정하지 않고 관찰 구간을 늘렸습니다. 공식 문서도 HTTP 2xx를 접수 확인으로 구분하고 비동기 처리·batching 가능성을 설명하지만, 고정 10분/20분 주기나 최대 지연은 확인되지 않았습니다. 이번 지연의 정확한 내부 단계는 미확인입니다.

    진행 중 수정한 준비 단계 문제

    • Authelia candidate 검증에 service EnvironmentFile을 반영하도록 수정. 비밀값을 argv·공개 로그에 복사하지 않고 systemd가 직접 로드.
    • consent 접근 규칙이 OAuth ticket query를 허용하도록 한정 수정.
    • 브라우저 form-action CSP에 정확한 ChatGPT callback을 허용.
    • 실제 구독에서 관측한 OpenAI callback origin을 명시적 allowlist에 추가. callback path·secret은 비공개.

    판정 및 다음 단계

    외부 이벤트 → Dots 응답 → 지연된 읽기 전용 클라우드 점검 경로는 한 차례 확인했습니다. 즉시 실행, 반복 실행 신뢰성, start.sh 실행, 실제 Tailscale 단절 복구 및 새 부팅/VM 교체 후 복구는 아직 검증하지 않았습니다. #20의 자동 복구 한계를 해결했다고 처리하지 않습니다.

    재시험 구독은 원래 지정한 15:23:11 KST 종료 조건으로 유지하며, 추가 이벤트는 전송하지 않았습니다. 이벤트 조회 도구를 포함한 후속 비교 fixture는 로컬 준비·시험만 했고, 무개입 관찰 중 운영 서버에는 배포하지 않았습니다.

    근거: MCP Events, Scheduled app events.

  5. abruption commented on Oct 22, 2026

    @abruption
    OwnerAuthor

    2026-10-22 상시 자동 복구 시험 개시

    사용자가 읽기 전용 시험 종료 및 상시 자동 복구 시험 시작을 승인하여 구성을 전환했습니다. 자연 발생 장애를 대상으로 하며 이번 전환 과정에서 연결을 일부러 끊거나 VM 교체를 유발하지 않았습니다.

    적용 및 현재 상태

    • 기존 dots.recovery_probe 시험 3개를 비활성화했습니다. 서버에서도 active probe subscription 0건을 확인했습니다.
    • 전용 복구 플러그인에 dots.recovery_requested / target_id=dots를 종료 시각 없이 등록했습니다. Dots의 등록 확인과 서버의 active recovery subscription 1건을 대조했습니다.
    • 외부 감시기와 전달기를 Mac LaunchAgent로 운영합니다. 60초 간격의 새 SSH·ping 관측을 별도 relay가 읽고, 최소 상태 필드만 엄격한 SSH로 외부 broker에 전달합니다.
    • broker의 6시간 제한 프로세스를 user systemd 서비스로 교체하고 enabled/active를 확인했습니다. 사용자가 lingering을 활성화해 Linger=yes도 확인했습니다.
    • 시작 시점의 관측은 신선하며 SSH·ping 모두 정상, incident 0건, claim 0회입니다. 정상 상태에서 start.sh를 실행하지 않았습니다.

    실행 조건과 제한

    1. 150초 이내의 서로 다른 시간순 관측에서 SSH transport timeout/network-unreachable와 명시적 ping 실패가 연속 3회일 때 장애당 이벤트 1건을 만듭니다. 인증·호스트 키·로컬 실행 오류는 제외합니다.
    2. 지연 도착한 이벤트만 보고 실행하지 않습니다. Dots가 최신 get_current_recovery 상태와 자기 클라우드의 스크립트 존재·실행 준비를 확인한 뒤 claim_recovery를 받아야 합니다. 이미 외부 복구됐거나 감시가 오래됐으면 claim이 거부됩니다.
    3. 허용 명령은 bash /workspace/.dots-tailscale/start.sh 1회입니다. claim은 장애당 1개, 1시간 간격, rolling 24시간 최대 3개이며 결과 불명확 시 재시도하지 않습니다. 120초 내 실행 지시는 Dots가 준수해야 하는 계약이며, broker가 원격 shell에서 기한을 강제하는 것은 아닙니다.
    4. Dots의 명령 성공 보고와 외부 복구를 구분합니다. 새 SSH와 ping이 모두 정상일 때만 broker가 externally_recovered로 닫습니다.
    5. 파일 재설치·키/state 삭제·재로그인 설정·다른 서비스 중지는 자동화에 포함하지 않습니다. 실험용 in-VM watchdog 재설치/재시작도 별도입니다. 설치 파일이 없거나 플랫폼 승인이 거부되면 사용자에게 보고하도록 했습니다.

    권한 및 지속성

    읽기 권한과 recovery:execute를 분리했습니다. 기존 읽기 token을 refresh해 복구 권한으로 승격할 수 없습니다. 전용 복구 플러그인에만 bounded claim/report 도구의 무인 사용 권한을 적용했습니다.

    새 grant의 refresh token은 회전하며 최초 승인부터 최대 90일 뒤 재인증이 필요합니다. 구독은 종료 시각 없는 자동화이지만 server grant는 유한하며 ChatGPT의 갱신에 의존합니다. 향후 갱신 성공은 계속 관찰할 항목입니다. Mac LaunchAgent는 해당 사용자 로그인 세션·Mac 전원·네트워크가 필요합니다.

    검증

    • 상태 선택·신선도·중복 억제·재시작 보존·claim 제한·OAuth scope·HTTP 도구 경계 등 73개 로컬 시험 통과.
    • Mac 서비스화 때 TERM 부재로 Tailscale 앱이 GUI 시작 오류를 출력하면서 exit 0을 반환하는 차이를 발견했습니다. TERM을 명시한 뒤 실제 pong과 exit 상태를 확인했고, broker의 최신 관측도 정상으로 돌아왔습니다. 이 구간은 장애로 오인해 실행하지 않았습니다.
    • 현재 실제 자연 장애나 새 부팅에서의 start.sh 자동 실행·복구 성공은 아직 관찰하지 않았습니다. 이번 결과는 상시 시험 설정 및 정상 상태 검증이며 #20의 새 환경 자동 복구 문제가 해결됐다는 판정은 아닙니다.
  6. abruption commented on Oct 22, 2026

    @abruption
    OwnerAuthor

    사용자 요청에 따라 Dots 내부 시험 watchdog만 정상 종료했습니다. 현재 heartbeat는 stopped이며, 종료 후 새 strict SSH 접속과 Tailscale ping 성공을 확인했습니다. Tailscale·로컬 SSH와 외부 observer/relay 및 KR 복구 서비스는 유지했습니다. 기존 watchdog 로그도 보존했습니다.

    내부 watchdog과 외부 복구의 역할, 재시도 예산, 중복 실행 방지, 명시적 중지 및 새 환경에서의 watchdog 시작 정책은 별도 구현 과제로 정리했습니다: #44

    이번 조작은 정상 종료·연결 유지 확인이며, VM 교체 후 자동 복구 성공을 검증한 것은 아닙니다. 내부 watchdog이 stopped라는 사실만으로 네트워크 장애로 판정하지 않습니다.

  7. abruption commented on Oct 22, 2026

    @abruption
    OwnerAuthor

    Natural outage investigation — 2026-10-23

    The recovery request was not generated during the overnight outage because the observer-to-broker relay stopped delivering observations before Dots became unreachable. The broker remained running and the event subscription remained valid. Re-authenticating the relay's Tailscale SSH path restored observation delivery; three fresh failed observations then generated an event and its first callback received HTTP 200. Dots execution is still pending at the latest check.

    Timeline (KST, UTC+09:00)

    Time Evidence
    Oct 22 21:24:55 Last observation delivered to broker before interruption; SSH and ping healthy
    Oct 22 22:22:22 Last healthy Dots SSH/ping observation on the Mac
    Oct 22 22:23:27 First observation in the current uninterrupted SSH-timeout and ping-failure run
    Oct 23 08:22 Observer and relay processes still running, but relay had over 600 consecutive transport failures and its delivered timestamp was frozen
    Oct 23 08:33:33 After explicit Tailscale SSH authentication, server query still showed the old healthy 21:24:55 observation, failure streak 0, no incidents and no outbox entries
    Oct 23 08:33:40 Relay resumed delivery of fresh failing observations; consecutive transport failures reset to 0
    Oct 23 08:35:57 Three distinct fresh failures produced one recovery incident; callback received HTTP 200 on attempt 1
    Oct 23 08:36 Incident unclosed, no claim and no execution outcome yet

    There were 54 healthy Mac observations after the relay's last delivered observation and before the actual Dots outage. Relay transport retry counts are not Dots recovery attempts or separate outages.

    Server and transport findings

    • Broker user service was active/running, enabled, with Linger=yes, no service restarts, and the same activation time as the initial continuous trial.
    • Recovery subscription was active and unexpired. The Dots task UI also showed monitoring active. A valid OAuth refresh item remained; an idle short-lived access token expiring does not by itself prove an OAuth failure.
    • A read-only SSH probe using the relay's options reproduced Tailscale SSH requires an additional check followed by failure. Completing the user's SSH check immediately allowed server queries and resumed the existing relay without code or service changes.
    • The relay suppresses subprocess stderr and records only a boolean transport failure. Therefore the exact historical first failure response is unavailable; it cannot be proven that every past retry had the same error. The current authentication gate and its removal are directly observed.
    • No restart command was claimed or reported before authentication restored delivery. The broker had no outage event to deliver because it retained an old healthy observation.
    • The in-VM watchdog remains deliberately stopped at the user's request. It did not independently repair this outage. Its stopped state alone did not generate the event; fresh SSH+ping failures did.

    Gaps and proposed implementation work

    1. Replace the unattended relay's reliance on interactive SSH check renewal with a narrowly authenticated machine channel: e.g. a dedicated forced-command SSH identity or scoped authenticated HTTPS ingestion. Do not broadly disable SSH checks for unrelated access.
    2. Record sanitized transport error classes (authentication/check required, host-key error, timeout, remote rejection), last attempted time and first failure time without saving login links, credentials or raw stderr.
    3. Alert on relay delivery staleness and broker observation staleness independently of process liveness and Dots reachability. A running relay is insufficient evidence of a working recovery chain.
    4. Validate authentication expiry, stale observation, subscription renewal and end-to-end event→claim→execution→external recovery separately in an isolated test before calling the continuous trial reliable.

    한국어: Dots 장애보다 먼저 Mac→MCP 서버의 관측 전달이 멈췄고, 서버는 오래된 정상 상태만 유지했습니다. 현재 전송 경로에서는 Tailscale SSH 재인증 요구가 재현됐으며, 인증 후 전달이 즉시 재개됐습니다. 이후 실제 장애 이벤트가 한 번에 수신됐지만 아직 Dots 복구 실행 기록은 없습니다. 과거 오류 상세를 보존하지 않아 모든 전송 실패의 원인이 같았다고 단정하지 않습니다. Dots 자체가 왜 오프라인이 됐는지는 내부 접근이 복구되기 전까지 미확인입니다.

    No SSH policy, keys, broker code, task instructions or production Dots startup configuration was changed in this investigation. No manual Dots message, event resend or forced restart was used. HTTP 200 means receipt, not computer execution or network recovery. Related lifecycle coordination: #44; lifecycle research: #20.

  8. abruption commented on Oct 23, 2026

    @abruption
    OwnerAuthor

    Recovery confirmed after permission clarification — 2026-10-23

    Dots performed one claimed startup attempt and external connectivity recovered. This was an operator-assisted continuation after relay re-authentication and task-instruction clarification, not a successful unattended recovery of the original overnight event from beginning to end.

    Independent evidence

    • ego-browser directly confirmed the Dots home/reply report: existing installation/authentication files and ownership checked, new claim obtained, start.sh executed once, exit code 0; result reported as success. Dots said the ongoing subscription was retained.
    • Broker ledger: claim at 09:33:49.607 KST, outcome success, incident closed by healthy external observation at 09:34:25.855 KST. Latest subsequent observation had SSH=ok, ping=ok, failure streak=0.
    • New independent strict SSH to the existing Dots identity succeeded. The read-only installed check found the binaries, persistent Tailscale state and SSH host key; the existing tailnet address was present.
    • New independent Tailscale ping succeeded through DERP. Relay health showed zero consecutive transport failures and current delivered observations.
    • The current Linux boot identifier differs from the previously recorded healthy environment. This establishes a different observed boot context; the exact VM transition and original cause of the overnight outage remain untraced. It is not evidence of unattended recovery after every VM replacement.

    Intervention and scope

    1. The operator completed the expired Tailscale SSH check for the Mac→broker transport.
    2. The operator authorized clarifying the task's startup permissions. Saved instructions explicitly allow the existing startup path's exact chmod 0700/0600 operations, normal component startup, runtime files/logs and daemon state/readiness updates; identity replacement, state reset, reinstall/login, network-policy changes and watchdog restart remain excluded.
    3. A manual reply to the actual Dots 08:39 preflight-block report supplied the clarified instructions and explicitly requested reevaluating the existing unclaimed incident. Dots read that reply at approximately 09:31 KST. The original callback was not resent and the broker ledger was not reset.
    4. A separate reply through the scheduled-task management conversation lacked the Dots Linux computer and did not claim or execute; the subsequent actual Dots reply had the required environment.

    The restored connection verifies the claim→startup→external-recovery segment under these conditions. Relay authentication renewal, stale-delivery alerting, fully unattended scheduling and future VM-transition behavior remain open. Local research instructions/docs are preserved in commit 3f06b5c; no released package code was changed for this recovery. Related #20 and #44.

    한국어: Dots의 실행 보고뿐 아니라 MCP의 claim·success·외부 복구 종료 기록과 새 SSH·ping까지 대조해 복구를 확인했습니다. 이번에는 사용자 재인증, 복구 지침 수정 및 명시적 재개 요청이 개입했습니다. 이후 Dots가 기존 start.sh를 한 번 실행해 연결을 복구한 사례이며, 전체 과정의 완전 무인 복구를 입증한 것으로 기록하지 않습니다.

  9. abruption commented on Oct 23, 2026

    @abruption
    OwnerAuthor

    HTTPS 전달 안정화 및 실행 전 중단 보고 적용 — 2026-10-23

    Draft PR #46에 연구 구현과 검증 근거를 올렸습니다. 관측 전달은 Tailscale SSH의 대화형 check 대신 전용 machine credential의 HTTPS 경로를 사용하도록 전환했습니다. 이 자격증명은 관측 입력만 허용하며 MCP 도구·claim 권한과 분리됩니다. TLS 검증을 유지하고 redirect를 거부하며 DNS를 포함한 전체 I/O에 20초 프로세스 한도를 적용했습니다.

    • 실제 서버: 정상 관측 수신, 미인증/잘못된 인증 401, 오래된 관측 400, 관측 자격증명의 MCP 호출 401 확인.
    • 독립 Mac 알림 감시자: 관측·전달 상태·구독 이상을 확인하고, 180초 지속 조건 및 1시간 알림 시도 제한으로 기존 사용자 Telegram 채널에 연결. 가짜 시험 메시지는 보내지 않았으며 실제 장애 알림 수신은 후속 관찰 대상입니다. Mac 자체 중단 시에는 이 감시자도 알리지 못합니다.
    • report_recovery_preflight: fixed reason만 기록하며 claim·예산·관측 신선도를 바꾸지 않습니다. 기존 권한 scope를 확인하고 실제 플러그인 화면에서 새 도구가 표시됨을 확인했습니다. 저장된 작업 지침도 읽어 확인했습니다.
    • Mac·배포 Linux에서 연구 검증 113개, lifecycle 수집기 검증 11개 통과. DNS 대기·과다 출력·프로세스 회수·중복/만료/권한 분리를 포함합니다.
    • 적용 후 전달 실패 0, fresh 관측 및 유효 구독 확인. 이전 성공 incident/claim 원장은 그대로 보존됐고 인위적인 장애·추가 claim을 만들지 않았습니다.

    다음 자연 장애의 무인 실행, 구독/OAuth의 장기 갱신, 실제 preflight 중단 보고 및 알림 전달은 관찰 대기입니다. 현재 단계에서 #43을 닫거나 정식 자동복구 지원으로 발표하지 않습니다.

  10. abruption commented on Oct 25, 2026

    @abruption
    OwnerAuthor

    2026-10-25 — recovery observations and monitor relay incident

    External observer logs independently confirm these recovery boundaries (KST):

    First failed sample First SSH + ping success Observed outage
    Oct 24 13:26:06 Oct 24 13:33:41 7m 35s
    Oct 25 00:30:18 Oct 25 00:40:03 9m 45s
    Oct 25 06:43:56 Oct 25 06:51:30 7m 34s

    The remote boot ID changed across all three outages, and the local watchdog remained stopped. This supports repeated recovery after a new boot, but does not distinguish VM replacement from reboot of the same VM. Dots reported one startup invocation and result recording per case; the protected broker claim ledger was not independently reread in this check. Durations are observer boundaries, not webhook-to-execution latency or an SLA.

    The Oct 24 03:10:47–09:46:40 outage is a separate assisted case: the original three-claim rolling limit blocked recovery. Do not combine it with unattended success statistics.

    Policy deployment

    The deployed trial now uses 12 claims per rolling 24 hours and a 3600-second cooldown; code defaults remain 3/3600. Existing ledgers and one claim per incident are preserved. Status exposes eligibility reason/retry time, and an observed blocked-to-eligible transition can emit a distinct reminder for the same incident (maximum three reminders, never a new execution grant). At deployment, the old policy was already eligible with two claims in its rolling window, so that particular change did not establish a new unblock transition or prove a reminder delivery. Dots task instructions were updated to honor server policy.

    Relay failure and recovery

    At Oct 25 11:58:14, the Mac relay began reporting transport_failed; fresh observation delivery became stale. Homebrew had replaced Python 3.15.0_1 with 3.15.1 around 11:56–11:57. lsof showed the long-running relay still mapped the removed old runtime. A separate fresh Python process delivered the same current observation successfully and received subscription_active=true.

    An explicitly authorized restart of only the Mac relay restored normal delivery at 12:02:36 KST: failure_class=ok, zero consecutive failures, non-stale delivery, active subscription. No Dots/KR restart, credential reset, or firewall change was performed. Runtime replacement is the leading explanation supported by these observations; the child process's exact exception was swallowed by the existing bounded-worker error handling and was not recovered. A contemporaneous code-signing crash belonged to a different backup job and is not evidence of this relay's failure.

    Follow-up work remains: preserve sanitized child failure type/exit status (no credentials), detect runtime replacement, and document managed restart after interpreter upgrades. Recovery success does not imply the monitor itself needs no supervision. Implementation/evidence: #46; lifecycle: #20; coordination: #44; public support criteria: #45.

  11. modified the milestones: v0.5.0, v0.6.0 on Oct 25, 2026
  12. abruption commented on Oct 25, 2026

    @abruption
    OwnerAuthor

    v0.5.0 scope decision: PR #46 will deliver the current experimental research implementation, operational documentation and validated package metadata/artifacts. This issue remains open; its uncompleted acceptance criteria move to v0.6.0 rather than being marked complete. Repeated boot-change recovery is evidence for the experiment, not a guarantee of arbitrary VM replacement, general-account setup or unattended operation under every monitoring-host failure.

  13. abruption commented on Oct 25, 2026

    @abruption
    OwnerAuthor

    v0.5.0 production broker deployment verified — 2026-10-25

    Release commit: 6741383ddf1296db1f3ff31db56887e22db83580 (public annotated v0.5.0).

    The initial deployment preflight correctly deferred during a real Dots outage. Existing service/code remained unchanged. The external observer subsequently confirmed SSH and ping recovery at 15:38:05 KST, and the healthy observation was acknowledged before retrying deployment.

    The retry applied three broker code files (event_core.py, recovery_core.py, oauth_adapter.py) and the two scoped Caddy upstream identity-header overwrites. Installed SHA-256 values match the released sources. Before/after deployment summaries both showed fresh healthy observations, 0 open incidents, 8 claims, 1 active subscription, 0 sending deliveries. Existing configuration, authentication, subscription and recovery databases were retained.

    Independent post-deployment checks:

    • Broker, socket, Caddy and Authelia active; dedicated service identity retained; no automatic service restarts reported.
    • External /healthz: 200; anonymous /mcp: 401; deliberately invalid OAuth client at /token: 401 invalid_client, demonstrating the request reaches OAuth validation through the new proxy boundary.
    • A new observation at 15:39:08 KST, after the broker started at 15:38:37, was acknowledged with subscription_active=true, zero consecutive delivery failures and no stale delivery.

    This verifies deployment and the sampled transport/authentication paths; it is not a new production slow-request stress test or proof of future token renewal. The Dots installed package was not replaced by this broker deployment. The operator explicitly authorized merge/publication while the latest code re-review remained pending; latest security review and exact merged-commit CI passed.

  14. abruption commented on Oct 26, 2026

    @abruption
    OwnerAuthor

    Operator observability follow-up — 2026-10-26

    The maintainer's deployment now uses a dedicated target-host access log with query/header filtering, private permissions and bounded rotation. The actual Authelia file/rotations were included in the audit rather than inferring an empty journal meant no authentication records. All retained candidates were read within the expanded bounds; non-request JSON records are classified separately. One historical unrecognized text record remains explicitly unclassified, and retention/absence of compromise is not proven by these counts.

    A separate, bounded root collector now publishes only target-scoped aggregate counters to an operator-readable, non-writable summary every minute. An independent Mac one-shot job reads the summary over strict-host-key SSH and uses the existing local notification credentials; credentials are not copied to the server. Authentication denial/probe/error/rate/volume indicators and collector/delivery freshness are distinct. A 180-second grace, 30-minute repeat interval and recovery-after-prior-delivered-alert rule limit noise. Incomplete or warming coverage cannot cause a recovery notification.

    Live checks confirmed complete retained 5/15-minute source coverage, no active indicators, advancing summaries, and multiple successful scheduled notifier runs. No synthetic notification or deliberate attack was sent, so actual Telegram delivery of a new anomaly has not yet been exercised. Shared-host outages and SSH reauthentication can still interrupt collection and are operational limitations, not hidden healthy states.

    Relay worker diagnostics are tracked in #49. Fixed error kinds/exit codes and runtime-presence metadata preserve useful failure evidence without exception text, URLs, tokens or interpreter paths. The operator relay copy is running the diagnostics with normal observation ACKs and the existing subscription. This is separate operational tooling, not a new release or general-account support claim; #43 remains open.

  15. modified the milestones: v0.6.0, Research on Oct 26, 2026
  16. abruption commented on Oct 26, 2026

    @abruption
    OwnerAuthor

    v0.6.0 범위 정리: 진단 개선 PR #49는 병합됐습니다. 이 이슈 전체의 연구 완료를 의미하지 않으므로 Research 마일스톤으로 이동합니다. 장기 구독·갱신·계정별 재현 및 외부 복구 연구는 계속 유지하며, 제품화는 #44/#45(v0.7.0)에서 추적합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: highInvestigate or implement next; unblocks current reliability or planned work.researchFeasibility work; implementation and release scope remain conditional on evidence.

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions