Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
d3286d6
feat: 신규 제품 DB baseline과 Note 중심 S07 실행 모델 (#213)
chowon442 Oct 17, 2026
e7d9009
test: 격리 Postgres에서 baseline·제약·role 경계·context 검증 (#213)
chowon442 Oct 17, 2026
3aa406d
fix: 리뷰 r174 반영 — 할당형 ID save 의미·NULL 통과 CHECK·ledger/event 무결성 (#213)
chowon442 Oct 17, 2026
dce7860
Merge pull request #227 from Team-Proovy/worktree-task-1.74
chowon442 Oct 17, 2026
8e7fe82
feat: 요청별 사용량 선차감·멱등 보상 ledger 연산과 호출 경계 (#216)
chowon442 Oct 17, 2026
dec5dda
test: 정책표·중복/동시 차감·보상 경합·상위 rollback을 격리 Postgres로 검증 (#216)
chowon442 Oct 17, 2026
7b682af
feat: 브라우저 run API 계약 browser-run-v1 pin·Java DTO 소비 검사·OpenAPI (#214)
chowon442 Oct 17, 2026
3390dbd
fix: 리뷰 r177 반영 — 잔액 writer lost update 차단·잠금 뒤 refresh·보상 상계 요약 (#216)
chowon442 Oct 17, 2026
4e9cf99
Merge pull request #228 from Team-Proovy/worktree-task-1.77
chowon442 Oct 17, 2026
9590731
fix: 리뷰 r175-server 반영 — OpenAPI 3.1 schema·wire 시각 절단 (#214)
chowon442 Oct 17, 2026
9b6029a
Merge remote-tracking branch 'origin/feat/s07-run-coordination' into …
chowon442 Oct 17, 2026
6167921
docs: 인계 후속 메모에 springdoc 비활성 시 OpenAPI bean 주의 추가 (#214)
chowon442 Oct 17, 2026
cbbbd52
Merge pull request #229 from Team-Proovy/worktree-task-1.75
chowon442 Oct 17, 2026
6c7890a
feat: Brain 내부 실행 client·canonical fingerprint와 서비스 인증 (#215)
chowon442 Oct 17, 2026
8afd061
fix: 리뷰 r176 반영 — 재전송 범주·credential timeout·미분류 예외·null 배열 (#215)
chowon442 Oct 17, 2026
7d543de
Merge pull request #230 from Team-Proovy/worktree-task-1.76
chowon442 Oct 17, 2026
4f505ba
feat: 실행 입력·history·참조·정책의 불변 snapshot 구성과 복원 (#217)
chowon442 Oct 17, 2026
538c8b4
feat: fence 기반 Activity 수락과 영속 이벤트 seq/dedup (#218)
chowon442 Oct 17, 2026
eba28fb
feat: terminal 공개 구조·출처 scope·Verified Solution 수락 검증 (#219)
chowon442 Oct 17, 2026
67e19cd
fix: 리뷰 r178 반영 — history soft 상한·revises 모호성·truncated·정렬 인덱스 (#217)
chowon442 Oct 17, 2026
66d7fb9
fix: 리뷰 r180 반영 — managed AiRun refresh·terminal source ID·구독 경합 (#218)
chowon442 Oct 18, 2026
77ad214
Merge pull request #231 from Team-Proovy/worktree-task-1.78
chowon442 Oct 18, 2026
a62c9c1
Merge remote-tracking branch 'origin/feat/s07-run-coordination' into …
chowon442 Oct 18, 2026
fd85a6d
Merge remote-tracking branch 'origin/feat/s07-run-coordination' into …
chowon442 Oct 18, 2026
b0bdc45
fix: 리뷰 r181 반영 — enum strip 없음·page metadata·저장 coverage 손상·signed U…
chowon442 Oct 18, 2026
0e8180b
Merge pull request #232 from Team-Proovy/worktree-task-1.80
chowon442 Oct 18, 2026
80c4663
Merge origin/feat/s07-run-coordination (1.80 #232) — BrainContractMir…
chowon442 Oct 18, 2026
10a2460
Merge pull request #233 from Team-Proovy/worktree-task-1.81
chowon442 Oct 18, 2026
ae66ace
feat: 원자적 요청 접수·Note 생성과 중복/Active Run 방어 (#220)
chowon442 Oct 18, 2026
cc41b43
fix: 리뷰 r179 반영 — 일괄 삭제 afterCommit·재시도 SQLState 한정·잠금 뒤 시각·NO KEY UP…
chowon442 Oct 18, 2026
1243241
Merge pull request #234 from Team-Proovy/worktree-task-1.79
chowon442 Oct 18, 2026
77320e0
feat: 현재 fence terminal의 응답·solution·사용량·event 원자적 확정과 commit 후 공개 (#…
chowon442 Oct 18, 2026
65c3e3d
fix: 리뷰 r182 반영 — provenance content_version sha256·재전달 식별(source·att…
chowon442 Oct 18, 2026
8c952a2
Merge pull request #235 from Team-Proovy/worktree-task-1.82
chowon442 Oct 18, 2026
5e46a9f
feat: POST/GET SSE durable replay·live 무유실 합류와 run 상태·대화 조회 (#223)
chowon442 Oct 18, 2026
76466bd
feat: 브라우저 독립 단일 coordinator의 run claim·전역 유한 슬롯·bounded dispatch (#222)
chowon442 Oct 18, 2026
cb1709a
fix: 리뷰 r186 반영 — 연결당 쓰기 thread 하나·오류 종료·stream 전 500 JSON·Note 삭제 중 …
chowon442 Oct 18, 2026
60c0aec
Merge pull request #236 from Team-Proovy/worktree-task-1.86
chowon442 Oct 18, 2026
1016f2a
Merge remote-tracking branch 'origin/feat/s07-run-coordination' into …
chowon442 Oct 18, 2026
3a6dc79
fix: 리뷰 r183 반영 — worker pool 거부 제거·dispatch 직렬화·비terminal 기준 전역 슬롯·l…
chowon442 Oct 18, 2026
56da1e3
fix: 리뷰 r183 2회차 반영 — dispatch tryLock 재실행 표시·CannotCreateTransaction…
chowon442 Oct 18, 2026
6ab433a
Merge pull request #237 from Team-Proovy/worktree-task-1.83
chowon442 Oct 18, 2026
ccf92a1
feat: stale 실행 bounded 회수 — 같은 attempt·fence lease 인수·status 우선 수습·실행…
chowon442 Oct 18, 2026
09b2882
feat: run 명시적 취소 — PENDING 즉시 취소·보상, RUNNING CANCELING→Brain 정리 확인/ti…
chowon442 Oct 18, 2026
d43f08e
fix: 리뷰 r185 반영 — FINAL_CHECK 조회 1회·다른 epoch 실패, 종료 중 인수 lease 반납, 로컬…
chowon442 Oct 18, 2026
0cc79e3
Merge pull request #238 from Team-Proovy/worktree-task-1.85
chowon442 Oct 18, 2026
7219290
Merge remote-tracking branch 'origin/feat/s07-run-coordination' into …
chowon442 Oct 18, 2026
793567b
docs: 1.85 반영 — FINAL_CANCEL_PENDING·FINAL_CHECK 전 Brain cancel 판정, 반…
chowon442 Oct 18, 2026
3a75456
fix: 리뷰 r184 반영 — cleanup 예약을 확정 transaction에, absent 확정 lease 재확인, 실…
chowon442 Oct 18, 2026
6125b9a
Merge pull request #239 from Team-Proovy/worktree-task-1.84
chowon442 Oct 18, 2026
9b5953f
test: 빈 DB Java 실행 경로 완주와 구형 실행 경로 잔여 참조 제거 [1.87]
chowon442 Oct 19, 2026
05c0553
test: 실제 Python Brain 연동 인수 — S07 Verification 1~5, 경합·장애 주입 [1.87]
chowon442 Oct 19, 2026
9173b1b
fix: 리뷰 r187 반영 — 연동 스크립트 실행 강제·결과 검증, 정리·격리 보강 [1.87]
chowon442 Oct 19, 2026
51212f0
Merge pull request #240 from Team-Proovy/worktree-task-1.87
chowon442 Oct 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/gradlew text eol=lf
*.bat text eol=crlf
*.jar binary

# proovy-brain 계약 fixture 사본: manifest sha256과 byte 단위로 같아야 한다
/src/test/resources/contracts/brain/** -text
18 changes: 18 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@ jobs:
SPRING_DATASOURCE_PASSWORD: proovy123
SPRING_DATA_REDIS_HOST: localhost
SPRING_DATA_REDIS_PORT: 6379
# 실제 Postgres 제약·role·baseline 테스트: 테스트마다 격리 database를 만든다 (superuser 필요).
# CI에서는 미구성 시 skip이 아니라 실패한다.
PROOVY_TEST_PG_URL: jdbc:postgresql://localhost:5432/postgres
PROOVY_TEST_PG_USER: proovy
PROOVY_TEST_PG_PASSWORD: proovy123
PROOVY_REQUIRE_DB_TESTS: "true"

# 실제 Brain 연동(task 1.87)은 proovy-brain이 private이라 CI에서 실행하지 않는다(사용자 결정). 통과로 보이지 않게 skip을 드러낸다.
- name: Report real-Brain integration tests NOT EXECUTED
if: always()
run: |
shopt -s nullglob
files=(build/test-results/test/TEST-com.proovy.integration.brain.*.xml)
if [ ${#files[@]} -eq 0 ]; then echo "real-Brain integration: no result file"; exit 0; fi
for f in "${files[@]}"; do
summary=$(grep -o 'tests="[0-9]*" skipped="[0-9]*" failures="[0-9]*" errors="[0-9]*"' "$f" | head -1)
echo "::warning title=Real Brain integration NOT EXECUTED::$(basename "$f" .xml) $summary — run scripts/brain-integration/run-local.sh locally (README)"
done

- name: Upload test report
if: always()
Expand Down
55 changes: 47 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,10 @@ proovy-api/
- AI 서버 연동

### 7. Conversation 도메인
- 사용 가능한 도구 목록 조회
- 멘션용 파일 검색 (자동완성)
- Note가 유일한 대화 단위 (`conversationId = noteId`), 메시지는 Note에 직접 연결
- 캔버스 이미지 업로드
- 대화 전송 (질문 + AI 응답, SSE 스트리밍)
- 대화 목록 조회 (검색)
- 대화 상세 조회
- 대화 검색
- 신규 run 접수·SSE·취소는 `POST /api/conversations`·`/api/ai-runs/*`(browser-run-v1). 구형 `/stream/v2`·ChatSession 경로는 없다

### 8. Credit 도메인
- 크레딧 잔액 조회
Expand All @@ -165,9 +163,50 @@ proovy-api/
- 크레딧 비용 정보 조회
- 예상 크레딧 비용 조회

### 9. Embedding 도메인
- 노트 임베딩 저장/조회
- 유사 노트 검색
### 9. Run 도메인 (S07 저장 기반)
- `ai_runs`·`ai_run_events`·`run_asset_dependencies`, `verified_solutions`, `request_usage_*` ledger
- 상태 전이·불변 snapshot·Active Run 제약은 DB baseline에서 강제

## 데이터베이스

- 제품 schema는 빈 DB에서 `db/migration/V1__product_baseline.sql`로 생성한다. 과거 migration·데이터 이관은 없으며 이후 변경은 `V2__...`부터 versioned migration으로 추가한다.
- `baseline-on-migrate`는 꺼져 있어 과거 schema/history가 있는 DB에서는 기동이 실패한다.
- Server ↔ Brain DB role 경계는 `db/provisioning/role-boundary.sql`(Flyway 미실행, 운영자 적용)로 고정한다.

### DB 통합 테스트

실제 Postgres에 테스트마다 격리 database를 만들어 제약·role·baseline을 검사한다 (superuser 접속 필요).

```bash
docker run -d --name proovy-postgres-test -p 127.0.0.1:21432:5432 \
-e POSTGRES_USER=proovy -e POSTGRES_PASSWORD=proovy123 postgres:15-alpine
PROOVY_TEST_PG_URL=jdbc:postgresql://127.0.0.1:21432/postgres \
PROOVY_TEST_PG_USER=proovy PROOVY_TEST_PG_PASSWORD=proovy123 \
PROOVY_REQUIRE_DB_TESTS=true ./gradlew test
```

환경변수가 없으면 DB 테스트는 skip(미실행)되고, `PROOVY_REQUIRE_DB_TESTS=true`(CI)이면 실패한다.

**전용 일회용 Postgres 클러스터에서만 실행한다.** role 경계 테스트는 cluster 단위 role(`proovy_server`, `brain_*`)을
만들고 비밀번호를 덮어쓰며, database를 지워도 role은 남는다. 공유·운영 클러스터를 `PROOVY_TEST_PG_URL`로 지정하지 않는다.

### 실제 Brain 연동 테스트 (task 1.87) — **CI에서는 실행되지 않는다**

`com.proovy.integration.brain.ServerBrainIntegrationTest`는 proovy-brain `testkit/`이 띄운 실제 Python 내부 API·runtime과
Server 전체 경로를 연결해 spec 07 Verification을 검사한다. proovy-brain이 private이라 Server CI는 Brain을 checkout할 수 없고,
사용자 결정으로 **CI에서는 skip**한다. skip은 통과가 아니다 — 테스트 로그에 `NOT EXECUTED — real Brain integration …` 이유가
남고 JUnit 보고서에는 skipped로 집계된다. 결과는 아래 로컬 명령으로 만들고 이슈·PR에 Server·Brain commit과 함께 기록한다.

```bash
# proovy-brain checkout(uv sync --locked 완료)을 원하는 commit에 맞춘 뒤
BRAIN_DIR=../proovy-brain PG_CONTAINER=proovy-postgres-brain-it scripts/brain-integration/run-local.sh
# JDK가 없으면 GRADLE_IN_DOCKER=1 (eclipse-temurin:21-jdk 임시 컨테이너, --network host)
```

스크립트는 격리 Postgres(tmpfs) → Brain testkit supervisor → Gradle(`PROOVY_REQUIRE_BRAIN_IT=true`라 미구성 시 실패) → 정리 순서로
돌고, Brain fixture sha256이 `src/test/resources/contracts/brain/PIN*.json`과 같은지·Brain commit이 checkout과 같은지도 검사한다.
모델·Daytona는 offline fake seat이고 일부 결과(자료 부재 안내·scope 밖 출처·변조 envelope)는 testkit scripted다 — 수학 품질·실제
provider·Cloud Run identity는 이 테스트가 인증하지 않는다(S14).

## API 문서

Expand Down
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ dependencies {
// Google Cloud Storage SDK
implementation platform('com.google.cloud:libraries-bom:26.34.0')
implementation 'com.google.cloud:google-cloud-storage'
// Brain 내부 API 서비스 인증: Cloud Run 서비스 계정 ID token (task 1.76, 버전은 libraries-bom)
implementation 'com.google.auth:google-auth-library-oauth2-http'

// PDF/이미지 처리 (썸네일 생성용)
implementation 'org.apache.pdfbox:pdfbox:3.0.6'
Expand All @@ -73,6 +75,8 @@ dependencies {

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
// browser-run-v1 계약 schema(JSON Schema 2020-12) 소비 검사 — Brain fixture 사본으로만 쓴다
testImplementation 'com.networknt:json-schema-validator:1.5.8'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

Expand Down
70 changes: 70 additions & 0 deletions docs/contracts/brain-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Server ↔ Brain 로컬 실행 연동 인수 (task 1.87, #226)

S07 Server 구현 전체(1.74~1.86)를 **실제 Python Brain 내부 API·runtime**과 로컬에서 연결해 인수한다.
Brain 쪽 test bootstrap은 proovy-brain `testkit/`(PR #150, squash `7b8608ee345761526aee0c76186ca984b496f41e`)이고,
Server 쪽 검사는 `com.proovy.integration.brain.ServerBrainIntegrationTest`다.

## 실행

```bash
BRAIN_DIR=<proovy-brain checkout @ 7b8608e, uv sync --locked> \
PG_CONTAINER=proovy-postgres-brain-it GRADLE_IN_DOCKER=1 scripts/brain-integration/run-local.sh
```

순서: Gradle `testClasses` → 격리 Postgres(tmpfs, `postgres:15-alpine`) → Brain testkit supervisor(`uv run --locked python -m testkit.integration supervise`)
→ warm-up child → `./gradlew test --tests 'com.proovy.integration.brain.*'`(`PROOVY_REQUIRE_BRAIN_IT=true`) → 컨테이너·프로세스 정리.

- **Server CI는 실행하지 않는다**(사용자 결정: proovy-brain이 private, checkout token 없음). CI 로그에는 skip 이유(`NOT EXECUTED — real Brain integration …`)와
`Report real-Brain integration tests NOT EXECUTED` step의 warning이 남는다. skip은 통과가 아니다.
- 한 database에 빈 제품 baseline(`proovy_server`가 Flyway 실행)과 Brain schema(`brain_migration`·`brain_runtime`, Brain bootstrap·migrate)를 두고
`db/provisioning/role-boundary.sql`을 적용한다(운영 형태). Server datasource는 `proovy_server`다.
- 스크립트는 `test --rerun`으로 항상 실제 실행하고, 끝에 `TEST-com.proovy.integration.brain.*.xml`이 이번 실행에서 생겼고 tests > 0·skipped·failures·errors = 0인지 검사해 아니면 실패한다(UP-TO-DATE·skip 위장 방지). 정리 때 supervisor에 `/brain/stop`을 보내고 프로세스 그룹 전체를 끈다.
- 공용 호스트 부하 대응: supervisor의 child readiness 대기는 60초 고정이라, 스크립트가 child를 미리 한 번 띄워 page cache를 데우고
Java client는 `did not become ready`일 때만 start·restart를 최대 3번 다시 보낸다(후속 메모: Brain readiness 대기 설정화).

## S07 Verification 대응

| Verification (spec 07) | 테스트 | 실제로 거친 경로 |
| --- | --- | --- |
| 1. 빈 DB·ChatSession/thread 없음, noteId 없는 중복·같은 Note 동시 전송이 하나만 남고 거부는 메시지 없음 | `firstTextQuestion…`, `concurrentDuplicateNotelessRequests…`, `concurrentSameNoteRequests…` (+ 단계 3 `RunPathEndToEndPostgresTest`·`LegacyExecutionPathGuardTest`) | HTTP 접수 → coordinator → Brain graph 1회 → terminal transaction. 409 RUN4091 + activeRunId, 메시지·run·차감 없음 |
| 2. SSE 단절·재접속 seq·canonical 복원, replay/live 무유실 | `firstTextQuestion…`(POST live = GET replay 바이트), `browserDisconnectAndInternalSseLoss…`, `storedTerminalLostInDelivery…` | 브라우저 Last-Event-ID 재접속, Brain 내부 SSE 첫 frame 직전 abort → status executing → 같은 attempt·fence OBSERVE 재부착, terminal 전 abort → status terminal 회수 |
| 3. 완료·취소·deadline·이전 attempt 경합에서 확정과 보상이 동시에 일어나지 않음 | `runningCancelBlocks…`, `pendingCancel…`, `deadlineRace…`, `brainSideDeadline…`(fake clock), `staleFenceTerminal…`, `serverRestart…`, `brainLostBeforeStorage…` | terminal event 1개·보상 ≤ 1·재실행 0을 run마다 단언. deadline 경합은 승자를 고정하지 않는다(실측: Server sweep). Brain fake clock은 Brain timeout terminal 확정을 단언. `serverRestart`는 같은 JVM의 coordinator `stop()/start()`(프로세스 재시작 아님) |
| 4. clarification·unsupported_only·혼합·no-match·최종 실패·PENDING/RUNNING 취소 순사용량 | `outcomeMatrix…`, `explainFollowUp…`, 취소 2종 | 정상 solve·check·explain 1, 미검증 공개 1, clarification 0, unsupported_only 0, 혼합 1, 자료 부재(scripted) 1, verification_failed 0, provider_error 0, PENDING 취소 0, RUNNING 취소 1, deadline 0, 저장 전 소실 0 |
| 5. Java DTO·fingerprint·source 변환이 공용 fixture와 일치, scope/provenance 위반 거부 | `javaAndPythonAgree…`, `outOfScopeSource…`, `forgedRunEnvelope…`, `staleFenceTerminal…` | Brain record fingerprint = `ai_runs.request_fingerprint`, Brain fixture sha256 = Server PIN 전부, scope 밖 asset(scripted) → FAILED internal_error·출처/solution 없음, 다른 run envelope(stream+status, scripted) → FAILED, 이전 fence(stream, scripted) → 버리고 저장 terminal 회수 |

보안 경계(`securityBoundariesHold`): Brain이 받은 호출은 전부 shared token이고 body에 사용자 JWT·`Bearer`·grant·`read_url`·서명 URL이 없다.
token 없음·사용자 JWT·틀린 token은 Brain이 401/403으로 거부한다. 브라우저 frame·대화 조회에 fence·grant·read URL·서비스 token이 없다.
같은 database에서 `brain_runtime` → `public.ai_runs` 42501, `proovy_server` → `brain_runtime.run_records` 42501.

## 구분 — fake·scripted·미검증

- **fake provider**: Brain 모델·Daytona·page VLM은 offline seat다. 결과 분류(검증/미검증/실패)는 scripted seat 판정이고 수학 품질을 인증하지 않는다.
- **scripted terminal/fault (그래프 미실행 또는 전달 변조)**: `no_match_notice`(자료 부재 안내 — Brain runtime에 문서 근거 no-match 경로가 아직 없다),
`out_of_scope_source`, `rewrite_terminal`(+`rewrite_status`). 저장·전달은 실제 Brain store·SSE(PgRuntimeBackend)를 거친다.
- **미검증(S14)**: 실제 유료 모델 품질·비용, Cloud Run 서비스 계정 ID token·IAM, Supabase/GCS, 실제 자산 업로드·signed URL(자산 경로는 1.81 seeded 계약 자료로만 검수),
부하·다중 인스턴스, 브라우저 화면.
- **Server CI**: skip(위). 결과는 이슈 #226·PR 본문에 Server head·Brain SHA와 함께 기록한다.

## S08이 쓸 외부 계약

- 브라우저 wire는 browser-run-v1 그대로다(변경 없음): `POST /api/conversations`(fetch 기반 SSE reader, body·Authorization 필요),
`GET /api/ai-runs/{runId}/events`(Last-Event-ID 또는 `lastEventId` query), `GET /api/ai-runs/{runId}`, `POST /api/ai-runs/{runId}/cancel`(body 없음),
`GET /api/conversations/{noteId}/messages`. 재접속 cursor는 마지막 처리 frame `id`.
- 실제 Brain에서 나오는 frame 순서(정상 solve): `run.created` → `activity.started/completed`(입력 분석·풀이·검증) → `response.page.started` →
`response.page.completed` → `run.completed`. 취소는 `run.canceling` → `run.canceled`, 실패는 `run.failed`(보상된 run은 순사용량 0).
- 이월(계약 변경 필요, 이 태스크는 바꾸지 않음): superseded 재표현 표시 필드, 대화 조회 before/limit fixture, U+0000 RUN4001, `viewerFocus.page` 상한.

## S13이 재사용할 복구 경계

- `RunClaimStore.findStale`·`takeOver`(같은 attempt·fence 인수), `RunExecution` RECOVER/FINAL_CHECK(status 먼저 → `settle(StoredTerminal)`·`failByServer`·`expireDeadline`),
`hasBrainEvents`(미시작 vs 실행 소실). 실제 Brain에서 확인한 결과:
- coordinator 정지 중(같은 JVM `stop()`) Brain이 저장한 terminal → `start()` 뒤 같은 epoch로 회수, graph 1회. Cloud Run 프로세스 교체는 S14.
- Brain이 terminal 저장 전 SIGKILL → 재시작한 Brain record는 `executing`(terminal 없음, 재개·재실행 0). Server는 같은 요청 OBSERVE·status 수습 뒤
`provider_error`(infrastructure, 실행 소실)로 한 번 보상한다(단언). **Brain record는 executing으로 남는다** — Brain lease 만료 sweep·`cleanup` 호출은 S13.
- `runtime_cleanup_at` 예약까지가 Server 범위이고 Brain `cleanup` 호출·retention은 S13이다.

## 후속 메모

- testkit release·clock route가 잘못된 JSON body에 500을 돌려준다(테스트 도구 한정, r187 r2).
- supervisor child readiness 대기(60s)를 설정값으로 — 공용 호스트 부하에서 재시도에 의존하지 않게(Brain 후속).
- `deploy.yml`의 `PROOVY_AI_HOST`·`INTERNAL_API_TOKEN` secret 주입은 읽는 코드가 없다(S14 정리 후보, 파일 미변경).
Loading
Loading