Skip to content

test: Server·Brain 로컬 실행 연동과 S07 경합 인수 [1.87] - #240

Merged
chowon442 merged 3 commits into
feat/s07-run-coordinationfrom
worktree-task-1.87
Oct 19, 2026
Merged

chowon442 merged 3 commits into
feat/s07-run-coordinationfrom
worktree-task-1.87

Conversation

@chowon442

@chowon442 chowon442 commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

📌 관련 이슈

🏷️ PR 타입

  • ✅ 테스트 추가 (Test)
  • ♻️ 리팩토링 (Refactoring) — 구형 내부 token 진입점 제거
  • 📝 문서 수정 (Documentation)

📝 작업 내용

단계 3 (9b5953f) — 빈 DB Java 경로와 구형 경로 잔여 참조 제거

  • RunPathEndToEndPostgresTest: 빈 baseline → 실제 HTTP 접수 → coordinator → BrainRunClient(loopback 가짜) → terminal transaction → POST SSE → GET replay 바이트 동일, row 수·순사용량, session/thread 열 없음, 실행·사용량 route는 신규 경로뿐
  • LegacyExecutionPathGuardTest: ChatSession·thread ID·/stream/v2·구형 AI client·토큰 누적·/api/credits/use|costs|estimate·X-Internal-Token 회귀 금지, deductCredit 호출자는 RequestUsageService뿐, Brain 호출 경로가 사용자 identity를 읽지 않음
  • 제거: 아무것도 지키지 않던 구형 agent → Server 내부 API token filter(/internal/**)와 internal.api.* 설정

단계 4 (05c0553) — 실제 Python Brain 연동 인수, 리뷰 r187 반영 (9173b1b)

  • com.proovy.integration.brain.ServerBrainIntegrationTest (18): 한 Postgres database에 빈 제품 baseline(proovy_server Flyway)·Brain schema(Brain db bootstrap·migrate)·role-boundary.sql, Server는 production bean 그대로, Brain은 testkit 실제 내부 API·run driver·PgRuntimeBackend·graph
  • BrainTestkit(supervisor·control client), scripts/brain-integration/run-local.sh(격리 Postgres → supervisor → warm-up → Gradle → 정리)
  • docs/contracts/brain-integration.md: Verification 대응표, fake·scripted·미검증 구분, S08 외부 계약, S13 복구 경계
  • README 연동 테스트 절, CI에 "Real Brain integration NOT EXECUTED" warning step(추가형)

S07 Verification 대응 (실제 HTTP/SSE/DB, Brain 7b8608e)

# 검사 결과
1 빈 DB 첫 텍스트 접수, noteId 없는 같은 requestId 5건 동시, 같은 Note 4건 동시 Note·run·차감·Brain 실행 각 1, 같은 Note는 1건 접수·3건 409 RUN4091(activeRunId), 거부는 메시지·run·차감 없음
2 POST live = GET replay, 브라우저 Last-Event-ID 재접속, 내부 SSE 첫 frame 전 abort, terminal 저장 후 전달 abort 바이트 동일·seq 연속, 같은 attempt·fence OBSERVE 재부착, status로 저장 terminal 회수, source event 중복 0, graph 1회
3 RUNNING 취소 vs 늦은 완료, PENDING 취소, 요청 deadline 경합, Brain fake clock deadline, 이전 fence 변조, coordinator 재시작(같은 JVM stop()/start(), 프로세스 재시작 아님), Brain 저장 전 SIGKILL 단언: terminal event 정확히 1·보상 ≤ 1·재실행 0, Brain fake clock은 Brain timeout terminal로 확정, 저장 전 소실은 Brain record executing(재개 없음)·Server provider_error 한 번 보상. 실측(승자 고정 안 함): deadline 경합은 Server sweep이 확정
4 결과별 순사용량 solve·check·explain·미검증 공개·혼합·자료 부재(scripted) 1, clarification·unsupported_only·verification_failed·provider_error·PENDING 취소·deadline 0, RUNNING 취소 1
5 fingerprint·fixture·scope/provenance Brain record fingerprint = ai_runs.request_fingerprint, Brain fixture sha256 = Server PIN 전부(manifest·파일), scope 밖 asset(scripted) → FAILED internal_error·출처/solution 없음, 다른 run envelope(stream+status, scripted) → FAILED·미저장, 이전 fence(stream, scripted) → 버리고 저장 terminal 회수

보안: Brain이 받은 호출 전부 shared token, body에 사용자 JWT·Bearer·grant·read_url 없음 / token 없음·사용자 JWT·틀린 token은 Brain 401·403 / 브라우저 frame·대화 조회에 fence·grant·read URL·서비스 token 없음 / 같은 DB에서 brain_runtime→public.ai_runs 42501, proovy_server→brain_runtime.run_records 42501.

r187 r2 권고 확인: out_of_scope_source·rewrite_terminal(+rewrite_status)이 Pg 경로(PgRuntimeBackend)에서 동작함을 위 V5 테스트로 확인했다(scripted terminal은 Brain Postgres store에 저장되고 status로도 회수된다).

📸 스크린샷

실행 명령 (로컬, 격리 자원 proovy-postgres-t187:26432, supervisor 26081, Brain API 26080)

BRAIN_DIR=<proovy-brain checkout @ 7b8608ee345761526aee0c76186ca984b496f41e> PG_CONTAINER=proovy-postgres-t187 GRADLE_IN_DOCKER=1 \
  scripts/brain-integration/run-local.sh 'com.proovy.integration.brain.*' \
  'com.proovy.domain.run.coordinator.RunPathEndToEndPostgresTest' 'com.proovy.global.LegacyExecutionPathGuardTest'
  • head 9173b1bfaee9ed89c7e2c4c768f96e39a9059b50 × Brain 7b8608ee345761526aee0c76186ca984b496f41e(clean), PROOVY_REQUIRE_BRAIN_IT=true
  • 실행 A: ServerBrainIntegrationTest 18/18, RunPathEndToEndPostgresTest 3/3, LegacyExecutionPathGuardTest 5/5 — skip 0, > Task :test 실행
  • 실행 B(곧바로 같은 소스·build/test-results를 지우지 않고 재실행, testClasses UP-TO-DATE): > Task :test 실제 실행 18/18 skip 0 — test --rerun
  • 스크립트 결과 검증: 이번 실행이 만든 TEST-com.proovy.integration.brain.*.xml이 tests>0·skipped/failures/errors=0이 아니면 실패. 음성 확인: skipped=18 XML → 실패, 실행 전 시각의 stale XML → 실패
  • 정리: 두 실행 뒤 testkit supervisor·child 0, 컨테이너 0 (/brain/stop + setsid 프로세스 그룹 종료)
  • testkit 없이(CI 조건) 같은 클래스는 18 skipped(통과 아님) + stderr NOT EXECUTED — … + CI warning step. 전체 ./gradlew test는 CI로 확인.

리뷰 r187 반영 (9173b1b)

  • [차단 1] run-local.sh: test --rerun으로 UP-TO-DATE 0건 실행을 막고, 결과 XML(이번 실행·tests>0·skip 0)을 검사해 아니면 exit 1
  • 2: supervisor를 setsid로 띄워 cleanup이 /brain/stop → 프로세스 그룹 종료 → 남은 child 정리, pg_isready·supervisor 대기 60s 초과 시 실패
  • 3: ServerBrainIntegrationTest·RunPathEndToEndPostgresTest에 @DirtiesContext
  • 4: runningCancel·deadlineRace·brainLostBeforeStorage·serverRestart의 hold 해제·SSE close를 finally로
  • 5: JwtAuthenticationFilter의 /internal JWT 우회 제거 + LegacyExecutionPathGuardTest.securityHasNoInternalPathCarveOut, internal-run-v1.md 잔여 서술 정정
  • 6: SseClient reader 판독 오류를 test thread로 다시 던지고 여러 data: 줄을 결합
  • 7: 잔액 단언을 요청별 차감액으로, 저장 전 소실 provider_error 단언 추가, deadline 승자는 실측으로 표기, coordinator 재시작은 같은 JVM으로 명시. SseClient·newUser seed 중복 정리는 후속

✅ 체크리스트

  • 코드 리뷰를 받을 준비가 완료되었습니다
  • 테스트를 작성하고 모두 통과했습니다 (로컬 연동 결과 위, 전체는 CI)
  • 문서를 업데이트했습니다 (docs/contracts/brain-integration.md, README)
  • 코드 스타일 가이드를 준수했습니다
  • 셀프 리뷰를 완료했습니다

📎 기타 참고사항

  • CI skip (사용자 결정): proovy-brain이 private이라 Server CI는 실제 Brain 연동을 실행하지 않는다. CI 로그의 warning과 JUnit skipped로 드러난다. 결과는 위 로컬 명령·commit으로 재현한다.
  • fake·scripted 구분: 모델·Daytona는 offline fake seat(수학 품질 미인증). no_match_notice·out_of_scope_source·rewrite_terminal은 testkit scripted(실제 Brain store·SSE 경유).
  • 미검증 (S14): 실제 유료 모델 품질·비용, Cloud Run ID token·IAM, Supabase/GCS·실제 자산 업로드(자산은 1.81 seeded 계약 자료로만), 부하·다중 인스턴스, 브라우저 화면.
  • 공용 호스트 부하 대응: supervisor child readiness가 60초 고정이라 스크립트가 child를 미리 띄워 데우고, Java client는 did not become ready일 때만 start·restart를 최대 3번 재시도한다. Brain 쪽 readiness 설정화는 후속 메모.
  • S13 인계: Brain 저장 전 소실 뒤 Brain record는 executing으로 남는다(Brain lease sweep·cleanup 호출은 S13). Server는 runtime_cleanup_at 예약까지.
  • 후속 메모: testkit release·clock route의 잘못된 JSON → 500(r187 r2), deploy.yml의 미사용 secret PROOVY_AI_HOST·INTERNAL_API_TOKEN(S14 정리 후보, 파일 미변경), browser-run-v1 다음 consumer_version 이월 항목(대화 조회 before/limit·superseded 표시·U+0000·viewerFocus.page 상한), internal-run fingerprint latex·viewer 없는 케이스, SafeMarkdown CR, FINAL_CHECK 전 Brain cancel용 CancelCause — 모두 이 PR은 계약을 바꾸지 않았다.
  • 공용 설정 변경: .github/workflows/ci.yml warning step 추가, application.yaml·application-test.yaml에서 internal.api.* 제거(읽는 코드 없음). migration 추가 없음.

🤖 Generated with Claude Code

chowon442 and others added 2 commits October 19, 2026 10:12
- RunPathEndToEndPostgresTest: 빈 baseline에서 HTTP 접수→coordinator→BrainRunClient(loopback 가짜)
  →terminal transaction→POST SSE→GET replay 바이트 동일, 순사용량·row 수, 구형 테이블·route 없음
- LegacyExecutionPathGuardTest: ChatSession·thread ID·구형 stream/client·토큰 누적·기능별 사후 차감·
  브라우저 임의 차감·구형 내부 token 진입점·Brain 경로의 사용자 identity 읽기 회귀 금지
- 구형 agent → Server 내부 API token filter(X-Internal-Token, /internal/**)와 internal.api 설정 제거
  (대상 controller는 1.74에서 제거됨)
- support/http: 실제 HTTP 브라우저 run client·SSE reader (단계 4와 공용)

Refs #226

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ServerBrainIntegrationTest: 같은 DB의 빈 제품 baseline(proovy_server)·Brain schema(bootstrap)·role 경계 위에서
  실제 HTTP 접수→coordinator→BrainRunClient→proovy-brain testkit(7b8608e) 내부 API·graph→terminal transaction→SSE.
  중복·같은 Note 충돌, 결과 분류별 순사용량, 브라우저 재접속·내부 SSE 유실·저장 후 유실, Server 재시작, Brain 저장 전
  SIGKILL, RUNNING/PENDING 취소, deadline 경합·Brain fake clock, fingerprint·fixture sha256 일치, scope 밖 출처·변조
  envelope(scripted) 거부, JWT 비전달·서비스 인증 거부·브라우저 비노출·역할별 DB 격리
- BrainTestkit: supervisor·control client. 미구성 시 "NOT EXECUTED" 이유로 skip, PROOVY_REQUIRE_BRAIN_IT=true면 실패
- scripts/brain-integration/run-local.sh: 격리 Postgres→testkit supervisor→Gradle→정리 (Server CI는 skip, 사용자 결정)
- CI: real-Brain 연동 미실행을 warning으로 드러내는 step
- docs/contracts/brain-integration.md: Verification 대응표, fake·scripted·미검증 구분, S08 외부 계약·S13 복구 경계 인계
- README: 연동 테스트 실행·CI skip 명시

Closes #226

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chowon442

Copy link
Copy Markdown
Member Author

CI (run 39193762845, head 05c0553): test pass. 실제 Brain 연동 ServerBrainIntegrationTest는 CI에서 18 skipped (통과 아님) — 로그에 [brain-integration] NOT EXECUTED — …, step 'Report real-Brain integration tests NOT EXECUTED'가 ##[warning] … tests="18" skipped="18"를 남긴다. 실제 연동 결과는 본문 로컬 실행(18/18, Brain 7b8608e) 기준. 그 밖 테스트 실패 0.

- 차단: run-local.sh가 `test --rerun`으로 항상 실제 실행하고, 이번 실행의 TEST-com.proovy.integration.brain.*.xml이
  tests>0·skipped/failures/errors=0이 아니면 실패한다(UP-TO-DATE·skip을 통과로 위장하지 않음)
- 정리: supervisor를 setsid로 띄워 /brain/stop 뒤 프로세스 그룹 전체 종료, 남은 child도 정리, readiness 루프 60s 초과 시 실패
- 테스트: coordinator 켠 두 클래스에 @DirtiesContext, hold 해제·SSE close를 finally로, 요청별 차감액으로 잔액 단언,
  저장 전 소실 provider_error 단언, coordinator 재시작은 같은 JVM stop/start로 명시
- SseClient: reader 판독 오류를 test thread로 전달, 여러 data 줄을 SSE 규칙대로 결합
- JwtAuthenticationFilter의 /internal JWT 우회 제거(대상 endpoint 없음) + 회귀 검사, internal-run-v1.md 잔여 서술 정정

Refs #226

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chowon442

Copy link
Copy Markdown
Member Author

리뷰 r187 반영 push: head 9173b1b. CI(run 39207782298) test pass — 실제 Brain 연동은 CI에서 18 skipped(통과 아님, NOT EXECUTED·warning). 로컬 실연동은 본문 '스크린샷' 절(실행 A·B 모두 > Task :test 실제 실행 18/18 skip 0).

@chowon442
chowon442 merged commit 51212f0 into feat/s07-run-coordination Oct 19, 2026
1 check passed
@chowon442
chowon442 deleted the worktree-task-1.87 branch October 19, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant