증상
policies/default-pipeline.yaml의 두 블록이 런타임에 적용되지 않는다.
| 블록 |
위치 |
실제 동작 |
timeouts (max_retries / backoff / on_exhaust_policy, #1082) |
:214-251 |
src/engine/transition_timeout.rs decide_timeout이 유일 소비자인데, 이 리듀서는 TransitionEvent::TimeoutExpired로만 도달한다. 라이브 타임아웃 스윕(policies/timeouts/card-timeouts.js, dispatch-maintenance.js)은 그 이벤트를 발화하지 않고 하드코딩 예산으로 직접 escalate/retry 한다. 결과는 agentdesk::timeout_shadow 로그(log_ops.rs:7)뿐이다. transition_timeout.rs:8-14 주석이 이를 명시한다(#3916 범위 경계, "deferred follow-up epic"). |
stage_failure_policy |
:191 |
src/pipeline.rs:627 PipelineConfig에 해당 필드가 없다. deny_unknown_fields가 없어 serde가 파싱 시 조용히 버린다. 파싱 오류도 경고도 없다. |
사용자 관점: yaml에서 단계별 시간 제한·재시도·실패 시 이동을 바꿔도 카드 동작이 변하지 않는다. 실제 타임아웃 결정은 전부 policies/timeouts/*.js 12개가 한다.
결정 (사용자, 2026-09-05)
옵션 2: yaml 블록을 제거하고 JS 정책을 타임아웃 결정의 유일한 정본으로 문서화한다. (옵션 1 "shadow를 실행으로 승격"은 기각. 자동 회수는 위험한 동작이고 JS 정책 12개가 이미 같은 역할을 하며, 두 곳에서 같은 결정을 내리면 충돌한다.)
수정
default-pipeline.yaml에서 stage_failure_policy(:191)와 timeouts(:214-251) 블록 삭제. 코멘트로 "타임아웃·실패 이동은 policies/timeouts/*.js가 담당" 한 줄.
PipelineConfig와 파이프라인 override 구조체(pipeline.rs:619 timeouts: Option<HashMap<String, TimeoutConfig>> 포함)에 #[serde(deny_unknown_fields)]. 알 수 없는 키는 부팅 시 거부한다. 조용히 버리는 것을 없애는 것이 이 이슈의 핵심.
TimeoutConfig, transition_timeout.rs 리듀서, transition.rs:340 TimeoutExpired 분기, timeout_shadow 로그 타겟(log_ops.rs:7-8, 테스트 :66) 제거. #3916이 "미래 라이브 배선의 기반"으로 남긴 코드이며 배선 계획을 폐기하므로 함께 제거. 남기면 다음 사람이 또 승격을 검토한다.
pipeline.rs:341-347 override 병합의 timeouts dropped-items 진단 제거.
docs/source-of-truth.md에 "카드 타임아웃·단계 실패 이동 정본 = policies/timeouts/*.js" 행 추가. docs/memory-scope.md·docs/generated/db-file-duplication-audit.md의 참조 갱신.
완료 정의
관련
증상
policies/default-pipeline.yaml의 두 블록이 런타임에 적용되지 않는다.timeouts(max_retries/backoff/on_exhaust_policy, #1082):214-251src/engine/transition_timeout.rsdecide_timeout이 유일 소비자인데, 이 리듀서는TransitionEvent::TimeoutExpired로만 도달한다. 라이브 타임아웃 스윕(policies/timeouts/card-timeouts.js,dispatch-maintenance.js)은 그 이벤트를 발화하지 않고 하드코딩 예산으로 직접 escalate/retry 한다. 결과는agentdesk::timeout_shadow로그(log_ops.rs:7)뿐이다.transition_timeout.rs:8-14주석이 이를 명시한다(#3916 범위 경계, "deferred follow-up epic").stage_failure_policy:191src/pipeline.rs:627PipelineConfig에 해당 필드가 없다.deny_unknown_fields가 없어 serde가 파싱 시 조용히 버린다. 파싱 오류도 경고도 없다.사용자 관점: yaml에서 단계별 시간 제한·재시도·실패 시 이동을 바꿔도 카드 동작이 변하지 않는다. 실제 타임아웃 결정은 전부
policies/timeouts/*.js12개가 한다.결정 (사용자, 2026-09-05)
옵션 2: yaml 블록을 제거하고 JS 정책을 타임아웃 결정의 유일한 정본으로 문서화한다. (옵션 1 "shadow를 실행으로 승격"은 기각. 자동 회수는 위험한 동작이고 JS 정책 12개가 이미 같은 역할을 하며, 두 곳에서 같은 결정을 내리면 충돌한다.)
수정
default-pipeline.yaml에서stage_failure_policy(:191)와timeouts(:214-251) 블록 삭제. 코멘트로 "타임아웃·실패 이동은policies/timeouts/*.js가 담당" 한 줄.PipelineConfig와 파이프라인 override 구조체(pipeline.rs:619timeouts: Option<HashMap<String, TimeoutConfig>>포함)에#[serde(deny_unknown_fields)]. 알 수 없는 키는 부팅 시 거부한다. 조용히 버리는 것을 없애는 것이 이 이슈의 핵심.TimeoutConfig,transition_timeout.rs리듀서,transition.rs:340TimeoutExpired분기,timeout_shadow로그 타겟(log_ops.rs:7-8, 테스트:66) 제거. #3916이 "미래 라이브 배선의 기반"으로 남긴 코드이며 배선 계획을 폐기하므로 함께 제거. 남기면 다음 사람이 또 승격을 검토한다.pipeline.rs:341-347override 병합의timeoutsdropped-items 진단 제거.docs/source-of-truth.md에 "카드 타임아웃·단계 실패 이동 정본 =policies/timeouts/*.js" 행 추가.docs/memory-scope.md·docs/generated/db-file-duplication-audit.md의 참조 갱신.완료 정의
default-pipeline.yaml에timeouts·stage_failure_policy없음. 부팅·파이프라인 로드 정상rg timeout_shadow src0건,TransitionEvent::TimeoutExpired0건,#[allow(dead_code)]신규 0개card-timeouts.js테스트 통과)docs/source-of-truth.md갱신관련
on_exhaust_policy도입)01c0c078d8