refactor(opencode): удалены устаревшие профили safe-build/safe-plan

Профили дублировали работу permission-reviewer статическими списками:
их deny обходили ревьюер и давали отказы без причины (git push). Теперь
решения об ask принимает плагин; статикой оставлены только deny на чтение
секретов - детерминированная гарантия, LLM-ревьюеру не доверяем.

- opencode.json: default_agent -> build, убраны статические списки
  и deny на git push (решение за ревьюером)
- permission-reviewer.jsonc: actorProfiles переключены на встроенные
  build/plan
- install.sh: блок линковки agents заменён чисткой старого симлинка;
  добавлено копирование permission-reviewer.jsonc в ~/.config/opencode
  (плагин читает его только оттуда - раньше тюнинг не применялся)
- тесты: проверка чистки симлинка и копирования конфига ревьюера
This commit is contained in:
Dmitry Dementiev committed 2026-10-10 17:32:34 +02:00
1 parent c3efe60a00
commit 32cd7097e6
6 files changed
+34 -212

No files matched your search

+16 -2
View File
@@ -437,11 +437,19 @@ SKILLS_SRC="$DOTFILES_DIR/agents/.agents/skills"
OPENCODE_DIR="$HOME/.config/opencode"
OPENCODE_SRC_DIR="$DOTFILES_DIR/opencode/.config/opencode"
OPENCODE_JSON_SRC="$OPENCODE_SRC_DIR/opencode.json"
OPENCODE_REVIEWER_SRC="$OPENCODE_SRC_DIR/permission-reviewer.jsonc"
mkdir -p "$OPENCODE_DIR"
if [ -d "$OPENCODE_SRC_DIR/agents" ]; then
ensure_symlink "$OPENCODE_SRC_DIR/agents" "$OPENCODE_DIR/agents"
# Профили safe-build/safe-plan удалены: агенты встроенные (build/plan),
# решения об "ask" принимает permission-reviewer. Старый симлинк чистим.
if [ -L "$OPENCODE_DIR/agents" ]; then
case "$(readlink "$OPENCODE_DIR/agents" 2>/dev/null || true)" in
"$OPENCODE_SRC_DIR"*)
rm "$OPENCODE_DIR/agents"
info "Удалён устаревший симлинк ~/.config/opencode/agents"
;;
esac
fi
if [ -d "$SKILLS_SRC" ]; then
@@ -452,6 +460,12 @@ if [ -f "$OPENCODE_JSON_SRC" ]; then
copy_managed_file "$OPENCODE_JSON_SRC" "$OPENCODE_DIR/opencode.json" "opencode.json"
fi
# Настройки permission-reviewer: плагин читает их только из глобального
# ~/.config/opencode, из репозитория они не подхватываются — копируем.
if [ -f "$OPENCODE_REVIEWER_SRC" ]; then
copy_managed_file "$OPENCODE_REVIEWER_SRC" "$OPENCODE_DIR/permission-reviewer.jsonc" "permission-reviewer.jsonc"
fi
# ── Claude Code ──────────────────────────────────────────────────────
# Из репозитория линкуются только skills. Настройки (settings.json,
# settings.local.json) принадлежат Claude Code и живут только на машине.
@@ -1,91 +0,0 @@
---
description: Build agent with guarded shell access and no silent git mutations
mode: primary
tools:
write: true
edit: true
patch: true
bash: true
permission:
write: allow
edit: allow
patch: allow
webfetch: ask
task:
"*": deny
"explore": allow
bash:
"*": ask
# безопасное чтение
"pwd": allow
"ls": allow
"ls *": allow
"cat": allow
"cat *": allow
"head": allow
"head *": allow
"tail": allow
"tail *": allow
"wc -l": allow
"wc -l *": allow
# read-only git
"git status": allow
"git status *": allow
"git diff": allow
"git diff *": allow
"git log": allow
"git log *": allow
"git show": allow
"git show *": allow
"git blame": allow
"git blame *": allow
"git rev-parse": allow
"git rev-parse *": allow
"git branch --show-current": allow
"git branch --list*": allow
"git tag --list*": allow
# опасные git-операции — только с подтверждением
"git add*": ask
"git commit*": ask
"git switch*": ask
"git checkout*": ask
"git restore*": ask
"git reset*": ask
"git clean*": ask
"git merge*": ask
"git rebase*": ask
"git stash*": ask
"git fetch*": ask
"git pull*": ask
# push вообще запрещаем
"git push*": deny
# ключи и секреты не читаем даже по прямой просьбе
"*/.ssh/*": deny
"*id_rsa*": deny
"*id_ed25519*": deny
"*.pem": deny
"*shadow*": deny
"*.env": deny
"*.env.*": deny
"*.secrets*": deny
"*.netrc*": deny
# а примеры env-файлов читать можно
"*.env.example": allow
---
You are a build agent.
Default to making code changes through native file-editing tools.
Use bash when it is the clearest path, but avoid unnecessary shell usage.
Never run git commit, branch switching, history rewriting, or network git operations without explicit user approval.
Prefer built-in tools for reading files and searching code.
@@ -1,112 +0,0 @@
---
description: Safe planning and repository analysis with read-only focus
mode: primary
tools:
write: false
edit: false
patch: false
bash: true
permission:
webfetch: ask
task:
"*": deny
"explore": allow
bash:
"*": ask
"pwd": allow
"ls": allow
"ls *": allow
"find": allow
"find *": allow
"cat": allow
"cat *": allow
"head": allow
"head *": allow
"tail": allow
"tail *": allow
"wc -l": allow
"wc -l *": allow
"rg": allow
"rg *": allow
"git status": allow
"git status *": allow
"git diff": allow
"git diff *": allow
"git log": allow
"git log *": allow
"git show": allow
"git show *": allow
"git blame": allow
"git blame *": allow
"git remote -v": allow
# жёсткий запрет на мутации
"git add*": deny
"git commit*": deny
"git switch*": deny
"git checkout*": deny
"git restore*": deny
"git reset*": deny
"git clean*": deny
"git merge*": deny
"git rebase*": deny
"git stash*": deny
"git push*": deny
# ключи и секреты не читаем даже по прямой просьбе
"*/.ssh/*": deny
"*id_rsa*": deny
"*id_ed25519*": deny
"*.pem": deny
"*shadow*": deny
"*.env": deny
"*.env.*": deny
"*.secrets*": deny
"*.netrc*": deny
# а примеры env-файлов читать можно
"*.env.example": allow
"git pull*": deny
"git fetch*": deny
"rm *": deny
"mv *": deny
"cp *": deny
"tee *": deny
"chmod *": deny
"chown *": deny
"sed -i*": deny
"perl -pi*": deny
"python*": deny
"node*": deny
"sh -c*": deny
"bash -c*": deny
"npm *": deny
"pnpm *": deny
"yarn *": deny
"bun *": deny
---
You are a planning and analysis agent.
For repository briefing:
1. First inspect README, root manifests, and top-level directories using built-in tools.
2. Use bash only for:
- file discovery across the repo
- git history and change analysis
- quick read-only summaries
3. Never use bash for edits or execution of interpreters.
Prefer:
- read/list/glob/grep for content inspection
- git log/show/diff/blame for history
- find/rg only when built-in tools are inconvenient
+11 -3
View File
@@ -6,7 +6,7 @@
"options": {}
}
],
"default_agent": "safe-plan",
"default_agent": "build",
"permission": {
"write": "ask",
"edit": "ask",
@@ -15,8 +15,16 @@
"task": "ask",
"bash": {
"*": "ask",
"git push": "deny",
"git push *": "deny"
"*/.ssh/*": "deny",
"*id_rsa*": "deny",
"*id_ed25519*": "deny",
"*.pem": "deny",
"*shadow*": "deny",
"*.env": "deny",
"*.env.*": "deny",
"*.secrets*": "deny",
"*.netrc*": "deny",
"*.env.example": "allow"
}
},
"mcp": {
@@ -12,9 +12,9 @@
"variant": "none",
"outputFormat": "json_schema"
},
// Профили наших агентов: снимает "actor identity partial" у ревьюера
// Профили встроенных агентов: снимает "actor identity partial" у ревьюера
"actorProfiles": {
"safe-build": "workspace",
"safe-plan": "read-only"
"build": "workspace",
"plan": "read-only"
}
}
+4 -1
View File
@@ -482,13 +482,16 @@ test_opencode_runtime_dir_is_preserved_and_config_is_managed() {
cat > "$home_dir/.config/opencode/opencode.json" <<'EOF'
{"source":"local"}
EOF
# Артефакт прежнего установщика: симлинк на удалённые профили агентов
ln -s "$repo_root/opencode/.config/opencode/agents" "$home_dir/.config/opencode/agents"
run_install "$repo_root" "$home_dir" env WSL_DISTRO_NAME= INSTALL_INTERACTIVE_MODE=never >/tmp/test-install.out
[ -f "$home_dir/.config/opencode/package.json" ] || fail "Expected opencode runtime files to be preserved"
[ -L "$home_dir/.config/opencode/agents" ] || fail "Expected ~/.config/opencode/agents symlink"
assert_not_exists "$home_dir/.config/opencode/agents"
[ -L "$home_dir/.config/opencode/skills" ] || fail "Expected ~/.config/opencode/skills symlink"
assert_file_contains "$home_dir/.config/opencode/opencode.json" '"$schema": "https://opencode.ai/config.json"'
assert_file_contains "$home_dir/.config/opencode/permission-reviewer.jsonc" '"confidenceThreshold"'
backup_path="$(find "$home_dir/.config/opencode" -maxdepth 1 -name 'opencode.json.bak.*' -print -quit)"
[ -n "$backup_path" ] || fail "Expected backup for existing opencode.json"