feat(msgr): 크루 브리지(P1-S2) — 조직 채널 멘션·DM → 크루 턴, 결재 카드 미러, 등록 API (스택: #419 위) - #421
Open
beyondworks wants to merge 62 commits into
Open
feat(msgr): 크루 브리지(P1-S2) — 조직 채널 멘션·DM → 크루 턴, 결재 카드 미러, 등록 API (스택: #419 위)#421beyondworks wants to merge 62 commits into
beyondworks wants to merge 62 commits into
Conversation
beyondworks
force-pushed
the
feat/msgr-bridge
branch
from
September 3, 2026 05:07
617dc5f to
ddc07e1
Compare
…러) + 등록 API
- src/gateway/msgr.mjs: makeDb(supabase-js 체인 단일 층)·drain(허용 범위 게이트·만료 폐기·적재 후 커서 전진·결재 결정 큐 우회 반영)·makeMsgrHandler(채널 접두·발화자 귀속·첨부 내려받기·journal 정책·client_msg_id 멱등 답글·산출물 업로드·부재중 접두)·msgrPush(결재 카드 미러·웹 확정 동기화·후속 보고·위임 미러)·startMsgrBridge(15s 폴 + Realtime private topic 깨우기)
- gateway.mjs 접합 4지점(qkeys·핸들러·리더 전용 폴러·pushEvent 머리), channel-events msgr 등재, chat() journal {off,tag}(세 saveHandover 지점을 journalWrite 하나로), memory.saveHandover tag=별도 일지 파일(회수 단위), thread.appendTurn actor, approvals resolvedBy
- app/api/companies/[ws]/msgr: 기기 세션으로 msgr_crews 등록/해제/조회, company.json.msgr.enabled 동기화
- 테스트: msgr-bridge.test 8건(가짜 db·chat 주입, 배선 구간 불변식), 의도된 핀 갱신 2건(예산 분기 journalRel 조건부·402 일지 제외는 journalWrite 경유)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…altime·중복·허용 범위·결재 미러 왕복 23건 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…곳 전파, 결재 항목에 msgr 문맥 각인(동시 턴 오배달 차단), 제3자 발화 프레이밍·이름 세척, 음소거 배선, 부재중 판정=큐 대기, 위임 미러 멱등 키, 조직 태그 일지 정제 제외, 라우트 문구 코드화·uuid 검증·본인 필터 - HIGH-1: 답글·첨부 insert를 try/catch로 종결(던지면 유료 턴이 초당 1회 재실행) · HIGH-2: chat() 재귀 6곳·위임·makeCrewServer에 journal 전파 + 핀 · HIGH-3: addApproval 3곳(request_approval·profile·hire)이 mirrorCtx를 item.msgr로 각인, msgrPush는 각인 우선·활성 문맥 CAS 폴백 · HIGH-4: 채널 텍스트를 제3자 발화 프레임으로, 채널명·이름 세척(개행·길이) - MEDIUM: 활동 이벤트 오표시 제거, myOrgs 본인 필터, 부재중=큐 대기 시간, company.json.msgr.mutedEvents 음소거(channelSends), apimsg 코드 3종(PG 원문은 로그), consolidate 일별·주간 롤업에서 org 태그 일지 제외, DM 소유자 멤버십 계약·기억 옵션 범위 문구 - LOW: 위임 미러 client_msg_id(sha1), rtChannels 회사별 키, 첨부 25MB 상한·mime 기록, syncEnabled 일시 오류 시 유지, 틱 중복 조회 제거 - 잔여(의도): 등록 기본 allow='all'은 사용자 결정(설계 T6에 위험 기재), 상주 노드 로그인 절차는 별도 스토리 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…인(OTP·개발용 비밀번호)·조직/초대·채널·메시지·@멘션·첨부·결재 카드·크루 부재중·타이핑, Tauri 2 셸 + 로컬 스택 개발 시드 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Owner
Author
|
분리 검수(HIGH 4·MEDIUM 8·LOW) 반영 커밋 푸시. 근거: |
beyondworks
force-pushed
the
feat/msgr-bridge
branch
from
September 3, 2026 05:27
ddc07e1 to
57ec4ff
Compare
…크립트(~/.argo/msgr-local-stack) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… 브리지 스크립트(가짜 러너로 멘션 응답, 개발 전용) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…이트, argo-theme 공유)·LanguageProvider·Icon/Avatar/Markdown/DropUp 재사용, 사이드바·nav-item·필 버튼·입력바·말풍선·호버 액션·fade-up 동일 규칙, Pretendard 동봉(심링크) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…vider defaultTheme(메신저 기본 linen), 동기 테스트 일반화 - globals.css: linen / @media dark / linen-light / linen-dark 4블록을 apps/messenger/design/tokens.css에서 생성. .side·.msgr-composer 차콜 스코프(토큰 재정의). :root에 --mark 가족·--shadow-float 기본값 - theme.jsx THEMES·defaultTheme prop, i18n family/theme 라벨, 설정 FAMILIES·THEME_SWATCHES - test/helpers/theme-family.mjs(그래파이트 테스트 일반화) + theme-linen-sync(옐로는 --mark에만·라이트 차콜 레일) + theme-boot-default(부트 폴백 == Provider 기본값) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…/비소유자)·세그먼트 탭·자체 아이콘 스프라이트 - styles.css: 시안 v2(design/system-v2.css)를 .msgr-* 로 이식, 색 평문 0(토큰만) - App.jsx: 채널 칩 랩(+N 접힘)·크루 카드·멤버 스택·척추 스레드(날짜 노드)·결재 슬립 4상태·빈 상태 단계·폰 레일 오버레이 - icons.jsx 21종, i18n +40키(ko/en) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… 분리 평가 v1 8.6·v2 8.6 통과, 유건 승인 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…자 미상 시 버튼(M1), 결재 탭 배지/필터 모수 통일(M2), 멘션 앞 경계(M4), 하드코딩 폴백 i18n(L1), 죽은 키·아이콘 제거, THEMES 파싱 배열 구간 한정(L6), 탭 role, Esc 레일 닫기, README를 공개용(시안 사용법·토큰·모티프)으로 축소(M3 — 검수 로그는 내부 문서로) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…한 스크롤바 폭(--sbw)으로 (유건 실검수) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…), 입력창 아래 단축키 안내 제거 — 유건 실검수 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…AUDE_CONFIG_DIR 회사별 폴더 + ENABLE_TOOL_SEARCH=false 실측 2026-09-03(메신저 실러너 E2E): 호스트 ~/.claude 로그인이 보이면 CLI가 제3자 base 요청의 인증 헤더를 빼 190초 뒤 401(→ '인증 실패' 오분류·폴백), CLI 2.1 기본 도구 검색은 비 Anthropic 엔드포인트에서 400. 같은 키 curl은 200. claude 본가·host 옵트인은 불변. + scripts/msgr-real-bridge.mjs·msgr-real-send.mjs: 실러너(OpenRouter 무료 모델·Claude host) 메신저 E2E 드라이버(개발 전용, 키는 env) + test/compat-runner-sdk-isolation(변이 3종 red) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…유자만 편집·RLS) + 멤버의 '허용 요청'(소유자 멘션 메시지); 본문에 직접 친 @이름도 멘션으로 인식; 요청 직후 스레드 즉시 갱신 — 유건 실검수 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…정 멤버/나만, 기본 '나만')·브리지 상태; 라우트 GET에 조직별 멤버, POST 기본 allow='owner' 계획 정본 부록 F1-1·H(정책 테이블 전까지 가장 좁게). 실측: 소유자 기기 세션 루트의 격리 Argo(:3131)에서 등록→지정 멤버 선택→해제가 로컬 Supabase msgr_crews에 반영. 핀: test/msgr-settings-card(배선·기본값·i18n ko/en) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…채널 사람/크루 추가·내보내기(크루=소유자 동반), 보관; 멤버 스택·크루 시트에서 1:1 대화(사람·크루, 기존 DM 재사용), 레일 1:1 그룹; 설정 카드 제목 줄바꿈 정리 실측(로컬 스택·실러너): 민수↔서윤 DM에서 @ 없이 실답변(OpenRouter), 소유자가 marketing 주제 편집·기억 끔(DB f), 비공개 채널 생성→민수·준 추가(소유자 동반)→민수 레일에 노출 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…안내(F1-5) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…HIGH-1), 크루 무멘션 트리거를 DM만으로(HIGH-2), 크루 소유자 내보내기 차단(HIGH-3), DM 재사용을 참가자 집합으로(HIGH-4), allow_users 조회(HIGH-5), 좌석 셈법=서버(게스트 포함), DM 라벨=나 아닌 참가자, 1:1 버튼은 시킬 수 있을 때만, 스택 겹침 셀렉터, 채널 한도 안내, DM 멤버 정책(생성자·관리자만 쓰기, 참가자는 나가기만)+구성 상한 트리거, 핀 키 수집기 대소문자 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…참가자 끼워넣기·축출 거절, 나가기 허용, msgr_dm_full), 시트 닫기 효과 deps 구간 핀; dm_shape advisory lock, 관리자 조항 DM 제외, loadOrg의 채널 선택을 보조 조회보다 먼저 (변이 3종 red 실증) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…·잠금 sweep·감사, 관리자 정책 카드, 시트·아르고 등록 카드 잠금 표시; 메신저 로그아웃을 기기 범위로
- 스키마: 조직당 정책 1행(생성 트리거+백필), RLS select 멤버/update 관리자. BEFORE 게이트(크루 allow·채널 crew_memory): 잠금이면 insert는 기본값으로 맞추고 update로 다른 값은 msgr_policy_locked 거절. 정책 갱신 AFTER: 잠그는 순간 기존 크루·채널을 기본값으로 정리 + policy.update 감사(meta 4값), updated_by/at 도장
- 메신저: loadOrg가 정책 조회, 설정 "조직 정책" 카드(관리자 편집·멤버 읽기 전용, 개인 PC 크루 한계 정직 표기), 크루 시트·채널 시트는 잠기면 비활성+안내, 서버 거절은 err.policyLocked
- 아르고: 라우트가 조직별 policy를 실어 등록 카드 라디오 잠금+안내(i18n ko/en)
- 별건 실측 결함: signOut() 기본 범위(전역)가 같은 계정의 아르고 기기 세션 리프레시 토큰까지 폐기 → { scope: 'local' } 2곳 + 핀
- 테스트: 역할 경계표 9행동(editPolicy), pg 드릴 정책 케이스(18/18), 소스 구간 핀 3건, 변이 8종 red 실증(pg 2스위트 fail 합산)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…an_decide, 코드 위험 판정, 슬립 고위험 배지·권자 분기, 정책 카드 결재권 행
- 스키마: msgr_crew_approvals.risk('low'|'high', 등록 후 불변), msgr_org_policies.approval_high_by('admin' 기본 | 'owner'). msgr_can_decide(ap): 저위험=크루 소유자, 고위험=정책이 owner면 소유자·아니면 조직 관리자. decide 정책 USING/WITH CHECK에 결합(소유자의 pending 카드 링크 갱신은 유지)
- 위험 판정 src/approval-risk.mjs(순수): 커넥터 쓰기=항상 고위험, profile/hire/loop=저위험, 자유 문장은 발송·결제·삭제·게시·계약 키워드(ko/en, 사유 포함). 브리지 미러가 risk를 싣고 고위험 카드 본문은 결재권자 안내
- 메신저: 슬립 고위험 배지·"조직 관리자 결정 대기"·비권자 안내, 버튼은 권자에게만, RLS 0행 문구 등급별. 정책 카드 "고위험 결재 확정권" 행
- 테스트: approval-risk 단위, 브리지 미러 risk·카드 본문, pg 드릴 결재권 케이스(19/19), 소스 핀. 변이 9종 red(pg 2스위트 fail 합산)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… 각인으로 로컬 확정 거절(협조적 강제), 정책 밖 확정 신호 - 서버: msgr_can_instruct(crew, author)(소유자 항상 / 'owner' 불가 / 'list'=목록∩활성 멤버 / 'all'=활성 멤버 전원 / detached·없는 크루 false). msgr_crew_reply_gate BEFORE INSERT: 크루 답글(reply:<crew>:<src>)의 원문 작성자를 재판정해 정책 밖이면 msgr_not_allowed — 브리지가 무시해도 서버가 막는다 - 브리지: drain이 메시지마다 서버 RPC로 판정(실패 시 로컬 판정 폴백+로그). 결재 미러 시 msgr_can_decide를 항목 msgr.ownerMayDecide에 각인. 메신저 경유 확정은 미러 갱신 생략. 정책 밖 로컬 확정(미러 0행)은 채널 시스템 메시지(apl:)로 표기 - 로컬: resolveApproval이 ownerMayDecide=false면 웹·텔레그램·슬랙 창구의 확정을 거절(via 'msgr'만 통과) — 정식 앱은 조직 정책을 따른다(부록 K) - 테스트: pg 드릴 RPC·답글 게이트(20/20), 브리지 행동 3건(서버 판정·폴백, 협조적 강제, 정직한 신호), 변이 7종 red. 실러너 실측: 멤버 멘션 거절·소유자 멘션 실답변 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rew_tier(invoker), 레일 카드 조직 배지·시트 등급 행·개인 크루 한계 문장
- 스키마: service_user_id(관리자 지정, 활성 멤버만 — msgr_service_not_member, 감사 org.service_account; 소유권 이전 본문 그대로). msgr_crew_tier(crew) = 서비스 계정 소유 ∧ resident면 'company', 그 외 'personal'. security invoker — 비멤버는 행이 없어 판정 오라클이 되지 않는다
- 메신저: 조직 조회에 service_user_id, crewTier(crew, org) 미러(정본은 서버). 회사 크루=각진 해시 배지+"{조직}의 크루", 개인=별 배지+"{소유자}의 크루 · 파견". 크루 시트에 등급 행·서비스 계정 소유 표기·한계 문장(부록 K ③)
- 테스트: pg 드릴 등급·서비스 계정 규칙(21/21), 소스 핀, 변이 5종 red. E2E는 ego-browser(격리 작업 공간)로 카드 3종·시트 2종 실측
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…정책(허용/읽기만/차단) + 사유 RPC msgr_instruct_check·멤버/답글 게이트·차단 전환 sweep, 멘션·추가 후보 필터 - I-2: 라우트가 정책 6항목을 실어 카드에 요약 한 줄(허용 범위 기본값·잠금, 고위험 결재권, 채널 크루 기억) + "파견한 크루 = 개인 크루" 한계 문장(부록 K ③) - I-3 서버: msgr_channels.personal_crews. msgr_instruct_check(crew, author, channel) → 'ok'|'inactive'|'crew_allow'|'channel_policy'(개인 크루는 소유자 지시도 불가·회사 크루 무관·채널 정책이 크루 규칙보다 먼저), msgr_can_instruct 2/3인자 포장, 답글 게이트가 채널을 본다, blocked 채널 멤버 추가 거절(msgr_channel_personal_blocked)·전환 시 기존 개인 크루 멤버 sweep·감사 channel.personal_crews - 브리지: 사유 RPC(채널 포함)로 묻고 channel_policy면 채널 사유로 안내(폴백은 로컬 판정) - 메신저: 채널 시트 세그먼트(dm 제외)·차단 안내·추가 거절 문구, 멘션 후보·추가 후보에서 개인 크루 제외(안 될 버튼 노출 금지 — 최종은 서버) - 테스트: pg 드릴(22/22), 브리지 채널 사유 케이스(15), 소스 핀, 변이 9종 red. ego-browser 실측: read_only 저장·후보 회사 크루만, blocked 전환 시 개인 크루 멤버 제거·추가 거절 문구, 아르고 카드 요약 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…oad, 슬립 미리보기, 승인 시 서버가 승인자 권한으로 문서 반영(version+1·감사); 채널 시트 인원·초대 안내 - chat.mjs: propose_org_doc(scope org|channel, folder, title, body, reason, 선택 slug) → addApproval(kind 'org_doc', payload). 메신저 조직 턴에만 등록 - 스키마: msgr_crew_approvals.kind·payload(잠김), msgr_apply_org_doc AFTER UPDATE — 승인자(관리자 또는 채널 편집권자)의 권한으로 msgr_org_docs 생성/갱신, 감사 doc.proposal.applied. NULL 주의: 서비스 문맥의 msgr_is_admin은 NULL → coalesce로 닫음(배터리가 적발) - 위험 판정 org_doc=high(관리자 확정). 브리지 미러가 kind·payload 실음, 카드 본문 제안 안내. 후속 턴 문구 "서버가 반영 — 다시 쓰지 마라" - 메신저: 슬립에 제안 미리보기(범위·경로·제목·본문), 승인 후 안내. 채널 시트 사람 추가에 "조직 인원 N · 플랜 좌석 M — 초대 링크" 안내(유건 질문) - scripts/msgr-real-bridge.mjs: onNotify→msgrPush 훅(없어서 로컬 결재가 미러되지 않던 실사고) - 테스트: pg 드릴(24/24, 비관리자 명의 강제 승인 거절 포함), 브리지·리스크·핀, 변이 6종 red. 실러너 E2E: 제안→카드→승인→문서 v1·감사·미러·후속 보고 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…건), 본인 표시명, 로컬 알림(멘션·관리자 결재), 오프보딩 자동 사슬 - 스키마: msgr_members_update_self(본인 표시명만 — 역할·제거 표시는 msgr_member_self_guard가 거절, NULL 주의 coalesce), msgr_member_offboard(제거 → 크루 detach·비공개 채널/DM 멤버십·크루 멤버십 제거·감사 member.offboard, 되살림 → 크루 복구). 메시지 방송 payload에 author_user_id(본문은 여전히 없음) - 메신저: 설정 "조직" 카드(관리자) — 조직 이름, 멤버 역할 세그먼트(소유자 행·본인 제외), 제거 2단계 확인(removed_at, 발언 유지), 초대 역할 선택·링크 만들기(클립보드)·목록·취소, 감사 기록 50건. 계정 카드 표시명 편집·알림 권한 행. OS 알림: 나를 부른 메시지·관리자가 확정할 결재, 자기 글 제외, 보고 있는 채널은 제외 - 실사고: 알림 블록을 isAdmin 선언 앞에 삽입해 TDZ로 앱이 통째로 비었다(빌드는 통과) → 위치 이동 - 테스트: pg 드릴 F2(25/25), 핀, 변이 5종. ego-browser 실측: 표시명·조직 이름 변경이 레일/풋터에 반영, 민수 역할 관리자↔멤버, 게스트 초대 생성·취소, 감사 기록 표시, 원복 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…l·지정 가드)와 지정 결재권자(approver_user_ids·approvers 정책·msgr_can_decide), 시트 태그/토글·정책 피커·슬립 확정권 - 채널 관리자: 채널 설정·멤버 쓰기 정책을 msgr_can_manage_channel(생성자·채널 관리자·조직 관리자(dm 제외))로 통일. 지정은 조직 관리자·생성자만(자기 증식 방지), 조직 멤버여야, 비공개 채널은 채널 멤버 중에서(아니면 RLS 열람이 막혀 0행 — 드릴 실측), 감사 channel.admins - 지정 결재권자: 정책 approval_high_by='approvers' + approver_user_ids(관리자는 항상 확정 가능). 정책 카드 3옵션·피커(게스트 제외 — 공개 채널 열람 불가), 슬립 확정권·안내 분기 - 메신저: 구성 행 "만든 사람/채널 관리자" 태그, 톱니 토글(지정 권한자만) - 테스트: pg 드릴 J-1(26/26), 핀 갱신, 변이 5종. ego-browser 실측: 소유자 지정·정책 저장 → 민수로 채널 주제 편집·지정 토글 비노출·고위험 카드 승인(decided_by=민수) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…노드 하트비트 RPC·폴러 훅, 부트스트랩 CLI, 조직 카드 '회사 노드' 섹션 - 서버: msgr_invites.for_node(member 전용 check) + msgr_accept_invite가 노드 코드면 msgr_orgs.service_user_id를 수락 계정으로 지정(소유자·관리자 계정은 msgr_node_not_admin — 강등 방지, 멤버십 손대기 전 거절), msgr_orgs.node_seen_at + msgr_node_heartbeat(org)(서비스 계정 본인만 true) - 브리지: makeDb.nodeHeartbeat, drain(nodeOrgId)가 크루 0명이어도 생존 신호, 폴러가 company.json.msgr.nodeOrgId 전달 - CLI: scripts/msgr-node-bootstrap.mjs → src/msgr-node.mjs(로그인은 env로만 → 수락 → 기기 세션 저장 → 조직 회사 org-<slug> 생성·nodeOrgId → 첫 하트비트, 재실행 멱등, 사람용 코드는 정직한 오류) - 메신저 조직 카드: 회사 노드 상태(없음/준비됨/연결됨/응답 없음 90초)·연결 코드 만들기(한 번에 하나, 다시 만들면 이전 취소)·실행 명령 블록·복사·취소, 노드 코드는 사람 초대 목록에서 분리. 조직 카드 시각은 날짜 포함형(fmtWhen) - 테스트: pg 드릴 27/27(I-4 케이스), 브리지·부트스트랩 단위, 핀, 변이 6종 red. ego-browser 실측(로컬 스택): 소유자 코드 발급 → CLI 부트스트랩 → 연결됨(초록) → 3분 경과 응답 없음 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rew_create)·노드 처리기(카드→등록→done)·채널 시트 폼, I-5b 정책 기본 엔진(crew_runner·crew_model) - 서버: msgr_crew_requests(RLS: 멤버 열람 / insert는 정책 crew_create 행렬(admin·channel_admin·member, 조직 전체 범위는 관리자만)+노드 연결 필수 / 상태 갱신은 서비스 계정만), done 트리거가 채널에 크루+서비스 계정 추가·crew.create 감사, crew_id 없는 done 거절, 방송 crew_request로 노드 즉시 기상. 정책 crew_runner·crew_model - 노드: persona.createAgentCard(모델 호출 없는 카드, slug·-n·예약어 규칙 동일) → msgr_crews 등록(resident·서비스 계정 소유·allow all) → done, 실패는 failed+사유. 조직 회사는 크루 0명이어도 조직 토픽 구독 - 메신저: 채널 시트 "회사 크루 만들기"(이름·역할·한 줄 지시·조직 전체 범위는 관리자), 요청 상태(만드는 중/생성됨/실패 사유) 3초 폴, 노드 없으면 관리자에게만 안내(안 될 버튼 노출 금지). 정책 카드 crew_create 세그먼트 + 기본 엔진 입력 - 실측(ego-browser·로컬 스택·실러너): 채널에서 온보딩봇 생성 → 참여 구성에 회사 배지 → 멘션 → 노드 턴(기본 모델 haiku 402 실패를 정직 표기) → 정책 엔진을 openrouter/무료로 저장 → helpbot 생성 → 멘션 실답변 - 테스트: pg 드릴 28/28(I-5·I-5b), 카드·브리지 단위, 핀, 변이 8종 red Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…LL 방어), msgr_org_locked 쓰기 게이트, 조직 카드 소유권 섹션·수락 배너·잠금 배너 - 서버: msgr_orgs.pending_owner_user_id·successor_user_id. 소유자는 활성 관리자에게 제안만(msgr_transfer_not_admin), 제안받은 사람이 자기로 owner_user_id 갱신 = 수락(역할 스왑·제안 비움·승계가 새 소유자면 비움·org.transfer 감사), 거절은 당사자, 취소는 소유자, 직접 이전은 msgr_transfer_needs_accept. 승계 관리자는 소유자만·관리자만(org.successor 감사). NULL 함정: 제안이 없을 때 (= me)가 NULL이라 not도 NULL로 통과하던 구멍 → coalesce(드릴 실측) - 잠금: msgr_org_locked(org) = ls_status past_due·unpaid → msgr_can_write_channel·크루 생성 요청 insert 차단(열람은 유지, 삭제 없음) - 메신저: 조직 카드 소유권 섹션(승계 관리자 칩·이전 제안 칩·대기 태그·취소), 제안받은 관리자에게 수락/거절 배너(제안자 이름 = 조직 행 owner_user_id — 미조회로 ? 표시되던 것 수정), 잠금 배너(관리자 문구 분기)+보내기 비활성 - 실측(ego-browser·로컬 스택): 유건→민수 제안(승계 지정 포함) → 민수 로그인 수락 → 소유자 교대 → 되돌리기 제안·수락 → 민수 멤버 복귀, 감사 org.transfer.offer/org.transfer 4건. past_due → 배너·보내기 비활성 → 해제 - 테스트: pg 드릴 29/29(J-2), 핀, 변이 6종 red Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…_joinable_orgs/msgr_join_by_domain RPC(좌석 게이트·감사), 소유권 섹션 도메인 행, 메뉴·빈 화면 가입 후보 - 서버: msgr_orgs.auto_join_domain·auto_join_role(member|guest). 가드 트리거: 소유자만, 소유자 로그인 이메일 도메인과 같아야(msgr_domain_not_owners — 그 메일함의 주인이 곧 소유자, DNS TXT는 후속), 공개 메일 도메인 거절(msgr_domain_public), org.domain 감사. 후보 RPC는 같은 도메인·미가입·살아 있는 조직만(이름·슬러그·역할), 가입 RPC는 초대 수락과 같은 멤버 insert 경로(좌석 게이트·member.join.domain 감사). 이메일 도메인 함수는 public에서 회수(오라클 방지) - 메신저: 조직 카드 소유권 섹션에 도메인 입력+역할 세그먼트+저장(빈 값 = 끄기, 서버 거절 사유별 문구), 조직 메뉴와 "조직 없음" 화면 1단계에 "내 도메인 · 바로 가입" 후보 - 실측(ego-browser·로컬 스택): 유건이 example.test 등록 → 같은 도메인 신입 계정 로그인 → 빈 화면 1단계에서 린 컴퍼니 가입 → 채널 목록 진입, 감사 org.domain·member.join.domain - 테스트: pg 드릴 30/30(J-3), 핀, 변이 5종 red Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…등록, 만료는 msgr_role이 즉시 판정, 좌석은 정책 guest_seats - 서버: msgr_invites.channel_id(비공개 채널만·채널 한정 = guest check)·guest_days(1~365), msgr_org_members.expires_at, 정책 guest_seats(기본 false). 초대 select/insert/delete 정책을 채널 관리자까지 확장(공개 채널·비관리자 거절). msgr_accept_invite: 게스트 = 기간 각인 + 채널 멤버 자동 등록, 정식 멤버가 게스트 링크를 열면 강등 없이 채널만 추가. msgr_role이 expires_at를 봐 만료 즉시 전 RLS 차단(잡·삭제 없음). 좌석 게이트: 게스트는 정책이 켜질 때만·만료자는 제외 - 메신저: 비공개 채널 시트 "게스트 초대"(7/30/90일 + 링크 만들기·복사), 멤버 목록 "게스트 · …까지"/"만료됨", 정책 카드 게스트 좌석 토글 - 실측(ego-browser·로컬 스택): 소유자가 design-private 7일 게스트 링크 → 파트너 계정이 링크로 진입 → 그 채널만 보임 → 멤버 목록에 기간 표기 - 테스트: pg 드릴 31/31(J-4; 드릴 픽스처 시드 — 앞 케이스가 뺀 PRIV 멤버십), 핀, 변이 5종 red Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…msgr_my_deleted_orgs RPC, msgr_purge_orgs(service_role), 감사 가드·소유자 표시명, J-4 드릴 보강 - 서버: 삭제·복구 판정은 역할이 아니라 owner_user_id = me(삭제 뒤 msgr_role이 null이라 역할로는 불가), 삭제 시 이전 제안 비움, org.delete/org.restore 감사. 삭제된 조직은 일반 UPDATE 정책을 못 지나므로 복구는 RPC(30일 안·msgr_restore_expired), 목록 RPC는 남은 날짜 포함. purge는 service_role 전용(authenticated 회수) — 운영 잡 배선은 후속 - msgr_audit: 조직이 cascade로 지워지는 문장 안에서 자식 트리거의 감사 insert가 FK를 깨던 것 → 조직 없으면 건너뜀(드릴 실측). msgr_org_after_insert: 소유자 멤버 행 표시명 = 이메일 앞부분(멤버 목록에 uid 앞자리 보이던 결함) - 메신저: 조직 카드 소유권 섹션 "조직 삭제"(이름을 그대로 입력해야 확정, 네이티브 confirm 없음), 조직 메뉴·"조직 없음" 화면 "삭제 예정 · N일 남음 · 복구" - J-4 드릴 보강: 공개 채널 관리자로 만든 뒤 게스트 링크 거절(직전 배터리에서 kind='private' 조건 제거가 초록이던 구멍 → red) - 실측(ego-browser·로컬 스택): 임시 조직 생성 → 이름 입력 삭제 → 메뉴 복구 → 감사 org.delete/org.restore - 테스트: pg 드릴 32/32, 핀, 변이 6종 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…속 검증(HIGH), 게스트 자기 만료 삭제·도메인 함수 권한·frontmatter 개행 주입·퇴사자 도메인 재가입·관리자 서비스 계정 자기 지정(HIGH), 게스트 노출면·member 정책 채널 검증·잠금 전면·purge 첨부·삭제 조직 목록·죽은 노드 게이트·오류 문구(MEDIUM), 공개 도메인·게스트 채널 필수·죽은 조건·CLI 안내(LOW) - 서버(전부 재정의로 덧붙임): msgr_lock_crew_requests + done 트리거가 crew_id를 같은 조직·서비스 계정·resident로 검증·확정 뒤 재변경 거절, msgr_channel_member_ok(user=활성 멤버·crew=같은 조직) insert/update, 게스트는 전사 문서·요금·정책·크루 요청 미열람, 자기 만료 갱신 거절(self_guard), msgr_email_domain anon·authenticated 회수, name/role_text 개행 금지, 도메인 가입은 행 없는 사람만(퇴사자 msgr_removed_rejoin·기존 멤버 msgr_already_member), 서비스 계정 지정은 소유자 또는 노드 수락 RPC(트랜잭션 플래그 msgr.node_accept)만, member 정책은 쓸 수 있는 채널만, 잠금은 채널 생성·크루 파견·초대·전사 문서 편집까지, resident는 서비스 계정만·hosting 불변, 게스트 초대는 채널 필수·도메인 가입 역할 member 고정, 소유권 이전 시 다른 도메인이면 자동 가입 해제, purge가 Storage 실파일도 삭제(스키마 있을 때), 공개 도메인 목록 확장, 채널 관리자 가드 만료 게스트 제외 - 노드: createAgentCard 값 개행 세척, 부트스트랩 CLI 서버 코드 → 한 줄 안내 - 메신저: 삭제 표시 조직은 목록 제외(복구 칩만), 회사 크루 만들기는 살아 있는 노드(90초)일 때만·게스트 제외·응답 없음 안내, RLS·check 거절 문구 매핑(friendlyErr 4곳), 조직 전체 초대 역할에서 게스트 제외·도메인 가입 역할 세그먼트 제거, 죽은 조건 제거, 게스트 정책 문구 정직화 - 드릴: 검수 항목별 케이스 2건 추가(34/34), 시드는 슈퍼유저(게스트·resident), G-1·I-1 기대값을 새 규칙으로. 변이 8종 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…하나로, 행 '…' 메뉴, 채널 설정은 접힘, 문장형 라벨 - 유건 지적(2026-09-04): 위치보다 기능이 이해가 안 됨 — 설명 없이 읽히게. 패널은 열리는 이유(누가 있나·넣기)가 첫 절, 이름·주제·기억·개인 크루·보관은 "채널 설정"으로 접음(1106px → 442px) - '+ 추가' 메뉴 = 사람 추가 / 크루 추가 / 외부 게스트(이 채널만 보는 링크·기간 지나면 자동 종료) / 새 회사 크루(서버가 없거나 죽으면 비활성 + 이유). 각 항목에 한 줄 설명 - 행 '…' 메뉴 = 1:1 대화 / 채널 관리자로 지정·해제 / 내보내기 (톱니 토글·x 아이콘 제거) - 문장형: "구성원이 자기 크루를 데려올 수 있음: 데려올 수 있음/보기만/못 데려옴", "채널 대화를 크루가 기억함", 회사 노드 → 회사 크루 서버 - 로직(upd·addMember·removeMember·toggleChAdmin·guestInvite·submitCrew·요청 폴)은 그대로. 핀은 새 불변식으로 이관(구성이 설정보다 앞, 항목 비활성 조건, 메뉴 안 게스트) - ego-browser 실측: 메뉴로 사람 추가 → 행 메뉴로 내보내기 → 게스트 링크 발급 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… 접기, 회사 크루 서버 연결 안내, 도메인 가입 토글, 소유권 넘기기 문장형, 승계 지정 UI 제거 - 유건 지적: 설명 없이 읽히게. 3,133px 카드 더미 → 탭. 첫 화면은 멤버. 각 탭이 한 화면 - 조직 카드는 part(members·org·node·audit)로 분할 렌더. 멤버 탭: 목록+역할, "사람 초대" 버튼 2개(멤버 링크·관리자로 초대), 초대 목록은 "멤버 초대 링크 · N일까지"(hex 코드 제거), 서버 계정 행은 "회사 크루 서버"로 표시·역할 세그먼트 없음 - 조직 탭: 이름, "@도메인 계정은 초대 없이 들어올 수 있음" 토글(어차피 소유자 도메인만 허용되므로 입력 없음), "소유권 넘기기" → 사람 → "민수가 수락하면 확정됩니다" 확인 문장, 삭제(이름 입력). 승계 관리자 UI는 자동 승계 전까지 숨김(서버 기능은 유지) - 크루와 서버 탭: "회사 크루 서버" 상태 한 줄 + "서버 연결하기" → 3단계 안내 안에서만 코드·명령. 크루 규칙 = "새 크루에게 일을 시킬 수 있는 사람은?" / "크루의 큰 결정은 누가 승인하나요?" / "회사 크루를 만들 수 있는 사람은?" + 고급(기억·게스트 좌석·AI·잠금) - 용어: 회사 노드 → 회사 크루 서버, 허용 범위 → 모두/정한 사람만/크루 주인만, 결재 → 승인 - 사람 후보(채널 추가·이전·결재권자)에서 서버 계정 제외. 핀 이관(24/24). 화면 실측은 브라우저 제어권 반환 후 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…fo)을 싣고, 규칙 카드는 목록에서 고른다 - 서버: msgr_orgs.node_info jsonb, msgr_node_heartbeat(org, info default null) — 서비스 계정만, 16KB 상한, 정보 없는 하트비트는 목록 유지. 멤버가 목록을 읽는다(조직 행) - 브리지: nodeRunnerInfo(ws) = 자격 있고 유효하고 숨김 아닌 러너 + 카탈로그 모델(id·label·free), 5분 캐시(runnerStatus는 CLI 감지). drain이 하트비트에 싣는다 - 메신저: 규칙 카드 "회사 크루가 쓰는 AI" — 목록이 있으면 러너 select → 모델 select(무료 표기, 러너 바꾸면 모델 초기화), 없으면 텍스트 입력 유지(정직) - 테스트: pg 드릴 34/34(+node_info), 브리지 단위(목록 필터·캐시), 핀 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…행 역할 버튼 오른쪽 고정, 게스트 링크 라벨, 크루와 서버 탭 렌더 오류(nodeSet)·페이지 오류 경계 - 레일: 호버에 '…' → 채널 설정 열기 / 채널 나가기(비공개만, 내 크루가 있으면 차단 안내, 2단계 확인) / 채널 보관(관리 권한만, 2단계). 1:1은 대화 나가기. 나가기는 RLS의 본인 행 삭제 허용을 그대로 사용 - 멤버 탭: 게스트 만료 문구를 이름 옆으로 옮겨 역할 세그먼트가 오른쪽에 고정. 채널 게스트 링크는 "게스트 링크(채널 한정)"로 표기(키 노출 실사고) - 조직 카드 서버 부분이 채널 시트 변수(nodeSet)를 참조해 ReferenceError → 앱 전체 빈 화면. 변수 정의 + PageBoundary(한 화면 오류가 앱을 지우지 않고 "대화로 돌아가기") - ego-browser 실측: 레일 메뉴 3항목, 멤버 탭 정렬·라벨, 크루와 서버 탭(질문 3개·연결됨·AI 드롭다운), 조직 탭(토글·넘기기·삭제) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…좁힘(읽기 함수·채널 목록 정책) - 실측: 만든 사람이 1:1·비공개 채널에서 나가도(멤버 행 삭제) 생성자 조항 때문에 계속 보였다. 조항은 insert … returning(멤버 등록 전) 용도였으므로 msgr_channel_has_users 도우미(security definer, 정책 순환 방지)로 "멤버 0명일 때"만 남긴다 - 드릴: 나가기 케이스 추가(생성 직후 보임 → 나가면 안 보임 → 남은 멤버는 그대로, 관리자도 비공개는 멤버 아니면 안 봄), 픽스처는 앱과 같게 만든 사람을 첫 멤버로(PRIV·ops). 35/35 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…240px, 문서 320px 목록+나머지) (유건 지적 2026-09-04) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… 대상의 활동 문장(유건 지시 2026-09-04), 설정의 기록 탭 대체 - 그래프는 아르고 Graph2D를 별칭(@argo/graph2d)으로 재사용(사본 금지) — 조직·채널·사람·크루·문서를 [[링크]] 문서로 구성해 같은 계약으로 그린다. 노드 클릭 = 트리 선택 = 활동 필터. linen 룩 통일: graph2d가 --mark-rgb(옐로)를 먼저 보게(차콜 --accent는 무채색이라 파랑 폴백이 나오던 문제) - 활동 문장: 감사 19종 + 상태 완성형(승인/거절, 문서 생성/수정/삭제)을 사람·채널·크루·문서 이름으로 치환, 날짜 묶음, 60건씩 더 보기, 한국어 조사(이/가·을/를·으로·은/는) 자동 선택, 관리자 지정 해제 문장 별도 - 감사 열람은 RLS(관리자)라 멤버에겐 그래프만 + 안내. 레일 풋터에 활동 버튼(별), 설정의 "기록" 탭 제거 - Aside 실측: 트리 64건, design-private 선택 → 8건 문장, 그래프 노드 클릭 연동 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Activity: 카드 섹션 제거 → 아르고 기억 페이지처럼 트리 | 탭 스트립 + 본문 전체 높이 분할(.msgr-actsplit)
- 가로 다중 탭(.vault-tabs 재사용): 그래프 탭 + 트리·그래프 클릭으로 대상(채널·사람·크루·문서) 탭 열기/닫기
- graph2d: nodeShape prop('star' 기본 | 'circle') — 메신저만 circle(십자 빛살 없음), 아르고 기억 그래프 기본 별 유지. 의존 배열 8개 고정(ref로 읽음)
- i18n act.tab.graph·act.closeTab, 핀 갱신
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- 트리 행 컴포넌트를 Activity 안에서 정의하던 것을 모듈 수준 ActRow로(렌더마다 새 타입 → 클릭마다 트리 리마운트 = '새로고침처럼' 보이던 뿌리). 감사 재조회 키는 채널 id 목록으로 - graph2d: --graph-rgb를 최우선으로 읽음(없으면 종전 --mark-rgb). 메신저 linen만 러스트(라이트 176,82,30·다크 228,136,84) — 옐로가 그레이지 캔버스에서 묻힘 - 탭 우클릭 메뉴(닫기·다른 탭·오른쪽 탭·모두 닫기), 가운데 클릭 닫기, 스트립 끝 '모두 닫기' 버튼(탭 2개 이상일 때) - 초대 수락 문장의 빈 괄호 제거 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- apps/messenger/src/graph3d.jsx: 3D 힘 배치(반발·스프링·중심)+원근 투영을 캔버스 2D로. 구성은 @argo/graph2d-core 재사용(별칭 추가) - 인터랙션: 드래그 궤도 회전(관성)·휠 줌·호버 강조(이웃·엣지)·클릭 열기·더블클릭 집중(빈 곳은 전체 복귀)·쉬는 동안 느린 자동 회전(동작 축소 설정 존중) - 룩: 원형 노드(허브 링·집중 링)·깊이별 크기·투명도·경계 구 적도 점선 지평, 색은 --graph-rgb(러스트) 우선 - 활동 페이지 그래프 탭·대상 탭 로컬 그래프 모두 3D로 교체, 안내 문구 i18n, 핀 갱신 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- graph3d local 모드(compact+focusRel): 집중 노드 원점, 이웃은 같은 간격 고리(위아래 교대), 힘 배치 생략, 위에서 내려다보는 시점 - 라벨은 왼쪽 반이면 왼쪽으로, 지평선 생략, 카드 높이 260 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- panes/focusPane 상태(기억 페이지 openTab·closeTab 계약과 같은 서명), 창은 둘까지 - 그래프 노드 클릭 → 옆 창(없으면 만들고)에 대상 탭, 트리 클릭 → 포커스 창, 대상 탭 '옆 창에 열기'(⫿) 버튼 - 탭 메뉴·가운데 클릭·모두 닫기는 창 단위(둘째 창은 비면 사라지고 첫 창은 그래프만 남음), 더 보기 상한은 탭별 - 활동 목록 계산을 대상별 함수(entityView)로 — 두 창이 서로 다른 대상을 동시에 보인다 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- 대상 탭: 조직/채널 = 범위의 기억 목록(종류별)+새 기억(전사=관리자·채널=멤버), 사람 = 남긴 기억, 문서 = 본문·편집·저장(MemDoc/MemNew 모듈 수준) - 본문 [[제목]] 링크가 그래프 엣지(아르고 vault 문법), 문서 본문까지 조회해 저장 뒤 재사용(load) - 별도 조직 문서 페이지(Docs)·레일 문서 아이콘 제거 — 같은 것이 두 자리에 있지 않게 - 활동 기록은 관리자에게만 접힌 보조 섹션, '옆 창에 열기'는 글자 라벨, 핀·i18n 갱신 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- .msgr-tabscroll(flex:1·overflow-x)이 탭만 밀고, '옆 창에 열기'·'모두 닫기'는 flex:none·nowrap - 탭 min-width 96px(제목이 '그…'로 뭉개지지 않게), 활성 탭은 scrollIntoView Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- .msgr-actsplit 배경을 --card로: 트리·탭줄·본문·그래프 캔버스(--paper-rgb == --card)가 같은 판(종전 본문만 --bg라 트리와 달랐다) - 노드 흑백: linen --graph-rgb = 잉크(라이트 38,36,31 / 다크 230,226,216). 명시 --graph-rgb는 렌더러의 채도 검사·파랑 폴백을 면제(graph2d·graph3d 같은 규칙, 본체는 미정의라 동작 불변) - 대상 탭의 작은 그래프 제거 — 그래프는 그래프 탭 전담. graph3d의 전용 배치(local) 분기도 함께 제거 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- '정말 나가기 — 목록에서 사라집니다' 한 문장을 제목(굵게)+설명(보조 줄)로 분리(ko/en 키 3쌍 신설) - .msgr-rowmenu button.confirm: height auto·상단 정렬·2단 그리드, 일반 항목은 nowrap, 메뉴 max-width 244 - 실측: 확인 버튼 166x50 한 덩어리, 설명 1줄, 메뉴 우측 247 < 레일 268 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- 판을 --bg(상단 바와 같은 베이지)로: 트리·탭줄·본문·그래프 캔버스(--graph-paper-rgb 신설) 모두 233,230,223 - 줌 결함 수정: 초점거리에 cam.dist를 곱해 두어 다가가도 배율이 상쇄됐다(휠·버튼이 사실상 무효) → 초점 고정, 노드 크기 기준도 fitDist. 실측 확대 +63%·축소 -25% - 줌 버튼(확대·축소·전체 보기) 우하단, ctrl+휠(트랙패드 핀치) 감도 분리, 휠 감도 상향 - 동적·미니멀: 노드 미세 부유, 호버 강조 이징, 호버 노드에서 이웃으로 흐르는 점, 호버 링 펄스, 진입 페이드, 지평선 장식 제거, 라벨 11.5px. 동작 축소 설정이면 전부 정지 - compact 분기 제거(소비자 0) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…프 재구축/줌 결함 보안 HIGH: 사람 멤버 0명이면 생성자 열람 조항이 마지막 사람이 나간 뒤 생성자를 되살렸다(실측) → 생성+첫 멤버를 RPC msgr_create_channel 한 번으로, 열람·목록·관리에서 생성자 예외 제거(비공개·1:1은 멤버십만, 공개는 조직 역할). 관리 자격도 멤버십에 묶어 나간 생성자가 자기를 다시 못 넣는다. RPC의 역할 NULL(비멤버) 구멍은 드릴이 적발 → coalesce 보안 MED: node_info는 트리거로 서비스 계정만·16KB(관리자 직접 update 우회 차단), RPC는 초과 정보만 버리고 생존 신호는 남김 / 문서 조회 400건 상한 / 표시명 DB 제약(not valid) 코드 HIGH: Graph3D agents 기본값 새 배열 + 부모 30초 재적재 → 그래프 통째 재구축(드래그 끊김) → 모듈 상수 + 내용 키 메모 / 집중 뒤 줌 하한이 원점 반경 기준이라 노드가 카메라 뒤로(캔버스 덮는 원) → 중심 기준 반경 + 카메라 뒤 컬링 코드 MED: 채널 키 이름→id(동명 충돌), 생성 시 동명 차단 / 본체 graph2d.jsx 되돌림(소비자 0·linen 포인트색 변경)+별칭 제거 / 하트비트가 CLI 감지 뒤에 갇히던 것 3초 타임아웃 / 창·탭 전이를 panes.mjs(순수)로 빼고 행동 테스트(빈 창·중복·활성/포커스 승계·closeRight 가드) / i18n 전수 스윕 테스트 LOW: 나가기 크루 가드 fail-closed, MemDoc/MemNew 오류 문구 관례, 죽은 상수·중복 헬퍼 정리, colors() getComputedStyle 1회 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
무엇
아르고 팀 메신저의 크루 브리지. 소유자의 로컬 아르고(또는 상주 노드)가 기기 세션 JWT로 Supabase에 붙어 자기 크루의 @멘션·DM을 디스크 큐 →
chat()→ 답글 insert로 잇는다. 텔레그램·슬랙 옆의 새 채널 종류msgr(접합 4지점: qkeys·핸들러·리더 전용 폴러·pushEvent 머리). #419(스키마) 위 스택 — #419 머지 후 base를 main으로 재타깃.src/gateway/msgr.mjs:makeDb(supabase-js 체인 단일 층) ·drain(허용 범위 게이트 all/list/owner, 24h 만료 폐기, 적재 후 서버 커서 전진, 결재 결정 큐 우회 반영) ·makeMsgrHandler([#채널] 이름:귀속, 첨부 내려받기,journal:{off,tag},client_msg_id=reply:<crew>:<msg>멱등 답글, 산출물 업로드, 부재중 접두) ·msgrPush(결재 카드 미러·웹 확정 동기화·후속 보고·위임 미러) ·startMsgrBridge(15s 폴 + Realtime private topic 깨우기)chat()journal옵션(세 saveHandover 지점 →journalWrite하나),saveHandovertag = 별도 일지 파일(오프보딩 회수 단위),appendTurnactor,resolveApprovalresolvedByapp/api/companies/[ws]/msgr: 기기 세션으로 크루 등록/해제/조회 →company.json.msgr.enabled검증
test/msgr-bridge.test.mjs8건(가짜 db·chat 주입, 배선 구간 불변식) + 전체npm test1417/0(skip 16) + lint 0scripts/e2e-msgr-bridge.mjs— 로컬supabase start(db·auth·rest·realtime) + 가짜 Anthropic SSE(실자격·비용 0) 23/23: 멘션→답글 7.6s(폴 20s 설정 → Realtime 깨우기 실증), 브리지 재시작 +drain동시 2회 → 답글 정확히 1건·큐 잔존 0, allow='owner' → 거절 안내 1건·답글 0, 결재 미러 RLS 왕복(B 확정 0행·A 확정 1행·로컬 approved resolvedBy=A·재확정 0행), 스레드 via/actor, org 태그 일지 파일journalRel조건부(journal.off) · 402 일지 제외는journalWrite경유영향 반경(문맥 행렬)
chat()공통이라 코드 동일성 추론, 라이브 미검증ARGO_TENANT_OWNER)에서 기기 세션 파일을 만드는 절차는 미구현(상주 노드 스토리)test/gateway*.test.mjs·channel-mute·approval-followup불변🤖 Generated with Claude Code