#!/bin/bash
# The last stage of this study is not in chain.run.sh, because chain.run.sh was already executing
# by the time I knew it was needed and a running bash script must not be edited (it is read by
# byte offset, hours later, mid-token). So the analysis stage waits out here instead.
#
# build_page.py refuses to render if analysis.txt is missing OR older than any scores_*.jsonl or
# padding_*.jsonl, which means forgetting this step cannot silently publish stale numbers — it
# just blocks the build at the end of an eleven-hour chain. Running it automatically is cheaper
# than remembering it.
#
# chain.sh ALSO runs analyse.py, as its last act before writing the done marker. So this is a
# second, redundant run — and a plain `analyse.py > analysis.txt` is strictly worse than nothing,
# because the redirect truncates the file before the program has produced a byte. A failed rerun
# would replace a good analysis with an empty one, and the staleness guard downstream tests mtime,
# which an empty file passes. So: render to a temporary file, check it actually contains an
# analysis, and only then move it into place. That turns the redundancy into a repair pass — if
# the chain's own run died this one fixes it, if this one dies the chain's survives — and makes
# the operation atomic either way.
#
# Waits on a FILE, never on a pgrep: a waiter whose pattern matches its own command line waits
# forever. "[chain] all done" is written only after the last padding check returns.
#
#   cp finish.sh finish.run.sh && setsid nohup ./finish.run.sh <chain-pid> > finish.log 2>&1 < /dev/null &
cd /home/agent/work/aidetect-fpr

CHAIN_PID="${1:-}"
while ! grep -q '^\[chain\] all done' chain.log 2>/dev/null; do
    if [ -n "$CHAIN_PID" ] && [ ! -d "/proc/$CHAIN_PID" ]; then
        echo "[finish] chain PID $CHAIN_PID is gone and chain.log never said all done — stopping." >&2
        echo "[finish] $(wc -l < scores_hello.jsonl 2>/dev/null) hello, $(wc -l < scores_openai.jsonl 2>/dev/null) openai corpus rows at the time." >&2
        exit 1
    fi
    sleep 60
done

echo "[finish] chain complete, re-running the analysis into a temporary file" >&2
python3 analyse.py > analysis.new 2>&1
rc=$?
lines=$(wc -l < analysis.new)
# One marker per detector block, plus a floor on length. A traceback is short and contains
# neither; a run that died between the two blocks fails the block count.
blocks=$(grep -c 'adversarial corpus, P(AI)>0.5:' analysis.new)
if [ "$rc" -eq 0 ] && [ "$lines" -ge 40 ] && [ "$blocks" -ge 2 ]; then
    mv analysis.new analysis.txt
    echo "[finish] analysis.txt replaced: $lines lines, $blocks detector blocks" >&2
else
    echo "[finish] REFUSING to replace analysis.txt: exit $rc, $lines lines, $blocks blocks." >&2
    echo "[finish] the chain's own analysis.txt is untouched; the failed output is in analysis.new" >&2
    tail -5 analysis.new >&2
fi
# Deliberately does NOT run build_page.py. Seven strings in copy.json are written after the
# numbers are known — the title, the lede, and five section strings whose wording depends on how
# the result comes out. A build before those are authored would render placeholders into a page.
echo "[finish] next step is manual: author the pending copy.json strings, then build_page.py" >&2
