
「슬슬 끝났으려나」 하고 확인하러 가지 않기 — Codex의 완료·정지·입력 대기 상태를 Teams로 받기
요약
Codex 작업의 완료, 정지, 입력 대기 상태를 Microsoft Teams로 실시간 알림 받는 자동화 메커니즘을 소개합니다. Python과 Power Automate를 활용하여 보안을 유지하면서도 효율적인 작업 흐름을 구축하는 설계 원칙을 다룹니다.
핵심 포인트
- Codex의 notify 기능을 활용한 외부 알림 시스템 구축
- 작업 상태(완료, 정지, 대기)를 구분하여 Teams로 전송
- 보안을 위해 알림 전용 스키마 사용 및 기밀 정보 폐기 설계
- Power Automate를 경유한 Webhook 기반 알림 경로 구현
1. Codex 화면을 다시 확인하는 횟수를 줄이고 싶다
Codex에 구현, 테스트, 리뷰를 한꺼번에 의뢰하면 완료될 때까지 잠시 기다려야 할 때가 있습니다.
제 환경에서는 Windows 상의 VS Code에서 SSH 접속을 하고, 그 너머의 Dev Container 내에서 Codex를 사용하고 있습니다. 여러 프로젝트를 다루게 되면서, 작업이 끝났는지 확인하기 위해서만 VS Code로 돌아가는 작은 중단이 신경 쓰이기 시작했습니다.
제가 원했던 것은 Codex의 대화를 Teams로 전송하는 메커니즘이 아닙니다.
- 의뢰한 작업이 완료됨
- 안전 조건이나 검증 실패로 인해 정지됨
- 이용자의 판단이 필요해짐
이 세 가지만 알아차릴 수 있는 부차적인 알림 경로입니다.
그래서 Codex의 notify로부터 Python으로 구현한 알림 프로그램을 실행하고, Power Automate를 경유하여 Teams로 알림을 보내는 메커니즘을 만들었습니다.
전체 흐름은 다음과 같습니다.
구현에서 가장 고민했던 것은 Webhook의 호출 방법이 아닙니다.
Codex가 가진 정보 중 무엇을 Teams로 보내도 되는가를 결정하는 것이었습니다.
이 기사에서는 알림 경로를 만드는 법을 모두 재현하는 것이 아니라, 다음의 설계 판단을 중심으로 설명합니다.
- Codex가 1회의 응답을 마친 것과 의뢰 전체의 완료를 구분한다
- 입력 문장이나 응답 전문을 보내지 않고, 알림 전용 스키마(Schema)만 보낸다
- 기밀 정보로 보이는 값을 검출하면, 마스킹하지 않고 알림 전체를 폐기한다
- 알림 실패로 인해 Codex 본체의 작업 결과가 실패로 처리되지 않게 한다
- 알림 프로그램과 Power Automate 양쪽 모두에서 알림 데이터를 검증한다
notify의 기본 동작을 이해하기
- 우선, Codex에는 이름이 비슷한 두 가지 알림 기능이 있습니다.
| 알림 기능 | 역할 | 이번에 채택함 |
|---|---|---|
notify | 대응 이벤트가 발생했을 때 외부 프로그램을 실행한다. Webhook이나 데스크톱 알림 등, Codex 외부로 알림을 보내고 싶을 때 사용한다 | 채택 |
tui.notifications | Codex의 터미널 화면에 내장된 알림. 표시 조건이나 대상 이벤트를 설정할 수 있다 | 미채택 |
이번에는 Power Automate로 Webhook을 보내고 싶기 때문에, 외부 프로그램을 실행할 수 있는 notify를 선택했습니다.
여기서 알림 기능과 이벤트 이름을 나누어 생각할 필요가 있습니다.
| 계층 | 이번에 사용한 것 | 의미 |
|---|---|---|
| Codex의 알림 기능 | notify | 외부의 알림 프로그램을 실행하는 메커니즘 |
| Codex의 이벤트 | agent-turn-complete | Codex가 1회의 응답 처리를 마쳤음을 알리는 이벤트 |
| 이번에 추가한 상태 | COMPLETED, STOPPED, WAITING_INPUT | 이용자가 알고 싶은 작업 상태 |
공식 문서에 표시된 알림 이벤트의 예는 다음과 같습니다.
| 이벤트 | 발생하는 상황 | 사용할 수 있는 알림 기능 |
|---|---|---|
agent-turn-complete | Codex가 1회의 응답 처리를 마쳤다 | notify, tui.notifications |
approval-requested | Codex가 이용자에게 조작 승인을 요청했다 | tui.notifications의 대상 이벤트 예 |
집필 시점에서는 외부 알림인 notify가 대응하는 이벤트는 agent-turn-complete뿐입니다.
이번에 여러 외부 알림 이벤트 중에서 agent-turn-complete를 선택한 것은 아닙니다. Teams로 알림을 보낼 수 있는 notify를 채택했고, 거기서 받을 수 있는 agent-turn-complete를 입구로 삼았습니다.
설정은 다음과 같이 사용자 단위의 config.toml에 기재합니다.
# Codex가 대응 이벤트를 냈을 때, 고정된 알림 프로그램을 실행한다
notify = ["/home/vscode/.codex/bin/codex-teams-notify"]
알림 프로그램에는 무엇이 전달되는가
notify는 외부 프로그램을 실행할 때, 이벤트 정보를 정리한 1개의 JSON을 인자로 전달합니다.
그 JSON에는 이벤트의 종류나 작업 디렉토리 등에 더해 다음 정보도 포함됩니다.
last-assistant-message
:직전 1회 최종 응답 전문
input-messages
:해당 응답으로 이어진 사용자의 입력
여기서 말하는 최종 응답 전문은 스레드의 대화 이력 전체가 아닙니다. Codex가 직전 턴(turn)에서 사용자에게 반환한 1회분의 최종 응답입니다.
기본적인 흐름은 다음과 같습니다.
즉, notify는 "Teams로 알림을 보내는 기능" 그 자체는 아닙니다. Codex가 이벤트 JSON을 외부 프로그램에 전달하는 것까지를 담당하며, 그 이후에 무엇을 할지는 외부 프로그램 측에서 결정합니다.
agent-turn-complete는 의뢰 전체의 완료를 의미하지 않는다
agent-turn-complete는 Codex의 1회 처리 단위(turn)가 종료되었음을 나타냅니다. 이것이 반드시 "의뢰된 작업 전체가 완료되었다"는 의미는 아닙니다.
반면, 이번에 Teams를 통해 알고 싶은 것은 다음 3가지 상태입니다.
| 이번에 추가한 상태 | 의미 |
|---|---|
COMPLETED | 의뢰된 완료 경계에 도달함 |
STOPPED | 안전 조건, 검증 실패, 전제 불일치 등으로 정지함 |
WAITING_INPUT | 사용자의 판단 또는 조작 결과가 필요함 |
이것들은 Codex에 원래 준비되어 있는 이벤트명이 아니라, 이번 알림용으로 추가한 상태입니다.
agent-turn-complete라는 이벤트명만으로는 이 3가지 상태에 해당하는 응답인지, 아니면 통상적인 설명이나 짧은 질의응답인지 구분할 수 없습니다. 이벤트가 발생할 때마다 전송하면, 알림이 필요 없는 응답까지 Teams로 보내지게 됩니다.
"알림을 보내지 않음"을 나타내는 네 번째 상태는 정의하지 않았습니다. 통상적인 응답에는 상태를 붙이지 않고, 후술할 알림 마커(notification marker) 자체를 추가하지 않음으로써 구분합니다.
| 최종 응답 패턴 | 알림 마커 | 알림 프로그램의 동작 |
|---|---|---|
| 통상적인 설명이나 짧은 질의응답 | 없음 | 아무것도 보내지 않고 종료함 |
| ... |
3. 기본 동작을 바탕으로 알림 대상과 전송 내용을 압축하기
이번 구현에서는 notify로부터 받은 이벤트 JSON을 그대로 Webhook으로 전달하지 않습니다.
last-assistant-message에서 알림 전용 정보만 추출하여, 검증된 짧은 알림 데이터를 새로 구성하여 Teams로 보냅니다.
방침을 정리하면 다음과 같습니다.
| 구분 | 방침 |
|---|---|
| 알림 대상 | COMPLETED, STOPPED, WAITING_INPUT만 |
| Teams로 보내는 내용 | project, status, task, summary 등 허가 리스트(allowlist)에 정의된 필드 |
| 보내지 않는 내용 | 입력문, 응답 전문, 커맨드, 표준 출력(stdout), 표준 에러 출력(stderr), 헤더, .env 값 |
| 기밀 정보 탐지 | 해당 부분을 마스킹(masking)하지 않고, 알림 전체를 폐기 |
| Webhook URL | 기밀 정보로 취급하여, 허가된 호스트 이외로는 보내지 않음 |
| ... |
알림 대상을 판별할 수 있도록, 알림을 보내고 싶은 최종 응답의 끝에 고정 형식의 알림 마커를 2줄 추가하기로 약속했습니다.
이 2줄을 알림 프로그램이 나중에 덧붙이는 것이 아닙니다. 리포지토리 직하의 AGENTS.md에 최종 응답 규칙을 정의하고, Codex 스스로가 알림 대상인 최종 응답을 만들 때 본문에 이어서 알림 마커를 생성합니다.
| 처리 | 담당 |
|---|---|
| 알림 마커의 형식과 출력 조건을 정의함 | 리포지토리 직하의 AGENTS.md |
| 최종 응답 끝에 알림 마커를 생성함 | Codex |
| 최종 응답을 포함한 이벤트 JSON을 전달함 | notify |
| 알림 마커를 해석·검증하여 전송함 | Python으로 구현한 알림 프로그램 |
AGENTS.md에는 완료, 정지, 사용자 입력 대기 상태의 최종 응답에만 다음 2줄을 추가하도록 기재되어 있습니다. 통상적인 설명, 중간 경과, 짧은 답변에는 추가하지 않습니다.
CODEX_STATUS=COMPLETED
CODEX_NOTIFY={"schema_version":1,"project":"example-project","status":"COMPLETED","task":"인증 기능 구현","summary":"구현 및 자동 테스트가 완료되었습니다"}
CODEX_STATUS는 응답 끝을 판별하기 위한 단순한 상태 행이며, JSON 내의 status
알림 데이터로 사용하는 상태입니다. 두 값이 동일한지 검증하며, AI가 생성한 2줄 사이에 불일치가 있다면 전송하지 않습니다.
알림 프로그램은 다음 순서로 처리합니다.
notify로부터 받은 이벤트 JSON을 검증한다last-assistant-message에서 직전 1회의 최종 응답 전문을 추출한다- 빈 줄을 제외한 응답 끝의 2줄만 확인한다
- 2줄의 알림 마커(Notification Marker)를 분석하여 상태와 알림 데이터를 검증한다
- 검증된 항목만으로 Teams용 데이터를 새로 구성한다
- Power Automate로 전송한다
문장, 인용, 코드 블록 중간에 동일한 문자열이 있더라도 알림을 보내지 않습니다. CODEX_STATUS=COMPLETED임에도 JSON 측이 STOPPED라면 거부합니다.
알림 마커 자체를 AI가 생성하게 하므로, 이것만으로는 신뢰 경계(Trust Boundary)가 될 수 없습니다. 알림 마커는 '알림 후보를 선택하는 조건'일 뿐이며, 그 이후 알림 프로그램에 의한 스키마 검증이 필요합니다.
4. 응답 전문이 아닌 알림 전용 스키마를 만든다
last-assistant-message를 그대로 Teams로 보내는 방안은 채택하지 않았습니다.
최종 응답에는 작업 내용에 따라 다음과 같은 정보가 포함될 가능성이 있습니다.
- 명령어 또는 파일 경로
- 내부 호스트 이름
- 에러 상세 내용
- API 응답
- 설정값
- 고객 또는 설비 관련 정보
input-messages에는 사용자의 요청 문구가 있습니다. 이 또한 알림에는 필요하지 않습니다.
Teams로 전송할 수 있는 정보는 처음부터 작은 스키마로 한정했습니다.
{
"schema_version": 1,
"project": "example-project",
...
필수 필드는 다음 5개입니다.
schema_version
project
status
task
summary
next_action이나, 허가된 GitHub Issue / Pull Request에 대한 artifact는 선택 사항(Optional)으로 두었습니다. 알 수 없는 필드는 허용하지 않습니다. 필드마다 타입, 글자 수, 제어 문자, URL 형식을 검증합니다.
반면, 다음 정보는 알림 대상으로 삼지 않습니다.
입력 문장
대화 전문
last-assistant-message의 전문
...
여기서 중요한 것은, 금지 목록(Deny List)으로 위험한 항목을 지우는 것보다, 보내도 좋은 필드만을 허용 목록(Allow List)으로 정의하는 것입니다.
5. 기밀 정보로 의심되는 값은 마스킹하지 않고, 알림 전체를 버린다
task나 summary는 자유 기술형입니다. 생성 측에 "기밀 정보를 쓰지 말 것"이라고 지시하더라도, 그것만으로는 안전 경계(Safety Boundary)를 확보할 수 없습니다.
알림 프로그램 측에서도 기밀 정보일 가능성이 높은 인증 정보 형식을 정규 표현식(Regular Expression)으로 검사합니다.
검사 대상은 최종 응답 전문이 아닙니다. 알림 마커에서 추출하여 Teams 전송 후보가 된 project, status, task, summary, next_action, artifact 등의 필드입니다. 이 값들을 연결하여 준비된 정규 표현식 중 어느 하나라도 일치하는지 조사합니다.
- 비밀키(Private Key) 시작 마커
Authorization또는Bearerpassword=,token=,client_secret=- GitHub, OpenAI, AWS 등의 특징적인 토큰 접두사(Prefix)
- 사용자 정보를 포함하는 URI
- 인증 정보를 포함하는 연결 문자열(Connection String)
- Power Automate의 콜백 URL 형태
처리를 간략화하면 다음과 같습니다.
def contains_high_confidence_secret(values: list[str]) -> bool:
# Teams로 보낼 후보 필드들만 검사용 문자열로 합침
combined = "\n".join(values)
...
필드의 타입, 글자 수, 제어 문자, URL 형식을 먼저 검증한 후에 이 검사를 수행합니다. CODEX_NOTIFY_ENVIRONMENT에 대해서도 설정값을 표시하지 않고, 읽어들인 값과 해석 후의 값을 동일한 패턴으로 검사합니다.
검출되었을 경우, 해당 부분만 ***로 교체하여 보내는 것이 아니라 알림 전체를 폐기합니다.
마스킹 (Masking) 방식으로는 검출된 부분만 숨기고 "안전해졌다"라고 오인할 가능성이 있습니다. 예를 들어 서명된 URL (Signed URL)의 쿼리 일부만 마스킹하더라도, 다른 부분에 인증 정보가 남아 있을 수 있습니다.
기밀 정보일 가능성을 검출한 알림 데이터는 부분적으로 구제하지 않는 편이 단순합니다.
물론, 정규 표현식 (Regular Expression)으로 모든 기밀 정보나 개인 정보를 검출할 수 있는 것은 아닙니다. 따라서 다음과 같은 경계(Boundary)를 중첩하여 적용합니다.
- 생성 측에서 통지 금지 정보를 명시한다
- 통지 프로그램에서 허가 리스트 (Allowlist)의 스키마와 기밀 정보일 가능성이 높은 형식을 검사한다
- Power Automate에서도 구조와 값을 재검증한다
- Teams의 열람자를 통지 대상자로 한정한다
- 상세 확인은 원본 데이터로 돌아가서 수행한다
.env를 셸 (Shell)로 읽지 않는다
- 통지 프로그램은 프로젝트명, Webhook URL, 실행 환경명을 리포지토리 직하의
.env에서 읽습니다.
APP_NAME=example-project
CODEX_NOTIFY_WEBHOOK_URL=<Power Automate가 발행한 콜백 URL>
CODEX_NOTIFY_ENVIRONMENT=dev-container-01
단, .env를 source 하지 않습니다.
# 이 방식은 채택하지 않는다. .env를 셸 코드로 평가해 버린다
source .env
필요한 키(Key)만 KEY=VALUE 형태로 해석하며, 다음을 확인합니다.
- 일반 파일이며, 심볼릭 링크 (Symbolic Link)가 아니다
- 실행 사용자의 소유이다
- 권한이
0600이다 - 키가 중복되지 않았다
- 읽는 도중에 파일의 동일성이 변하지 않았다
Webhook URL도 단순히 https://로 시작하는지만으로는 판정하지 않습니다. 표준 URL 분석 기능을 사용하여 분해하고, 스킴 (Scheme), 호스트명 (Host name), 포트 (Port), 사용자 정보 (User info), 프래그먼트 (Fragment), 경로 (Path)를 검사합니다.
전송 대상은 Power Automate가 발행하는 허가된 호스트로 한정하며, 리다이렉트 (Redirect)를 추종하지 않습니다.
이는 통지 프로그램을 임의의 HTTPS 엔드포인트로 데이터를 보낼 수 있는 범용 송신기(Generic transmitter)로 만들지 않기 위해서입니다.
CODEX_NOTIFY_ENVIRONMENT가 누락되었거나, 비어 있거나, 일반적인 형식 오류인 경우에는 실행 환경명만 생략하고 통지를 계속합니다. 반면, 기밀 정보 같은 형식이나 키 중복 등의 구조적 오류를 검출한 경우에는 통지 전체를 거부합니다. 표시상의 미비함과 보안상의 이상을 동일한 실패 조건으로 취급하지 않기 위해서입니다.
콜백 URL은 기밀 정보로 취급한다
Power Automate 측에서는 Microsoft Teams 커넥터의 When a Teams webhook request is received를 사용했습니다. 이 트리거는 호출자를 "누구나(Anyone)", "테넌트 내의 이용자", "테넌트 내의 특정 이용자" 중에서 선택할 수 있습니다.
이번 시도 도입에서는 통지 프로그램에 Microsoft Entra ID 액세스 토큰을 부여하지 않기 위해 Anyone을 선택했습니다.
이 구성에서는 콜백 URL을 알고 있는 것이 실질적인 액세스 조건이 됩니다.
따라서 URL은 다음 장소에 노출하지 않는 운용 방식을 택했습니다.
- Git
- Issue나 Pull Request
- 채팅
- 터미널 출력
- 커맨드 인자 (Command argument)
- 로컬 로그
- 화면 캡처
Anyone을 안전한 인증 방식으로 일반화하려는 의도는 아닙니다. 테넌트의 정책이나 용도에 맞지 않는 경우에는 인증 방식을 다시 설계해야 합니다.
7. Power Automate에서도 수신한 카드를 신뢰하지 않는다
통지 프로그램은 검증된 필드를 Adaptive Card의 요청 형식으로 변환하여 보냅니다.
하지만 Power Automate 측에서는 수신한 카드를 그대로 Teams에 게시하지 않습니다.
Power Automate의 플로우 (Flow)에서는 최소한 다음을 검사합니다.
- 최상위(Top level)와
attachments의 요소 수 - Adaptive Card의
type과version body요소의type,id, 순서facts의title, 순서, 중복, 미지의 요소- 필드의 타입과 길이
status와project의 형식artifact의 URL- 인증 정보 같은 문자열
검증을 통과한 값만 추출하여, 고정 템플릿으로부터 Teams용 카드를 다시 만듭니다.
알림 프로그램 측의 검증이 주요 경계이지만, 콜백 URL(callback URL)을 아는 주체는 알림 프로그램을 우회할 수 있습니다. Power Automate 측의 재검증은 그러한 우회를 전제로 한 다층 방어 (defense in depth)입니다.
프로젝트별 채널로 분류하기
프로젝트마다 Webhook을 늘리는 대신, 하나의 Power Automate 플로우 (flow)를 공통 라우터로 만들었습니다.
형식은 올바르지만 매핑(mapping)이 없는 프로젝트는 알림을 묵묵히 버리지 않습니다. 설정 누락을 인지할 수 있도록 퇴피 채널로 보냅니다.
단, 퇴피용 카드에는 자유 기술(free text) 내용을を引き継ぎ지 않습니다.
- 프로젝트
- 상태
- 이벤트 ID
- 수신 일시
- 알림 대상 미설정
이 최소한의 메타데이터(metadata)만을 Power Automate 측의 고정 템플릿으로 표시합니다.
8. 알림 실패로 Codex의 작업을 실패로 만들지 않기
알림은 편리하지만, 개발 작업 그 자체는 아닙니다.
구현과 테스트가 완료된 후, Power Automate의 일시적인 장애로 인해 알림만 실패할 수 있습니다. 이때 Codex의 작업 결과까지 실패로 변경하면, 정본(source of truth)과 알림 경로의 상태가 뒤섞이게 됩니다.
따라서 실행 시의 알림은, 알림에 실패하더라도 Codex의 작업 결과를 유지하는 설계 (fail-open)로 했습니다.
반면, 셋업(setup), 설정 확인, 자기 검사는 설정 오류를 발견하면 0이 아닌 종료 코드로 정지합니다.
| 처리 | 방침 |
|---|---|
| 실행 시의 알림 | 알림에 실패해도 작업 결과를 유지함 (fail-open) |
| 셋업 / 설정 확인 / 자기 검사 | 이상을 검출하면 정지함 (fail-closed) |
HTTP 송신은 타임아웃(timeout), 연결 실패, 429, 5xx 에 대해서만 최대 2회까지 시도합니다. 4xx나 스키마(schema) 오류는 재시도하지 않습니다.
동일한 이벤트의 재시도 시에는 요청 본문(request body)을 다시 만들지 않고, 동일한 이벤트 ID를 사용합니다. 이벤트 ID는 thread-id와 turn-id로부터 결정론적(deterministic)으로 생성하지만, 원래의 ID는 Teams로 보내지 않습니다.
Power Automate 측에 영구적인 중복 제거용 저장 영역을 마련하지 않았기 때문에, 요청 수락 후 응답만 유실될 경우 Teams에 중복 게시될 가능성이 있습니다.
소규모 개발 알림에서는 처음부터 엄격하게 단 한 번만 전달하는 것 (exactly-once)을 목표로 하기보다, 동일한 이벤트 ID로 중복을 식별할 수 있는 방식을 선택했습니다.
9. 셋업을 너무 자동화하지 않기
알림 프로그램의 소스(source)는 리포지토리(repository)에서 관리하지만, Codex가 직접 실행하는 것은 ${CODEX_HOME}/bin/에 설치된 사용자 환경의 실행 파일입니다.
리포지토리 관리 소스
-> 명시적인 셋업
-> ${CODEX_HOME}/bin/codex-teams-notify
...
notify는 실행 환경 내의 프로그램을 기동하는 설정입니다. Codex의 현행 사양에서는 프로젝트 단위의 .codex/config.toml에 두는 것이 아니라, 사용자 단위의 설정에 기재합니다.
리포지토리 상의 브랜치(branch)를 전환하는 순간, 알림 처리까지 암묵적으로 다른 버전으로 전환되는 것을 피하기 위해 리포지토리 내의 소스를 직접 지정하지 않았습니다.
또한, Dev Container 기동 시 자동으로 셋업되지 않도록 했습니다. Webhook URL을 준비하고, 이용자가 변경 예정 사항을 확인한 후 명시적으로 실행합니다.
셋업은 다음 4단계로 나누어져 있습니다.
| 단계 | 목적 |
|---|---|
| 변경 예정 확인 | 사용자 환경에 배치할 파일과 설정 변경을 반영 전에 확인한다 |
| ... |
셋업 처리는 기존의 config.toml을 전면 재생성하지 않습니다. 기존의 주석이나 MCP 설정을 유지하며, 서로 다른 notify가 있는 경우에는 덮어쓰지 않고 정지합니다.
10. 이 구성이 적합한 경우와 적합하지 않은 경우
이 구성은 다음 조건에서 사용하기 쉽다고 생각합니다.
- 장시간의 Codex 작업이 있으며, 완료, 정지, 이용자 입력 대기 상태만을 인지하고 싶다
- Microsoft 365와 Teams를 일상적으로 사용한다
- 알림과 작업 기록의 정본을 분리할 수 있다
- 알림 프로그램과 Power Automate 플로우 양측을 모두 유지보수할 수 있다
- 적은 양의 알림이며, 드문 중복은 허용할 수 있다
반면, 다음 조건에서는 다른 안을 검토하는 것이 좋습니다.
- 입력 문장이나 응답 전문을 Teams에서 검색하고 싶다
- 엄격하게 단 한 번의 전달 (exactly-once)이 필요하다
- 인증 방식이
Anyone
의 트리거를 허용할 수 없다 - 알림이 감사 기록이나 승인의 정본(source of truth)이 된다
- 플로우(Flow)의 소유자나 연결 설정을 지속적으로 관리할 수 없다
- 기밀 정보나 개인 정보가 포함될 가능성이 높은 업무에서 자유 기술(free-text)을 외부로 전송할 수 없다
단순히 수동으로 인지하는 것이 목적이라면, Codex의 TUI 알림이나 데스크톱 알림이 더 가볍게 만들 수 있습니다. Teams로 집약할 가치가 있는 경우는, 여러 환경의 알림 수신처를 통일하고 싶거나, 평소 업무 알림과 동일한 장소에서 인지하고 싶을 때입니다.
11. 요약
Codex의 notify를 Teams로 연결하기만 한다면, 받은 JSON을 Webhook으로 POST하는 짧은 스크립트로도 동작합니다.
하지만 실제로 고민해야 할 것은 송신 처리보다, 무엇을 알림으로 내보내도 되는가였습니다.
이번 구현에서는 다음과 같은 경계를 설정했습니다.
agent-turn-complete를 그대로 의뢰 완료로 해석하지 않는다 - 최종 응답의 알림 마커는 후보 선택에 사용하고, 알림 프로그램에서 재검증한다- 입력문이나 응답 전문을 보내지 않고, 허가 리스트(allowlist)로 정의된 짧은 스키마만 보낸다
- 기밀 정보로 의심되는 값을 감지하면 알림 전체를 폐기한다
.env를 셸(shell)로서 읽지 않고, Webhook URL의 송신처를 한정한다 - Power Automate에서도 알림 데이터를 검증하고, 고정된 카드(fixed card)를 재구성한다- 실행 시 알림은 작업 결과를 유지하고, 설정 검사는 이상 발생 시 정지한다
알림은 상세한 내용을 전달하는 곳이 아닙니다.
"무언가가 끝났다", "멈췄다", "판단이 필요해졌다"라고 안전하게 인지할 수만 있으면 되며, 상세한 내용은 정본(source of truth)으로 돌아가 확인합니다. 이 역할을 좁게 유지하는 것이 Codex의 알림을 오랫동안 운용하기 위한 토대가 된다고 생각합니다.
참고 자료
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기