diff --git a/scripts/verify-mission-delivery.sh b/scripts/verify-mission-delivery.sh index 544ea76..928ca4c 100755 --- a/scripts/verify-mission-delivery.sh +++ b/scripts/verify-mission-delivery.sh @@ -1588,12 +1588,23 @@ print("ok")' >/dev/null 2>&1 \ if [ "${CLAWMATES_SKIP_AUDIO:-0}" = "1" ]; then pass "cr: (audio assertion skipped by CLAWMATES_SKIP_AUDIO)" else - local ep - ep=$(ssh "$HOST" "docker exec clawmates_postgres_1 psql -U postgres -d clawmates -tAc \ - \"select coalesce(rendered_by,'-') || ' ' || coalesce(duration_secs,0)::text \ - from podcast_episodes where mission_id='$mission';\"" | head -1 | tr -d '\r') + # The render is a BACKGROUND sweep (every 2 minutes) followed by a + # text-to-speech call that takes minutes on a full dialogue. Checking the + # instant the mission completes asserts that the worker is fast, not that + # it works — the first run of this scenario failed exactly that way while + # the pipeline was fine. Wait for a verdict instead, and say so if none + # arrives rather than reporting the timeout as a product defect. + local ep waited + ep=""; waited=0 + while [ "$waited" -lt "${CR_EPISODE_TIMEOUT:-900}" ]; do + ep=$(ssh "$HOST" "docker exec clawmates_postgres_1 psql -U postgres -d clawmates -tAc \ + \"select coalesce(rendered_by,'-') || ' ' || coalesce(duration_secs,0)::text \ + from podcast_episodes where mission_id='$mission';\"" | head -1 | tr -d '\r') + [ -n "$ep" ] && break + sleep 30; waited=$((waited + 30)) + done case "$ep" in - '') fail "cr: no podcast_episodes row — the render sweep never reached this mission" ;; + '') fail "cr: no episode after ${waited}s — the render sweep never reached this mission" ;; unrenderable:no-turns*) fail "cr: the script parsed to zero spoken turns — the writer's format and parse_script disagree" ;; unrenderable*) fail "cr: the episode is a tombstone (unrenderable) — the script was not found in the checkout OR the vault" ;; *' 0') fail "cr: an episode was recorded with zero duration: $ep" ;;