作成日: 2026-03-31
ステータス: Draft
対象: read_from_gitea, record_to_gitea
関連文書:
本仕様は、butler2 における Gitea issue 操作 capability の最小仕様を定義する。
butler2 の最初の実装対象として Gitea issue 操作を選ぶ理由は次の通り。
本仕様の初期主眼は、Gitea 全機能ではなく issue 操作の安定化にある。
また、Issue 本文は ~/develop/issue のダッシュボード系ツールが読める構造化テンプレートに従うことを前提とする。
旧 ButlerLayer には read_from_gitea / record_to_gitea 相当の実装が存在したが、
butler2 ではそれをそのまま移植するのではなく、Maid routing 前提の capability として再整理する。
参照価値があるのは過去コードそのものではなく、次のような暗黙要件である。
Gitea capability は、Butler が Gitea issue を読み書きするための domain capability である。
初期段階では Butler 直下の known handler としては実装せず、
non-LLM Maid として Maid routing の対象に載せる。
理由:
Brain は Gitea API の詳細やエンドポイントを意識せず、
intent, target, payload.operation を通じて issue 操作を依頼する。
初期実装では issue 操作に限定する。
対象:
旧実装には次も含まれていたが、butler2 の最初の段階では主対象にしない。
これらは将来拡張として扱い、issue 操作が安定してから段階的に戻す。
初期段階では read_from_gitea と record_to_gitea を non-LLM Maid で実装する。
Goose Maid ではないが、Maid routing の対象には載せる。
理由:
Gitea issue 操作は、初期段階では次のような Maid として扱う。
kind: script または non_llm_worker 相当provider: local_scriptmodel: n/arole: gitea_issue_ops重要なのは、LLM を使わないことではなく、
他の内部実務ユニットと同じく Butler から見た Maid として統一することである。
新規 Issue は、repo 内の .gitea/ISSUE_TEMPLATE/ にあるテンプレートに従って起票する。
これは見た目の統一ではなく、~/develop/issue のダッシュボードが
本文中の次の 3 フィールドをパースして一覧表示・編集するためである。
## 現在の状態(なぜOpenか)## 次にすること(Next Action)## ブロック要因したがって create_issue は、テンプレート名と入力値から本文を組み立てるか、
少なくともこの 3 見出しを含む構造化本文だけを受け付ける。
read_from_giteaGitea issue 情報を取得する read intent。
同期実行を前提とする。
Butler 内部では対象 non-LLM Maid へ委譲して実行する。
基本 contract:
intent: read_from_giteatarget.service: giteadelegation_mode: known_onlyrecord_to_giteaGitea issue 情報を更新する write intent。
初期段階では同期実行を基本とする。
Butler 内部では対象 non-LLM Maid へ委譲して実行する。
基本 contract:
intent: record_to_giteatarget.service: giteadelegation_mode: known_only| キー | 必須 | 意味 |
|---|---|---|
operation |
必須 | 実行したい操作名 |
owner |
必須 | Gitea リポジトリ owner |
repo |
必須 | Gitea リポジトリ名 |
client |
任意 | 呼び出しクライアント識別子。省略時は既定値を使う |
| operation | 必須追加項目 | 内容 |
|---|---|---|
list_issues |
なし | issue 一覧を取得する |
get_issue |
issue_id |
issue 詳細を取得する |
get_issue_comments |
issue_id |
issue コメント一覧を取得する |
list_labels |
なし | ラベル一覧を取得する |
detect_project_api |
なし | Gitea Project API capability(has_projects と swagger 上の path 有無)を判定する |
初期オプション:
state: open / closed / alllimit: 取得件数labels: ラベル絞り込み| operation | 必須追加項目 | 内容 |
|---|---|---|
create_issue |
title |
issue を作成する |
add_issue_comment |
issue_id, note |
issue にコメントを追加する |
delete_issue_comment |
issue_id, comment_id |
issue コメントを削除する |
update_issue |
issue_id + 更新項目 |
issue を更新する |
close_issue |
issue_id |
issue を closed にする |
close_issue_with_note |
issue_id |
コメント追加後に close する |
add_labels |
issue_id, label_ids |
issue にラベルを付与する |
create_label |
name |
ラベルを作成する |
update_issue で受ける更新項目:
titlebodystatelabelscreate_issue の任意項目:
bodylabelstemplate_nametemplate_fieldslabel_namescreate_issue では、原則として次のどちらかを要求する。
template_name と template_fieldsbody推奨は 1 である。
2 は、テンプレート未整備の暫定 repo や移行期に限る互換経路として扱う。
例:
{
"operation": "create_issue",
"owner": "akira",
"repo": "butler2",
"title": "新butlerでのGitea issue操作実装",
"template_name": "feature",
"template_fields": {
"status": "未着手のため Open",
"next_action": "non-LLM Maid を実装する",
"blocker": "なし",
"summary": "Gitea issue 操作を新しい Butler で扱えるようにする",
"background": "旧 Butler ではテンプレートが崩れ、一覧ツールで状態が読めなかった",
"done_criteria": "Issue 作成・更新・コメント・クローズが新 Butler 経由で実行できる",
"related": "関連 Issue なし"
}
}
テンプレート名は repo 内 .gitea/ISSUE_TEMPLATE/*.md と対応する。
初期テンプレートは feature, bug, design の 3 種を想定する。
ラベルは次の 3 経路で付与できる。
labelslabel_nameslabel_idscreate_issue 時は、テンプレート既定ラベルと label_names を名前解決して ID に変換し、
label_ids とマージして Gitea API に渡す。
Gitea capability は、成功可否を単なる応答コードではなく evidence 付きで返す。
初期段階では次の形を基本とする。
operationread 系は取得したオブジェクトそのものを evidence に含める。
例:
get_issue: issuelist_issues: issuesget_issue_comments: commentslist_labels: labelsdetect_project_api: repo_projects_enabled, projects_mode, project_api_declared, project_api_scope, manual_fallback, candidates(swagger から抽出した Project API 候補 path 一覧)write 系は API の返却内容に加え、可能な限り再取得または状態確認で検証する。
初期方針:
create_issue: 作成後に issue を再取得してタイトル一致を確認するclose_issue: 返却 issue の state == "closed" を確認するupdate_issue: 返却 issue を evidence に残すadd_issue_comment: 追加した comment を evidence に残すdelete_issue_comment: 削除対象の issue_id と comment_id を evidence に残すcreate_issue: テンプレート名と解決済みラベルも evidence に残すbutler2 では将来的に、write 系は「before / action result / after」を揃える方向へ強化してよい。
need_input次の場合は need_input を返す。
payload.operation が無いowner / repo が無いfailed次の場合は failed を返す。
label_names が解決できない失敗時 evidence には少なくとも以下を残す。
operationerrorissue_id初期段階では Gitea REST API を直接呼ぶ。
MCP 経由ではなく、Gitea 用 non-LLM Maid の実装内で HTTP を実行する。
初期想定の環境変数:
GITEA_URLGITEA_TOKEN_AI またはクライアント別トークンbutler2 では、その実装有無に関わらず仕様としては次を満たす。
各プロジェクトは .gitea/ISSUE_TEMPLATE/ に Issue テンプレートを持つ。
butler2 の Gitea Maid は起票時にそのテンプレートを参照する。
このルールにより、project ごとにテンプレートを持ちつつ、
~/develop/issue のダッシュボードが同じ構造で横断利用できる。
初期段階では handler 内に最小 verifier を持つ。
後に Butler 共通 verifier へ寄せられるなら移行してよい。
issue 操作は初期段階では同期実行でよい。
将来的に破壊的操作や長時間処理が加わる場合のみ、承認ゲート付き非同期実行を検討する。
read_from_gitea.list_issuesread_from_gitea.get_issuerecord_to_gitea.create_issueここで Butler の contract → Maid routing → non-LLM Maid 実行 → evidence の最小往復を成立させる。
get_issue_commentsadd_issue_commentdelete_issue_commentupdate_issueclose_issueここで issue ライフサイクルを一通り扱えるようにする。
list_labels ✅add_labels ❌ 未実装create_label ❌ 未実装close_issue_with_note ✅(gitea_close_issue の note パラメータで対応)ここで日常運用に必要な補助操作を加える。
read_from_gitea.detect_project_api ✅ 実装済み(Project API capability 判定のみ。board 操作本体は未実装。詳細: issue #80 / docs/検討用/80_Gitea_Project_API対応実装案.md)将来的には次を検討してよい。
ただし初期段階では「issue の読み書きが確実にできること」を優先し、拡張を急がない。
docs/マスタードキュメント.mddocs/黒執事アーキテクチャ_v2.md