tools: run-plan: pure sessions, resume after the limit, row named
Three changes from the M5b run (implementer lessons T47, T48): - each session runs `opencode run --pure` with OPENCODE_DISABLE_CLAUDE_CODE=1, so no global plugin or borrowed rules file reaches the implementer; PLUGINS=1 restores both; - with RESUME=1, a session stopped at SESSION_LIMIT_MIN with work left uncommitted is resumed once, as one that ended by itself already was; an idle stop is still not resumed; - the prompt names the log row's Task cell, so a task's heading cannot mislead the row the driver then looks for. Checked against a stub opencode in scratch repositories (17 checks: the flags and variable, PLUGINS=1, a resume after the limit, no resume without work or without RESUME). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+25
-9
@@ -8,14 +8,18 @@
|
|||||||
# OPENCODE_MODEL model to use (default straylight/laguna-s-2.1; OpenCode's own default differs).
|
# OPENCODE_MODEL model to use (default straylight/laguna-s-2.1; OpenCode's own default differs).
|
||||||
# The part after the provider (`ornith-1.5-35b-a3b`) names the model in each
|
# The part after the provider (`ornith-1.5-35b-a3b`) names the model in each
|
||||||
# commit's `Co-Authored-By: <model> <agent@wntrmute.dev>` trailer and in the log.
|
# commit's `Co-Authored-By: <model> <agent@wntrmute.dev>` trailer and in the log.
|
||||||
# OPENCODE_FLAGS extra flags for `opencode run`, for example "--pure"
|
# OPENCODE_FLAGS extra flags for `opencode run`
|
||||||
|
# PLUGINS=1 load OpenCode's external plugins and let it read ~/.claude/CLAUDE.md. By
|
||||||
|
# default each session runs with `--pure` and OPENCODE_DISABLE_CLAUDE_CODE=1:
|
||||||
|
# a global plugin that rewrites the prompt forces a full re-read on a model
|
||||||
|
# that cannot rewind its cache (implementer lessons, T48).
|
||||||
# SESSION_LIMIT_MIN minutes a session may run before it is stopped (default 90)
|
# SESSION_LIMIT_MIN minutes a session may run before it is stopped (default 90)
|
||||||
# SLOTS_URL llama-server's slots URL, for example
|
# SLOTS_URL llama-server's slots URL, for example
|
||||||
# http://127.0.0.1:8081/slots?model=ornith-1.5-35b-a3b. When set, a session is
|
# http://127.0.0.1:8081/slots?model=ornith-1.5-35b-a3b. When set, a session is
|
||||||
# stopped once no slot has been busy for IDLE_LIMIT_MIN minutes (default 10).
|
# stopped once no slot has been busy for IDLE_LIMIT_MIN minutes (default 10).
|
||||||
# Trial: not yet used on a run.
|
# Trial: not yet used on a run.
|
||||||
# RESUME=1 when a session ends with work left uncommitted, resume it once. Trial: not
|
# RESUME=1 when a session ends, or is stopped at SESSION_LIMIT_MIN, with work left
|
||||||
# yet used on a run.
|
# uncommitted, resume it once, in a new session with the same limit.
|
||||||
# DRY_RUN=1 print what would be run and stop
|
# DRY_RUN=1 print what would be run and stop
|
||||||
# Each session runs as the `implement` agent of ./opencode.json: its permissions deny edits to the
|
# Each session runs as the `implement` agent of ./opencode.json: its permissions deny edits to the
|
||||||
# plans and design documents, reads outside the repository, subagents and pushes.
|
# plans and design documents, reads outside the repository, subagents and pushes.
|
||||||
@@ -42,9 +46,15 @@ mkdir -p "$runs"
|
|||||||
# `pkill`, which would match this script too.
|
# `pkill`, which would match this script too.
|
||||||
run_session() {
|
run_session() {
|
||||||
set -m
|
set -m
|
||||||
|
if [ "${PLUGINS:-0}" = 1 ]; then
|
||||||
|
pure=""
|
||||||
|
else
|
||||||
|
pure="--pure"
|
||||||
|
export OPENCODE_DISABLE_CLAUDE_CODE=1
|
||||||
|
fi
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
opencode run --agent implement -m "$model" ${OPENCODE_FLAGS:-} --title "$milestone/$name" "$1" \
|
opencode run $pure --agent implement -m "$model" ${OPENCODE_FLAGS:-} --title "$milestone/$name" \
|
||||||
>> "$runs/$name.log" 2>&1 &
|
"$1" >> "$runs/$name.log" 2>&1 &
|
||||||
pid=$!
|
pid=$!
|
||||||
set +m
|
set +m
|
||||||
started=$(date +%s)
|
started=$(date +%s)
|
||||||
@@ -83,7 +93,8 @@ for task in "$plan"/[0-9][0-9]-*.md; do
|
|||||||
name=$(basename "$task" .md)
|
name=$(basename "$task" .md)
|
||||||
number=$(echo "$name" | cut -c1-2)
|
number=$(echo "$name" | cut -c1-2)
|
||||||
[ "$number" -ge "$first" ] || continue
|
[ "$number" -ge "$first" ] || continue
|
||||||
prompt="Read \`$task\` and do exactly that task. You are $agent: write $agent in the log row's Model column, and end the commit message with this line, exactly: $trailer"
|
row="Your log row's Task cell is \`$milestone/$name\`, and you are $agent: write $agent in its Model column, and end the commit message with this line, exactly: $trailer"
|
||||||
|
prompt="Read \`$task\` and do exactly that task. $row"
|
||||||
|
|
||||||
if [ "${DRY_RUN:-0}" = 1 ]; then
|
if [ "${DRY_RUN:-0}" = 1 ]; then
|
||||||
echo "opencode run --agent implement -m $model ${OPENCODE_FLAGS:-} --title $milestone/$name \"$prompt\""
|
echo "opencode run --agent implement -m $model ${OPENCODE_FLAGS:-} --title $milestone/$name \"$prompt\""
|
||||||
@@ -100,11 +111,16 @@ for task in "$plan"/[0-9][0-9]-*.md; do
|
|||||||
# A new `opencode run` is a new session: nothing carries over from the task before.
|
# A new `opencode run` is a new session: nothing carries over from the task before.
|
||||||
rc=0
|
rc=0
|
||||||
run_session "$prompt" || rc=$?
|
run_session "$prompt" || rc=$?
|
||||||
if [ "$rc" = 0 ] && [ "${RESUME:-0}" = 1 ] && [ "$(git rev-parse HEAD)" = "$before" ] \
|
# A session that ended, or ran out of time, part-way through a task is resumed once. One stopped
|
||||||
&& [ -n "$(git status --porcelain)" ]; then
|
# for idling (125) is not: the server, not the task, is the likely cause.
|
||||||
|
if { [ "$rc" = 0 ] || [ "$rc" = 124 ]; } && [ "${RESUME:-0}" = 1 ] \
|
||||||
|
&& [ "$(git rev-parse HEAD)" = "$before" ] && [ -n "$(git status --porcelain)" ]; then
|
||||||
|
if [ "$rc" = 124 ]; then
|
||||||
|
echo "=== $milestone/$name: stopped at $limit minutes with work uncommitted"
|
||||||
|
fi
|
||||||
echo "=== $milestone/$name: work left uncommitted; resuming once $(date '+%H:%M:%S')"
|
echo "=== $milestone/$name: work left uncommitted; resuming once $(date '+%H:%M:%S')"
|
||||||
rc=0
|
rc=0
|
||||||
run_session "The previous session on \`$task\` left uncommitted work (see \`git diff\`). Do not start over. Finish the task, run the gate, commit, and write the log row. You are $agent: write $agent in the log row's Model column, and end the commit message with this line, exactly: $trailer" || rc=$?
|
run_session "The previous session on \`$task\` left uncommitted work (see \`git diff\`). Do not start over. Finish the task, run the gate, commit, and write the log row. $row" || rc=$?
|
||||||
fi
|
fi
|
||||||
case "$rc" in
|
case "$rc" in
|
||||||
0) ;;
|
0) ;;
|
||||||
|
|||||||
Reference in New Issue
Block a user