회귀(Regression): 암호화된 MultiAgentV2 메시지로 인해 읽기 가능한 작업 감사 추적(audit trail)이 제거됨
요약
Codex CLI의 MultiAgentV2 메시지 암호화 업데이트 이후, 작업 감사 추적(audit trail)이 불가능해지는 회귀 문제가 발생했습니다. 메시지 페이로드가 암호화되면서 사람이 읽을 수 있는 텍스트가 사라져 디버깅과 작업 검토가 어려워진 상황입니다.
핵심 포인트
- MultiAgentV2 메시지 암호화로 인해 사람이 읽을 수 있는 감사 텍스트 제거됨
- spawn_agent, send_message 등 주요 메시지 처리 과정의 가시성 상실
- 개인정보 보호와 디버깅/감사 가능성 사이의 트레이드오프 발생
- 암호화된 필드 외에 별도의 비암호화 감사 필드 추가 제안
회귀(Regression): 암호화된 MultiAgentV2 메시지로 인해 읽기 가능한 작업 감사 추적(audit trail)이 제거됨 #28058
설명 (Description)
어떤 버전의 Codex CLI가 실행 중인가요?
Upstream main
#26210 (Encrypt multi-agent v2 message payloads, 2026-06-05 병합됨) 이후 버전. 이 문제는 해당 변경 사항을 포함하고 MultiAgentV2를 활성화한 버전(0.137.0 이후)에 영향을 미치는 것으로 보입니다.
어떤 구독(subscription)을 사용 중인가요?
구독 유형에 관계없이 발생합니다.
어떤 모델을 사용 중이었나요?
모델에 국한되지 않습니다. 이는 MultiAgentV2의 spawn_agent, send_message, followup_task 메시지 처리와 관련이 있습니다.
컴퓨터의 플랫폼은 무엇인가요?
플랫폼에 국한되지 않습니다.
어떤 터미널 에뮬레이터와 버전을 사용 중인가요 (해당하는 경우)?
터미널에 국한되지 않습니다.
Codex doctor 보고서
해당 사항 없음. 이 회귀(regression) 현상은 로컬 환경 상태보다는 #26210에 병합된 코드 동작에서 명확히 나타납니다.
어떤 문제를 겪고 있나요?
#26210은 모델이 접하는 message 파라미터를 암호화된 것으로 표시하고, InterAgentCommunication.encrypted_content만 저장하며, InterAgentCommunication.content를 비워둠으로써 MultiAgentV2 에이전트의 작업/메시지 페이로드(payload)를 Codex가 읽을 수 없게(opaque) 만듭니다.
암호화된 전달 경로는 개인정보 보호 강화 측면에서 이해할 수 있으나, 이로 인해 로컬 롤아웃(rollout) 기록, 추적 축소(trace reduction), 그리고 부모 측의 감사(audit)/디버그(debug) 인터페이스에서 사람이 읽을 수 있는 작업/메시지 텍스트가 제거됩니다. 이로 인해 다음과 같은 기본적인 질문에 답하기 어려워집니다:
- 이
spawn_agent호출이 자식 에이전트에게 어떤 작업을 부여했는가? - 서브 에이전트(subagent)에게 어떤 메시지가 전송되었는가?
- 사후에 롤아웃(rollout)을 검토할 때 왜 자식 스레드(child thread)가 존재했는가?
이는 암호화된 도구 스키마(tool schemas)에 대한 요청 검증 실패를 보고하는 #26753과는 다릅니다. 이 문제는 암호화된 스키마가 수락된 이후의 감사 가능성(auditability) 및 디버깅 가능성(debuggability)에 관한 것입니다.
버그를 재현할 수 있는 단계는 무엇인가요?
- MultiAgentV2가 활성화된 상태에서 'Encrypt multi-agent v2 message payloads #26210'이 포함된 빌드를 사용합니다. (즉, 0.137.0 이후 버전)
- 모델이
spawn_agent,send_message를 호출하도록 합니다.
, 또는 followup_task
- 서브에이전트 (subagent) 태스크에 대해 부모 롤아웃 (rollout)/히스토리 (history)/트레이스 (trace)를 조사합니다.
- 태스크/메시지 내용이 사람이 읽을 수 있는 감사 텍스트 (audit text)로 제공되는 대신 암호문 (ciphertext) 뒤에 숨겨져 있습니다.
기대되는 동작은 무엇인가요?
Codex는 수신 모델로의 암호화된 전달 (encrypted delivery)을 허용하면서도, 서브에이전트 태스크/메시지에 대한 사람이 읽을 수 있는 구조화된 감사 사본 (audit copy)을 보존해야 합니다.
가능한 형태는 모델 전달을 위한 암호화된 message 필드는 유지하되, 읽을 수 있는 태스크 텍스트를 위한 별도의 비암호화 감사 (audit) 필드를 추가하는 것입니다. 감사 필드는 롤아웃 (rollout)/히스토리 (history)/트레이스 (trace) 메타데이터에 영구 저장되어야 하므로, 사용자와 유지 관리자가 모델 전달용 암호문을 복호화할 필요 없이 무엇이 위임되었는지 조사할 수 있어야 합니다.
추가 정보
관련 PR/이슈:
- 암호화 변경: Encrypt multi-agent v2 message payloads #26210
- 관련이 있지만 별개인 스키마 검증 (schema-validation) 이슈: MultiAgentV2 encrypted spawn_agent schema returns 400: model not configured for encrypted tool use #26753
목표는 반드시 암호화된 전달을 되돌리는 것이 아닙니다. 우려되는 점은 암호화된 전달이 서브에이전트 위임에 대한 로컬의 인간 가독성 감사 가능성 (human auditability)을 완전히 제거해서는 안 된다는 것입니다.
소스 분석
업스트림 (Upstream) InterAgentCommunication::new_encrypted()는 의도적으로 content를 빈 문자열로 초기화하고 페이로드 (payload)를 encrypted_content에만 저장합니다:
| #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema, TS)] | |
| pub struct InterAgentCommunication { | |
| #[serde(default, skip_serializing_if = "Option::is_none")] | |
| ... |
수신자 히스토리 (recipient history)에 사용되는 변환 과정은 encrypted_content가 존재할 때마다 암호화된 페이로드만을 방출합니다. 따라서 단순히 런타임 content 필드를 채우는 것만으로는 읽을 수 있는 영구 저장된 ResponseItem을 생성할 수 없습니다. 수정 사항에는 명시적인 로컬 감사 영구 저장 경로 (local audit persistence path)도 필요합니다.
| pub fn to_model_input_item(&self) -> ResponseItem { | |
| let content = match &self.encrypted_content { | |
| Some(encrypted_content) => { | |
| ... |
현재 v2 메시지 헬퍼(helper)는 비어 있는 평문(plaintext) 콘텐츠와 함께 암호화된 통신을 구성합니다:
| pub(super) fn communication_from_tool_message( | |
| author: AgentPath, | |
| recipient: AgentPath, | |
| ... |
send_message 및 followup_task는 여전히 target과 암호화된 message만을 역직렬화(deserialize)한 다음, 해당 암호문(ciphertext)을 공유 헬퍼를 통해 직접 전달합니다. 영구 저장할 수 있는 평문 동반 데이터가 존재하지 않습니다:
| #[derive(Debug, Deserialize)] | |
| #[serde(deny_unknown_fields)] | |
| /// MultiAgentV2 send_message 도구를 위한 입력. | |
| ... |
| let author = turn | |
| .session_source | |
| .get_agent_path() | |
| ... |
수신자는 to_model_input_item()에 의해 생성된 모델 대상 ResponseItem을 기록합니다. 암호화된 통신의 경우, 해당 항목에는 읽을 수 있는 감사(audit) 텍스트가 아닌 암호화된 전달 페이로드(delivery payload)가 포함됩니다:
| pub(crate) async fn record_inter_agent_communication( | |
| &self, | |
| turn_context: &TurnContext, | |
| ... |
구조화된 통신 로그(structured communication log)도 동일한 폴백(fallback)을 가집니다. content가 비어 있는 경우, encrypted_content를 이벤트 콘텐츠로 기록합니다:
| pub(crate) fn emit_agent_communication_send( | |
| communication_id: &str, | |
| context: &AgentCommunicationContext, | |
| ... |
구현 / 수정 사양 (Implementation / fix spec)
구체적인 구현을 통해 암호화된 전달은 유지하면서 로컬 감사 추적(local audit trail)을 복구할 수 있습니다:
- 기존의 암호화된
message필드를 전달 페이로드로 유지합니다. - 각 v2 통신 도구(
spawn_agent,task_message,send_message,followup_task)에 필수적인 비암호화 평문 동반 데이터를 추가합니다:task_message또는message_text와 같이 일관된 이름을 가진 평문 감사 필드. - 핸들러 경계(handler boundary)에서 비어 있는 평문 감사 값을 거부합니다.
encrypted_content가 암호화된message콘텐츠로 설정된 상태에서, 두 가지 모두를 포함하는InterAgentCommunication을 구성합니다.
평문 감사 복사본(plaintext audit copy)으로 설정됨
to_model_input_item()의 동작을 변경하지 않아 수신 모델이 로컬 감사 복사본이 아닌 암호문(ciphertext)을 계속 받도록 유지합니다. - 부모 도구 호출/롤아웃(rollout)에 평문 동반 데이터를 유지하고, 구조화된 추적 엣지(trace edges) 및 로컬 통신 로그에 이를 보존합니다.- 도구 호출(tool calls)을 전달된 자식 항목과 매칭할 때 평문 일치 여부가 아닌 암호문/ID를 사용합니다. 평문 필드는 감사 메타데이터(audit metadata)이며, 암호화된 전달 식별자(encrypted delivery identity)를 대체해서는 안 됩니다.
- 새로운 롤아웃/컨텍스트 항목이 무제한으로 커질 수 없도록, 평문 감사 필드에 대응하는 위임된 메시지(delegated message)와 동일한 엄격한 크기 제한(hard size limit)을 적용합니다.
spawn_agent
이 형태의 절반은 다음 스냅샷 커밋에 구현되어 있습니다:
해당 프로토타입은 task_message를 v2 spawn 스키마에서 필수 사항으로 만듭니다:
이는 해당 필드를 검증하고 InterAgentCommunication.content에 배치하는 동시에, encrypted_content에는 암호화된 전달 페이로드(encrypted delivery payload)를 남겨둡니다:
또한, 롤아웃 추적 축소(rollout-trace reduction)를 통해 암호화된 값은 도구 호출과 전달을 상관관계(correlate) 짓는 데만 사용하고, 읽기 가능한 감사 콘텐츠는 유지하도록 학습시킵니다:
남은 구현 작업은 send_message 및 followup_task에도 동일한 이중 콘텐츠 계약(dual-content contract)을 적용하고, 모든 사용자 대상 히스토리/리플레이/디버그 인터페이스가 제공자의 암호문으로 되돌아가는 대신 감사 복사본을 읽도록 보장하는 것입니다.
수락 기준 (Acceptance criteria)
- 부모 롤아웃/히스토리에 v2
spawn_agent,send_message,followup_task에 대한 읽기 가능한 텍스트가 표시되어야 합니다. - 암호화가 활성화된 경우 자식 모델은 여전히 암호화된 전달 페이로드만 수신해야 합니다. - 구조화된 롤아웃 추적 상호작용 엣지는 제한된 크기의 평문
message_content를 포함해야 합니다.
. - 통신 로그(Communication logs)는 감사 내용(audit content)이 존재할 경우 평문(plaintext)을 사용하며, 읽기 가능한 메시지 텍스트로 제시된 필드에 암호문(ciphertext)을 절대로 대체하여 넣지 않습니다.
- 재개/재생(Resume/replay) 시에는 감사 사본(audit copy)을 자식 모델 컨텍스트(child model context)에 주입하지 않고 그대로 보존합니다.
- 기존의 평문 v1 통신 동작은 변경되지 않습니다.
- 회귀 테스트(Regression tests)는 세 가지 v2 도구 모두를 다루며, 계약(contract)의 양측 모두를 확인합니다: 읽기 가능한 로컬 감사 데이터(local audit data)와 암호화된 수신자 모델 입력(encrypted recipient-model input).
AI 자동 생성 콘텐츠
본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기