Skip to main content

completion-detector-fires-on-an-earlier-success-string

긴 작업을 기다리는 폴링 루프의 패턴이 **종료 이벤트에만** 나타나는 문자열이 아니면, 앞선 단계의 성공 메시지에 걸려 일찍 끝난다 — "끝났다"는 알림이 오는데 결과는 아직 없다. 체인된 게이트(`ruff && mypy && pytest`)에서 특히 잘 터진다. 종료 신호는 **형태로 유일**해야 하고, 안 되면 마커를 직접 심어라. 트리거 - `until grep -q ...` 대기, `tail -f | grep` 완료 감지, CI/배포 폴링, 여러 도구를 && 로 묶은 게이트.

Jump to install

Source facts

Repository
blas1n/claude-skills
Last source activity
August 28, 2026 at 09:56
Detected SKILL.md language
Korean
Stars
2
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
completion-detector-fires-on-an-earlier-success-string
description
긴 작업을 기다리는 폴링 루프의 패턴이 **종료 이벤트에만** 나타나는 문자열이 아니면, 앞선 단계의 성공 메시지에 걸려 일찍 끝난다 — "끝났다"는 알림이 오는데 결과는 아직 없다. 체인된 게이트(`ruff && mypy && pytest`)에서 특히 잘 터진다. 종료 신호는 **형태로 유일**해야 하고, 안 되면 마커를 직접 심어라. 트리거 - `until grep -q ...` 대기, `tail -f | grep` 완료 감지, CI/배포 폴링, 여러 도구를 && 로 묶은 게이트.
version
1.0.0
task_types
["devops","testing","workflow"]
triggers
[{"pattern":"until grep -q \"passed|failed\" ... 처럼 로그를 폴링해 완료를 감지할 때"},{"pattern":"여러 명령을 && 로 묶어 한 파일에 출력하고 그 파일을 감시할 때"},{"pattern":"완료 알림이 왔는데 결과가 비어 있을 때"}]
category
trap
# 완료 감지기가 앞 단계의 성공 문자열에 걸린다 ## Problem 긴 스위트를 백그라운드로 돌리고 결과를 기다린다: ```bash uv run ruff check . && uv run mypy . && uv run pytest -q > out.log 2>&1 & # 결과가 나오면 알려줘 until grep -qE "passed|failed" out.log; do sleep 10; done tail -14 out.log ``` **즉시 끝난다.** `ruff` 가 먼저 `All checks passed!` 를 찍기 때문이다. `pytest` 는 아직 10분 남았는데 대기 루프는 "완료"를 신고하고, `tail` 은 아직 `=== PYTEST ===` 헤더만 있는 파일을 보여준다. BSVibe 2026-08-28 실측. 위 루프가 정확히 이렇게 헛돌았고, 나는 알림을 받고 결과 파일을 열었다가 pytest 요약이 없다는 걸 보고서야 알아챘다. > **종료 신호로 고른 문자열이 앞 단계에도 나타나면, 그 감지기는 도착하지 않은 결과를 > 도착했다고 읽는다.** 침묵이 성공이 아니듯, **소음도 성공이 아니다.** ### 왜 잘 안 보이나 - 패턴을 **관대하게** 잡는 것이 안전해 보인다 — `passed|failed|error` 는 실패까지 잡으려는 좋은 의도였다. 넓힐수록 오작동 확률이 **올라간다**. - 게이트를 `&&` 로 묶는 습관 때문에 한 파일에 **여러 도구의 요약**이 섞인다. - 거짓 완료는 **에러가 아니다.** 명령은 exit 0 이고 알림도 정상이다. 유일한 증상은 "결과가 이상하게 비어 있다"인데, 그건 작업이 실패한 것처럼도 보인다. ## Solution ### 1. 종료 신호는 **형태로 유일**해야 한다 pytest 요약에는 **숫자가 앞에 붙는다**. ruff 의 `All checks passed!` 에는 없다. ```bash until grep -qE "[0-9]+ (passed|failed|error)" out.log; do sleep 15; done ``` 고를 때 물어라: **이 정규식이 앞 단계 출력 어디에도 안 나타난다고 말할 수 있나?** 말 못 하면 그 패턴이 아니다. ### 2. 확신이 안 서면 **마커를 직접 심어라** 추측할 필요가 없다. 끝에 내가 아는 문자열을 찍는다. ```bash { uv run ruff check . && uv run mypy . && uv run pytest -q; echo "__GATE_DONE__ rc=$?"; } > out.log 2>&1 & until grep -q "__GATE_DONE__" out.log; do sleep 15; done ``` rc 까지 같이 실으면 **완료와 성패를 한 번에** 읽는다. (⚠️ 파이프로 넘기면 exit code 가 마지막 명령 것이 된다 → [[piped-gate-masks-exit-code]]) ### 3. 애초에 **프로세스 종료**를 기다려라 로그 파싱은 프로세스 종료를 관측할 수 없을 때만 쓰는 대체 수단이다. 백그라운드 태스크가 완료 알림을 주는 환경이면 **그 알림을 기다려라.** 폴링 루프를 하나 더 얹으면 신호원이 둘이 되고, 둘 중 약한 쪽이 먼저 거짓말한다. ### 4. 실패도 잡히는지 확인하라 완료 패턴을 좁히다가 **실패 종료를 못 잡게** 되면 크래시에서 영원히 매달린다. 좁힌 뒤 반드시 반대편을 확인: | 종료 형태 | 내 패턴이 잡나 | |---|---| | 전부 통과 | `123 passed` ✅ | | 실패 있음 | `2 failed, 121 passed` ✅ | | 수집 에러 | `error` / `ERROR` — 별도 확인 필요 | | 프로세스 사망(OOM/kill) | **로그에 아무것도 안 남는다** → 타임아웃이 유일한 방어 | 마지막 줄 때문에 **대기 루프에는 항상 상한**이 필요하다. ## Verification - [ ] 종료 패턴이 **앞 단계 출력에 나타나지 않음**을 실제 로그로 확인했다 - [ ] 실패 종료도 같은 패턴에 걸린다 - [ ] 프로세스가 죽어도 빠져나온다(타임아웃) - [ ] 알림을 받으면 **요약 줄을 실제로 읽는다** — "완료됨" 상태만 보고 넘기지 않는다 ## Related - [[piped-gate-masks-exit-code]] — 파이프가 성패를 가린다 - [[truncated-diagnostic-shows-only-the-passing-half]] — `tail` 로 잘라 보다 앞의 에러를 놓친다 - [[failure-feedback-blind-prefix-shows-only-passes]] — 통과 목록만 보여주는 피드백
View on GitHub