Recipes

PG1 자체 운영 서비스: 예약 보고서, 발견 사항을 작업으로 전환, 롤백을 포함한 저위험 자동 병합

README 링크에서 발견 · today

Software & DevOpsWork & Operations

에이전트가 자체 운영을 수행: 일간/주간 보고서, 작업, 가드된 자동 병합

What they did

PG1(project-gifted1/pg1-ai-agent)은 병렬 시스템을 새로 구축하는 대신 기존의 자율성 정책, 기회 스캔, 자율 틱, 랩, watches/push, 승인 카드를 확장했습니다. 새 코드는 `lib/operator/`에 있으며 이들 기능에 훅으로 연결됩니다. 매일 07:15 UTC 크론(`api/operator/daily.mjs`)을 추가해 전일 대비 실제 사용량과 7일 평균, 최근 24시간 결제(402, 유료, 정산, `lib/usageVerify.mjs`를 통한 온체인), fault별 오류, 프로덕션 배포 및 상태, PG1이 자체적으로 수행한 작업, 다음 작업, 대기 중인 승인, 그리고 롤백이나 비라이브 머지로 프로덕션이 고정된 경우 맨 앞에 'Production is pinned' 섹션을 다룹니다. 매주 월요일 07:30 UTC 기회 스캔 크론은 06:41에서 이동했으며 주간 요청, 미충족 수요(real/probe 분리), 결제 퍼널, 디스커버리 상태, 실험 및 제안으로 확장되었습니다. 보고서는 저장되고, 채팅 카드로 표시되며, 기기로 푸시되고, PDF로 저장되며, `/report today`와 `/report week`로 조회할 수 있습니다. 읽을 수 없는 소스는 추정하지 않고 'not read'로 명시합니다. 각 발견 사항은 근거로 삼은 카운트와 함께 중복 제거된 하나의 작업(fix, improve, new, listing, pricing)이 되어 랩 실험, PR, 리스팅 준비 또는 가격 점검으로 라우팅됩니다. `code:merge_low_risk`를 추가했습니다. PG1_AUTONOMY=on이고 스위치가 켜진 경우에만 FREE이며, fix/improve 작업에서 나온 랩 PR로서 헤드 SHA에서 필수 CI 검사를 통과하고, 전체 diff를 읽고(300개 파일까지 페이지 처리, 모든 파일 패치), 약화되거나 삭제된 테스트가 없고, config/env/SQL 변경이 없고, 보호 경로가 없고, MCP 계약 변경이 없고, 변경 라인이 300줄 미만이고, 프로모션 게이트를 통과하고, 하루 3회 한 번에 하나씩이라는 상한을 충족하는 경우에만 해당합니다. 머지는 60분간 감시되며 배포 실패, Ready 아님, 또는 50% 초과 오류율/p95 회귀 시 롤백되고, 이어서 revert PR과 푸시가 수행됩니다. 롤백 후에는 프로덕션이 고정되고 자동 머지가 일시 중지되며, `/report resume`은 프로덕션이 최신 Ready 배포를 서빙한 뒤에만 재개합니다. 승인은 보고서에 표시되며 `task_decide` 또는 `/report approve|decline`을 통해 Approve/Decline할 수 있고, operator 외의 액터는 거부하며, 7일 후 만료됩니다.

How it went

#403 위에 PR로 올렸습니다(아직 병합되지 않음). 충돌은 양쪽을 모두 유지하는 방식으로 해결했습니다. `tests/operator.test.mjs`에는 reports, findings, 모든 disqualifying 규칙, stuck 검사, rollback 및 pinning, approvals, 마이그레이션을 다루는 82개의 테스트가 있습니다. lab 및 autonomy 테스트는 115/115 통과했고, report cards에 대한 브라우저 테스트도 통과합니다. 248db61의 CI는 `npm test`(테스트 파일이 `supabase.test`에 도달하면서 발생한 실패 하나로, e9b4ad8에서 수정됨)와 항상 빨간 상태인 Cloudflare Workers Builds 앱 체크를 제외한 모든 job을 통과했습니다. 최신 커밋에서는 아직 재실행하지 않았습니다.

