#!/bin/bash
# round.sh <phase> <brief.md> [orientation.md]  — one headless phase round. Env: HARNESS_* (see harness.ts), MODEL (atlas/qwen)
set -u
PHASE=$1; BRIEF=$2; ORIENT=${3:-}
export HARNESS_PHASE=$PHASE HARNESS_OUT=/out/$PHASE
export HARNESS_SCOPE=${HARNESS_SCOPE:-$(grep -m1 '^SCOPE:' "$BRIEF" | sed 's/^SCOPE: *//')}
: "${HARNESS_WALL_S:=3600}" "${HARNESS_MAX_STEPS:=60}" "${HARNESS_WRITE_CAP:=16000}"
export HARNESS_WALL_S HARNESS_MAX_STEPS HARNESS_WRITE_CAP
mkdir -p /out/$PHASE
RULES=/out/$PHASE/rules.md
cat > $RULES <<EOR
You are a senior Rust engineer working autonomously with tools on the INKBOARD workspace (single-user whiteboard: \`model\` pure domain crate, \`server\` axum+tokio+sqlx on Postgres, \`engine\` wasm whiteboard + minimal frontend). Paths are relative to the workspace root. The workspace and every build tool live on the build host; your tools run there.
This is phase "$PHASE". Budget: about $((HARNESS_WALL_S/60)) minutes of wall time and $HARNESS_MAX_STEPS tool calls.
Method — test-driven and scoped:
- Your first message is an ORIENTATION PACKET: file tree, previous phase summary/verification, the FULL content of this phase's focus files and the current verify. Do NOT read those files again. Read other files only when you must, and only the region you are about to change (offset/limit, 40-80 lines): every turn re-processes your whole context (~2 s per 1K tokens on this engine), so reads are the most expensive thing you do. Make your first edit by step 4.
- SCOPE: this phase may change only files matching: ${HARNESS_SCOPE:-unrestricted}. Anything else is earlier phases' work; a failing test outside the scope is expected and not your task.
- Loop: edit -> cargo test -p <crate> <name> / verify -> fix. Every new .rs file must be declared with \`mod x;\` in its parent. Prefer edit for existing files; write for new files; never retype a file from memory. No placeholders or todo!() in code a brief says must pass tests.
- SIZE: one write/append_file call is capped at $HARNESS_WRITE_CAP chars (~300 lines): write long files in parts (write, then append_file), then cargo check. Long single generations are slow and get corrupted.
- COMPILE FIRST: a phase is NOT accepted while any crate has compile errors. If a fix cascades into more errors, revert_file the file and redo that part in pieces instead of chasing the cascade.
- Do not use skills, subagents or plan files unless the brief asks; there is no bash.
When the acceptance criteria are met (or the budget is nearly gone), output a summary starting exactly with:
ROUND COMPLETE
containing what was delivered, the verification commands you ran with their results, and what is left.

===== THE SPEC AND THIS PHASE'S BRIEF (authoritative) =====
EOR
cat "$BRIEF" >> $RULES
PROMPT="Start phase $PHASE now. SCOPE: ${HARNESS_SCOPE:-unrestricted}."
if [ -n "$ORIENT" ]; then PROMPT="$(cat "$ORIENT")

$PROMPT"; fi
echo "$(date -Is) round $PHASE start scope=[$HARNESS_SCOPE] wall=${HARNESS_WALL_S}s steps=$HARNESS_MAX_STEPS" | tee -a /out/$PHASE/driver.log
timeout $((HARNESS_WALL_S + 900)) pi -p --mode json --no-session --thinking off --no-context-files \
  --model "${MODEL:-atlas/qwen}" --tools read,write,edit,list_files,append_file,revert_file,cargo,trunk_build,verify \
  --system-prompt "$(cat $RULES)" "$PROMPT" > /out/$PHASE/events.jsonl 2> /out/$PHASE/stderr.log
RC=$?
echo "$(date -Is) round $PHASE end rc=$RC" | tee -a /out/$PHASE/driver.log
exit $RC
