opencode.json: an implement agent for unattended runs; run-plan uses it

From the combined Ornith guidance (§8.2), checked against OpenCode
1.18.30's schema and permission docs (last matching rule wins). Reads
and edits outside the repository are denied, except OpenCode's own
tool-output and temporary directories; web access, questions, subagents
and doom-loop prompts are denied; edits to AGENTS.md, CLAUDE.md,
opencode.json, the design documents, specs, plans and tools/ are denied;
shell commands are allowed except push, reset, rebase, amend, switch,
checkout, find /, locate, sudo, rm -rf / and curl/wget. A denied call
continues the loop (experimental.continue_loop_on_deny, untested with
Ornith). steps = 400 is a backstop. No custom prompt: OpenCode already
reads AGENTS.md, and a prompt may replace its tool guidance.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-26 00:18:03 -07:00
co-authored by Claude Opus 5.5
parent 0356c877dd
commit 31fe078e64
2 changed files with 62 additions and 3 deletions
+5 -3
View File
@@ -8,7 +8,9 @@
# 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
# commit's `Co-Authored-By: <model> <agent@wntrmute.dev>` trailer and in the log.
# OPENCODE_FLAGS extra flags for `opencode run`, for example "--pure" or "--auto"
# OPENCODE_FLAGS extra flags for `opencode run`, for example "--pure"
# 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.
# DRY_RUN=1 print what would be run and stop
set -eu
@@ -32,7 +34,7 @@ for task in "$plan"/[0-9][0-9]-*.md; do
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"
if [ "${DRY_RUN:-0}" = 1 ]; then
echo "opencode run -m $model ${OPENCODE_FLAGS:-} --title $milestone/$name \"$prompt\""
echo "opencode run --agent implement -m $model ${OPENCODE_FLAGS:-} --title $milestone/$name \"$prompt\""
continue
fi
if [ -n "$(git status --porcelain)" ]; then
@@ -44,7 +46,7 @@ for task in "$plan"/[0-9][0-9]-*.md; do
echo "=== $milestone/$name: started $(date '+%H:%M:%S')"
# A new `opencode run` is a new session: nothing carries over from the task before.
# shellcheck disable=SC2086
if ! opencode run -m "$model" ${OPENCODE_FLAGS:-} --title "$milestone/$name" "$prompt" \
if ! opencode run --agent implement -m "$model" ${OPENCODE_FLAGS:-} --title "$milestone/$name" "$prompt" \
> "$runs/$name.log" 2>&1; then
echo "run-plan: opencode exited with an error in $name; see $runs/$name.log" >&2
exit 1