Worth knowing

아직 명시적으로 병합하지 않습니다. 마이그레이션은 추가형이지만, 이미 20261113120000을 실행한 데이터베이스는 `pr_opened_at` alter 라인을 한 번 수동으로 실행해야 합니다. 자동 병합에는 `PG1_AUTONOMY=on`, `PG1_VERCEL_PROJECT_ID`(또는 노출된 `VERCEL_PROJECT_ID`), 그리고 contents 및 pull-requests write 권한이 있는 `GITHUB_TOKEN`이 필요합니다. `PG1_PAID_CALL_WORST_CASE_USD`와 `PG1_PRODUCTION_ALIAS`는 선택 사항입니다. Cloudflare Workers Builds 앱 체크는 항상 빨간색이며 의도적으로 무시합니다. CI는 최신 커밋에서 다시 실행되지 않았고, pin 체크는 Vercel aliases API에 의존합니다.

Wiring

(1) 추가 마이그레이션 `supabase/migrations/20261113120000_pg1_operator.sql`을 적용하여 `pg1_operator_reports`와 `pg1_operator_tasks`를 생성하고(RLS 켜짐, 정책 없음), `pr_opened_at`을 추가하며, `pg1_autonomous_actions.status`를 `expired`에 맞게 확장하고, 이전 파일을 이미 실행한 데이터베이스에서는 `alter table ... add column if not exists pr_opened_at` 라인을 한 번 실행합니다. (2) 환경 변수를 설정합니다: `PG1_AUTONOMY=on`, `PG1_VERCEL_PROJECT_ID`(또는 노출된 `VERCEL_PROJECT_ID`), contents + pull-requests write 권한이 있는 `GITHUB_TOKEN`, 선택 사항인 `PG1_PAID_CALL_WORST_CASE_USD`와 `PG1_PRODUCTION_ALIAS`(기본값 `pg1-ai-agent.vercel.app`), 기존 `VERCEL_TOKEN`, `VERCEL_TEAM_ID`, VAPID 키 및 lab 시크릿을 재사용합니다. (3) 매일 07:15 UTC에 실행되는 크론 `api/operator/daily.mjs`를 추가하고, opportunity-scan 크론을 월요일 07:30 UTC로 옮기며 확장된 섹션을 포함합니다. (4) 발견 사항을 key 기준으로 중복 제거하여 `pg1_operator_tasks`에 연결하고, lab, listing prep 및 pricing 검사를 공급합니다. (5) `lib/operator/`에 `qualifyPr`와 `code:merge_low_risk`를 구현하고, head SHA에서 GitHub API를 통해 CI를 읽으며(`npm test`와 `browser tests`만 인정), diff를 300개 파일로 페이지 처리하고, protected-path, test-weakening, config 및 size 규칙을 적용합니다. (6) `GET /v4/aliases/{alias}`를 통한 pre-merge alias 검사, 60분 watch, 그리고 `POST /v1/projects/{id}/rollback/{prevDeployment}`를 통한 롤백과 revert PR 및 push를 추가합니다. (7) 승인을 `task_decide`(operator 세션 전용) 또는 `/report approve|decline <id>`를 통해 라우팅하고, 해당 항목의 APPROVAL 액션을 `approved: true`로 실행합니다. (8) `/report today`, `/report week`, `/report resume`를 추가하고, `tests/operator.test.mjs`와 브라우저 report-card 테스트를 실행합니다.

Try it yourself

I'll start by reading the existing PG1 operator design to understand the current architecture before making changes.

<||DSML|| calls>
<||DSML|| invoke name="bash">
<||DSML|| parameter name="command" string="true">find . -path ./node_modules -prune -o -type f \( -name "*.mjs" -o -name "*.ts" -o -name "*.sql" \) -print | grep -E "(operator|autonomy|lab|usageVerify|pg1)" | head -50</||DSML|| parameter>
</||DSML|| invoke>
</||DSML|| calls>

Source

English

Tools in this stack