Skip to content

확정된 읽기 실패 하나로 요청 전체가 끝나지 않게 했다 (ADR-0052) - #99

Merged
SonAIengine merged 1 commit into
mainfrom
feat/recoverable-read-failures
Oct 25, 2026
Merged

SonAIengine merged 1 commit into
mainfrom
feat/recoverable-read-failures

Conversation

@SonAIengine

Copy link
Copy Markdown
Contributor

문제

75 KB 파일을 read-text로 읽다가 64 KiB 상한에 걸리자, 요청 전체가 8초 만에 rejected: failed_work로 끝났다. Step 하나가 Failed가 되면 agent loop가 FailedSteps로 멈추기 때문이다. 없는 경로나 UTF-8이 아닌 파일을 읽을 때도 같다. 반면 테스트 실패(exit 1)는 정상 observation으로 처리되어 모델이 이어서 고칠 수 있었다.

변경 (ADR-0052)

  • frontier가 Failed이면서 durable intent가 read_only인 Step을 read_only_failed_step_ids로 따로 분류한다.
  • terminal_quiescence와 driver는 read-only가 아닌 실패가 있을 때만 멈춘다.
  • TaskCompletion 수락(reducer와 agent loop)과 planned-step 예산 판정은 all_steps_settled()를 쓴다. 조건이 넓어지기만 하므로 기존 journal은 그대로 replay된다.
  • 실패한 Step은 계속 dependency를 막는다. 모델은 status=failed만 보고 경로나 OS 오류는 보지 못한다.
  • planner prompt는 바꾸지 않았다. prompt 바이트가 저장된 digest에 묶여 있기 때문이다.

검증

  • cargo test --workspace 716개 통과, clippy 경고 0
  • 새 e2e: 64 KiB+1 파일 읽기 실패 → 다른 파일 읽기 → 완료(exit 0). 게이트를 되돌리면 이 테스트가 실패하는 것을 확인했다.
  • 쓰기(apply-patch) 실패는 여전히 failed_work로 멈추고, 파일은 바뀌지 않는다.
  • frontier 단위 테스트: read_only 실패는 settled, idempotent/non_idempotent 실패는 blocking으로 분류된다.
  • 실사용 재실행: failed_work 없이 24턴을 진행했다. 다만 모델이 틀린 패턴(@mcp.tool)으로 같은 검색을 15번, 같은 실패 읽기를 7번 반복해서 턴 예산 소진으로 끝났다. 큰 파일을 범위로 읽는 capability와 실패 원인 전달은 후속 과제로 남긴다.

🤖 Generated with Claude Code

실사용 시나리오에서 75 KB 파일을 read-text 로 읽다가 64 KiB 상한에 걸리자 요청이
8초 만에 rejected: failed_work 로 끝났다. Step 하나가 Failed 면 agent loop 가
FailedSteps 로 멈추기 때문이다. 없는 경로, UTF-8 이 아닌 파일도 같았다. 반면
테스트 실패(exit 1)는 정상 observation 이라 모델이 이어서 고칠 수 있었다.

- frontier 가 Failed 이면서 durable intent 가 read_only 인 Step 을
  read_only_failed_step_ids 로 따로 분류한다. 읽기는 부작용이 없어 지나쳐도
  되돌릴 것이 없다.
- terminal_quiescence 와 driver 는 read-only 가 아닌 실패가 있을 때만 멈춘다.
  쓰기·실행 실패, EffectUnknown, ManualRequired 는 기존과 같다.
- TaskCompletion 수락(reducer, agent loop)과 planned-step 예산 판정은
  all_steps_settled() 를 쓴다. 모든 Step 이 receipt-completed 이거나 확정된
  read-only 실패이면 완료할 수 있다. 조건이 넓어지기만 해서 기존 journal 은
  그대로 replay 된다.
- 실패한 Step 은 계속 dependency 를 막는다. 모델은 planning context 에서
  status=failed 만 보고 경로·OS 오류는 보지 못한다(ADR-0022/0038 redaction 유지).
- planner prompt 는 바꾸지 않았다. prompt 바이트가 저장된 digest 에 묶여 있다.

검증
- cargo test --workspace 716개 통과, clippy 경고 0
- 새 e2e: 64 KiB+1 파일 읽기 실패 → 다른 파일 읽기 → 완료(exit 0). 게이트를
  되돌리면 이 테스트가 실패하는 것을 확인했다. 쓰기(apply-patch) 실패는 여전히
  failed_work 로 멈추고 파일은 그대로다.
- frontier 단위 테스트: read_only 는 settled, idempotent/non_idempotent 는 blocking.
- 실사용 재실행: 같은 요청이 failed_work 없이 24턴을 진행했다. 다만 모델이 틀린
  패턴(@mcp.tool)으로 같은 검색 15번, 같은 실패 읽기 7번을 반복해 턴 예산 소진으로
  끝났다. 큰 파일을 범위로 읽는 capability 와 실패 원인 전달은 후속 과제다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SonAIengine
SonAIengine merged commit 919fff6 into main Oct 25, 2026
3 checks passed
@SonAIengine
SonAIengine deleted the feat/recoverable-read-failures branch October 25, 2026 11:49
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