Open-source release of MAESTRO, an agent orchestration platform that runs LLM-driven tasks through sandboxed tools, with a web UI. Apache-2.0. See README.md and docs/ (getting-started, configuration, architecture).
132 lines
7.7 KiB
YAML
132 lines
7.7 KiB
YAML
name: ssh-ops
|
|
description: |
|
|
SSH 経由でリモートホストに対するオペレーションを実行する。
|
|
サーバー稼働確認 (health check)、設定ファイル配信とリロード (config push)、
|
|
ログ取得と分析 (log fetch) の 3 軸をカバーする ops piece。
|
|
|
|
選ぶべき場合: タスクが「SSH で〜したい」「リモートサーバーで〜を実行」「サーバーから〜を取得」等
|
|
選ぶべきでない場合: ローカル作業のみ、Web 調査のみ、Office 加工のみ
|
|
|
|
事前条件:
|
|
- admin が `config.yaml` の `ssh.enabled: true` を設定済み
|
|
- 利用する SSH 接続が登録され、TOFU host key 検証が完了
|
|
(Settings → User Folder → SSH Connections → 該当接続 → Test)
|
|
- ジョブ owner に接続への grant がある (private は owner 自身、global は admin の grant)
|
|
|
|
詳細: docs/ssh.md (operator runbook) と docs/tools/ssh-tools.md (LLM 向け)
|
|
triggers:
|
|
keywords: ["SSH", "リモート", "サーバー", "デプロイ", "ヘルスチェック", "ログ取得", "remote"]
|
|
max_movements: 50
|
|
initial_movement: execute
|
|
|
|
movements:
|
|
- name: execute
|
|
edit: true
|
|
persona: ops-operator
|
|
instruction: |
|
|
## 最初のステップ: タスク把握と接続の選定
|
|
|
|
1. Glob で input/ と output/ の現状を確認する
|
|
2. タスク本文を読み、以下のどの軸かを判定する (複合も可):
|
|
- Health check: uptime / df -h / free -m / process status / journalctl 等で状態確認
|
|
- Config push: ローカルで作成・編集した設定を SshUpload で配信 → SshExec でリロード
|
|
- Log fetch: SshDownload でリモートのログを取得 → ローカルで grep / 集計 / 分析
|
|
3. タスクで指定された SSH 接続 ID を確認する。指定が無く接続候補が複数ある場合は
|
|
`complete({status: "needs_user_input", missing_info: "どの SSH 接続を使うか"})` で確認する
|
|
|
|
## SshExec の使い方
|
|
|
|
- 単発コマンド: `SshExec({connection_id, command})`
|
|
- output は JSON envelope (`{stdout, stderr, exit_code, truncated, ...}`)。
|
|
`truncated: true` の場合は出力が大きすぎる → `SshDownload` で file 経由に切り替える
|
|
- 機密値 (token / password) は command 文字列に直接渡さない。リモート側の env や config に置く
|
|
- 接続ごとに deny-list / allow-list が設定されていることがある。`command_rejected` エラーは
|
|
admin に許可パターン追加を相談する (ローカルで回避してはいけない)
|
|
|
|
## SshUpload / SshDownload の使い方
|
|
|
|
- リモートパスは接続の `remote_path_prefix` 配下のみ書き換え可能。違反は `path_not_allowed` で reject
|
|
- ローカルパスは workspace の output/ または input/ 配下を推奨
|
|
- 大きなファイル: 上限は接続/グローバル設定の `max_upload_size_mb` / `max_download_size_mb`
|
|
- Download 先のファイルが既にある場合は `local_target_exists` で reject される。
|
|
旧版を消すかリネームしてから再実行する
|
|
|
|
## エラーハンドリング (詳細は docs/tools/ssh-tools.md の error code 表)
|
|
|
|
- `host_key_not_verified`: TOFU 未完了。
|
|
`complete({status: "needs_user_input", missing_info: "SSH 接続 <id> の host key を UI で検証してください (Settings → User Folder → SSH Connections → Test)"})` で停止する
|
|
- `host_key_mismatch`: MITM 疑い。**自動でリトライしない**。
|
|
`complete({status: "aborted", abort_reason: "host_key_mismatch: <details>"})` で停止する
|
|
- `abuse_locked`: 連続失敗で接続がロック。
|
|
`complete({status: "needs_user_input", missing_info: "接続が <until> までロックされています。admin に force-unlock を依頼してください"})` で停止する
|
|
- `no_grant` / `access_denied`: 権限不足。admin に grant 追加を依頼するよう user に報告して停止する
|
|
- `connect_timeout` / `auth_failed` 等の一時失敗: 同じ command を最大 2 回まで再試行。
|
|
それ以上は `complete({status: "aborted", abort_reason: "..."})`
|
|
|
|
## 成果物
|
|
|
|
ops の結果は output/report.md にまとめる。**機密値は記録しない**:
|
|
- 実行した command (機密値はマスク) と使用した接続 ID
|
|
- SshExec の場合は stdout/stderr の要点 (全文ではなく要約。重要な行のみ転載)
|
|
- SshUpload/SshDownload の場合は転送したファイル名 + サイズ
|
|
- 観測した状態 / 異常があれば項目立てて記述
|
|
- 推奨アクション (異常があれば「再起動を提案」等) または「異常なし」の明示
|
|
|
|
## 終了 / 遷移方法
|
|
|
|
- **次の verify へ**: `transition({next_step: "verify"})`
|
|
- **必要情報不足で停止**: `complete({status: "needs_user_input", missing_info: "...", why_no_default: "..."})`
|
|
- **致命的失敗で打ち切り**: `complete({status: "aborted", abort_reason: "..."})`
|
|
allowed_tools: [SshExec, SshUpload, SshDownload, SshListConnections, Read, Write, Bash, Glob, Grep]
|
|
allowed_ssh_connections: ['*']
|
|
default_next: verify
|
|
rules:
|
|
- condition: output/report.md に ops 結果をまとめた
|
|
next: verify
|
|
|
|
- name: verify
|
|
edit: false
|
|
persona: reviewer
|
|
instruction: |
|
|
ops 結果を確認する。
|
|
|
|
確認手順:
|
|
1. Glob で output/report.md の存在を確認する
|
|
2. 報告書が無い、または内容が抽象論だけで実行結果が記載されていない場合は execute に差し戻す
|
|
3. Read で report.md を読み、以下をチェック:
|
|
- 実行した command / 接続 ID が記録されているか
|
|
- 観測結果 (stdout 要点 or 転送ファイル一覧) が記載されているか
|
|
- 異常があった場合、推奨アクションが書かれているか
|
|
- **機密値 (token / password / 秘密鍵 fingerprint 全体 / .env 内容等) が漏れていないか**
|
|
4. 不足があれば `transition({next_step: "execute", summary: ...})` で差し戻す:
|
|
[判定] needs_fix
|
|
## 問題点
|
|
- [報告書の項目] 何が問題か
|
|
## 期待する修正
|
|
- 何をどう直すべきか
|
|
## 合格基準
|
|
- 再レビューで何を確認するか
|
|
## 次にやること
|
|
- execute で最初に着手すべき具体的な作業
|
|
5. **機密値漏れを検出した場合は ABORT** (差し戻さない、ファイルにも残さない):
|
|
`complete({status: "aborted", abort_reason: "secret_leak: report.md contained <field> credential"})`
|
|
|
|
## 合格時のユーザーへの返答
|
|
|
|
`complete({status: "success", result: ...})` で output/report.md の要点を会話調で返す。
|
|
result そのものが user に表示される最終回答 (「report.md を確認」のような参照ではなく内容を書く)。
|
|
- 1 行目からいきなり本題: 「✅ 完了」等のメタ文言は禁止
|
|
- 観測した状態 + 推奨アクションを構造化して提示
|
|
- 異常無しなら明示する
|
|
|
|
## 終了方法のまとめ
|
|
- 合格: `complete({status: "success", result: "ユーザー向け最終回答"})`
|
|
- 修正必要: `transition({next_step: "execute", summary: "差し戻し指摘"})`
|
|
- 機密漏れ: `complete({status: "aborted", abort_reason: "secret_leak: ..."})`
|
|
- 技術的失敗: `complete({status: "aborted", abort_reason: "..."})`
|
|
allowed_tools: [Read, Glob, Grep]
|
|
default_next: COMPLETE
|
|
rules:
|
|
- condition: ops 報告が不足している
|
|
next: execute
|