diff --git a/AGENTS.md b/AGENTS.md index a6750e2..755873c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,4 +1,3 @@ - # Disinto — Agent Instructions ## What this repo is @@ -43,9 +42,11 @@ disinto/ ```bash # ShellCheck all scripts -shellcheck dev/dev-poll.sh dev/dev-agent.sh review/review-poll.sh \ - review/review-pr.sh gardener/gardener-poll.sh \ - supervisor/supervisor-poll.sh lib/env.sh lib/ci-debug.sh \ +shellcheck dev/dev-poll.sh dev/dev-agent.sh dev/phase-test.sh \ + review/review-poll.sh review/review-pr.sh \ + gardener/gardener-poll.sh \ + supervisor/supervisor-poll.sh supervisor/update-prompt.sh \ + lib/env.sh lib/ci-debug.sh lib/load-project.sh \ lib/parse-deps.sh lib/matrix_listener.sh # Run phase protocol test diff --git a/dev/phase-test.sh b/dev/phase-test.sh index f89a0c0..56a4a3b 100755 --- a/dev/phase-test.sh +++ b/dev/phase-test.sh @@ -41,7 +41,7 @@ check_phase() { local sentinel="$1" echo "$sentinel" > "$PHASE_FILE" local got - got=$(cat "$PHASE_FILE" | tr -d '[:space:]') + got=$(tr -d '[:space:]' < "$PHASE_FILE") if [ "$got" = "$sentinel" ]; then ok "write/read: $sentinel" else @@ -59,11 +59,17 @@ check_phase "PHASE:failed" echo "PHASE:awaiting_ci" > "$PHASE_FILE" echo "PHASE:awaiting_review" > "$PHASE_FILE" line_count=$(wc -l < "$PHASE_FILE") +file_content=$(cat "$PHASE_FILE") if [ "$line_count" -eq 1 ]; then ok "phase file overwrite (single line after two writes)" else fail "phase file should have 1 line, got $line_count" fi +if [ "$file_content" = "PHASE:awaiting_review" ]; then + ok "phase file overwrite (content is second write, not first)" +else + fail "phase file content should be 'PHASE:awaiting_review', got '$file_content'" +fi # ── Test 4: failed phase with reason ────────────────────────────────────────── printf 'PHASE:failed\nReason: %s\n' "shellcheck failed on ci.sh" > "$PHASE_FILE" diff --git a/docs/PHASE-PROTOCOL.md b/docs/PHASE-PROTOCOL.md index b981a65..4dbd7cb 100644 --- a/docs/PHASE-PROTOCOL.md +++ b/docs/PHASE-PROTOCOL.md @@ -37,7 +37,7 @@ Claude writes exactly one of these lines to the phase file when a phase ends: ### Writing a phase (from within Claude's session) ```bash -PHASE_FILE="/tmp/dev-session-${PROJECT_NAME}-${ISSUE}.phase" +PHASE_FILE="/tmp/dev-session-${PROJECT_NAME:-project}-${ISSUE:-0}.phase" # Signal awaiting CI echo "PHASE:awaiting_ci" > "$PHASE_FILE" @@ -58,9 +58,12 @@ echo "PHASE:failed" > "$PHASE_FILE" The orchestrator reads with: ```bash -phase=$(cat "$PHASE_FILE" 2>/dev/null | tr -d '[:space:]') +phase=$(head -1 "$PHASE_FILE" 2>/dev/null | tr -d '[:space:]') ``` +Using `head -1` is required: `PHASE:failed` may have a reason line on line 2, +and reading all lines would produce `PHASE:failedReason:...` which never matches. + ## Orchestrator Reaction Matrix ``` @@ -102,7 +105,8 @@ If the tmux session dies (Claude crash, OOM, kernel OOM-kill, compaction): ```bash # 1. Read current state from disk git_diff=$(git -C "$WORKTREE" diff origin/main..HEAD --stat 2>/dev/null) -last_phase=$(cat "$PHASE_FILE" 2>/dev/null || echo "PHASE:unknown") +last_phase=$(head -1 "$PHASE_FILE" 2>/dev/null | tr -d '[:space:]') +last_phase="${last_phase:-PHASE:unknown}" last_ci=$(cat "/tmp/ci-result-${PROJECT_NAME}-${ISSUE}.txt" 2>/dev/null || echo "") review_comments=$(curl -sf ... "${API}/issues/${PR}/comments" | jq ...) @@ -134,7 +138,7 @@ file and git history. |------|-----------|---------| | `/tmp/dev-session-{proj}-{issue}.phase` | Claude (in session) | Current phase | | `/tmp/ci-result-{proj}-{issue}.txt` | Orchestrator | Last CI output for injection | -| `/tmp/dev-{proj}-{issue}.log` | Orchestrator | Session transcript | +| `/tmp/dev-{proj}-{issue}.log` | Orchestrator | Session transcript (aspirational — path TBD when tmux session manager is implemented in #80) | | `WORKTREE` (git worktree) | dev-agent.sh | Code checkpoint | ## Sequence Diagram