コンテンツにスキップ

Slack MCP Agent — MVP 要件定義書

v2.3 / 2026-04-20

本書は docs/requirements.md(要求定義書 v1.1)を入力とし、各機能の入出力契約・状態遷移・受け入れ条件を定義する。


1. MVP 概要

1.1 スコープサマリー

領域 内容 開発優先度
Slack Bot + パイプライン L1-L4、承認ゲート、却下再生成、中止、再実行 1(最優先)
実 freee API 統合 OAuth 認証、勤怠集計シナリオの 3 ツール 1(並行)
Web 管理画面 Pipeline / Settings / Integrations / Audit 2(作り込み)

1.2 インタラクション面

エントリーポイント イベント 用途 MVP
チャンネルメンション app_mention チーム可視の承認フロー 主軸(実装済み)
Agent Container(Split Pane) assistant_thread_started / message.im 1:1 AI 対話、サジェストプロンプト Post-MVP(docs/post-mvp-roadmap.md 参照)

MVP はチャンネルメンション(app_mention)のみを実装する。Agent Container は Post-MVP で追加予定。

1.3 対象シナリオ

勤怠集計(先月分の打刻データ集計 → Sheet 出力 → 完了通知)

1.4 テナント

シングルテナント運用。データモデルに tenant_id を含め将来のマルチテナント拡張に備える。


2. 4 層パイプライン仕様

2.1 L1: Message → Task

入力

項目 説明
user_message string チャンネルメンション: ボット ID を除去したテキスト
source string channel 固定(MVP)。Post-MVP で agent_container を追加予定

処理

  • Anthropic SDK messages.create で 1-shot 呼び出し
  • System Prompt: backend/src/prompts/l1_system.md(HR 業務理解 AI)
  • User メッセージを <user_input> タグで隔離
  • max_tokens: 2048
  • Model: claude-sonnet-4-6(環境変数 CLAUDE_MODEL で上書き可)

出力: Task JSON

{
  "title": "勤怠集計 (先月分)",
  "description": "先月 1〜末日の打刻データを集計し、給与計算用に出力",
  "priority": "low | medium | high",
  "taskType": "standard | urgent"
}

バリデーション

  • JSON パース成功
  • title, description, priority, taskType の 4 キーが存在
  • priority{low, medium, high}
  • taskType{standard, urgent}

エラー時

  • ValueError を raise → 呼び出し元(orchestrator)がキャッチし Slack にエラー通知

副作用

  • DB: tasks レコード作成(status: extracted
  • Slack: Task カード投稿 → Task 情報で chat.update

2.2 L2: Task → Prompt

入力

項目 説明
task_json dict L1 の出力
tool_catalog string テナントに許可されたツール一覧(Markdown テキスト)

処理

  • Anthropic AsyncAnthropic messages.create で 1-shot 呼び出し
  • System Prompt: backend/src/prompts/l2_system.md(HR オペレーションプランナー)
  • max_tokens: 8192
  • 却下時は前回 Prompt と rejection_reason を user メッセージに含めて再生成

出力: Prompt Content

番号付き手順書(自然言語テキスト)。ツール名・入出力・エラー時対応を含む。

1. list_employees を使って全従業員を取得する
   - 入力: department=all
   - 出力: 従業員 ID と名前の一覧
2. 各従業員について list_attendance で先月分の勤怠データを取得
   ...

バリデーション

  • 空文字列・空白のみでない

エラー時

  • ValueError を raise → Slack にエラー通知

副作用

  • DB: prompts レコード作成(status: generatingpending_approval
  • Slack: Prompt カード投稿(生成中 → 承認待ちに chat.update

承認ゲート 1

  • 承認: prompts.statusapproved、L3 へ進む
  • 却下: 理由入力モーダル表示 → フィードバック付きで L2 を再実行、prompts.version を +1

2.3 L3: Prompt → Process

入力

項目 説明
prompt_content string 承認済み Prompt テキスト
tool_schemas string テナントに許可されたツールの JSON Schema

処理

  • Anthropic AsyncAnthropic messages.create で 1-shot 呼び出し
  • System Prompt: backend/src/prompts/l3_system.md(JSON only 強制)
  • max_tokens: 8192
  • コードフェンス(```json )がある場合は除去してパース

出力: Process JSON

{
  "steps": [
    {
      "stepId": "step_1",
      "order": 1,
      "title": "従業員一覧を取得",
      "description": "全従業員の ID と名前を取得する",
      "tool": "list_employees",
      "toolInput": { "department": "all" },
      "requiresHumanCheck": false
    }
  ]
}

Step フィールド定義

フィールド 必須 説明
stepId string ユニーク ID(step_N
order integer 実行順序(1-based)
title string ステップ名
description string 実行内容の説明
tool string ツール名(tool_schemasname と一致)
toolInput object ツールへの入力パラメータ
requiresHumanCheck boolean 重要操作前の停止フラグ(MVP では auto-approve)

バリデーション

  • JSON パース成功
  • トップレベルに steps キーが存在
  • 各ステップに必須フィールドが存在

副作用

  • DB: processes レコード作成(status: generatingpending_approval
  • Slack: Process カード投稿(生成中 → 承認待ちに chat.update

承認ゲート 2

  • 承認: processes.statusapprovedtasks.statusrunning、L4 へ進む
  • 却下: 理由入力モーダル表示 → フィードバック付きで L3 を再実行、processes.version を +1

2.4 L4: Process → Execution

入力

項目 説明
steps list[dict] 承認済み Process の steps 配列
agent_id string Managed Agent の Agent ID
environment_id string Managed Agent の Environment ID

処理

  1. Managed Agents API で Session を作成
  2. 承認済みステップを日本語の実行指示としてフォーマットし、user.message で送信
  3. ポーリングループ(POLL_INTERVAL_SECONDS=3, MAX_POLL_ATTEMPTS=120
  4. session.retrieve でセッション状態を取得
  5. session.events.list でイベントを取得
  6. agent.mcp_tool_use イベント: evaluated_permission == "ask" の場合 user.tool_confirmation で自動承認(allow_once
  7. agent.custom_tool_use イベント: Backend 内の handle_custom_tool() で実行し、結果を user.custom_tool_result として返送(docs/custom-tools.md §3 参照)
  8. 進捗コールバック on_progress(tool_names, current_tool) はシグネチャのみ用意されており、MVP では未配線(Slack カードの逐次進捗更新は Post-MVP)
  9. セッション終了条件:
  10. idle: 正常完了
  11. error / failed: 異常終了
  12. MAX_POLL_ATTEMPTS 超過: タイムアウト

出力: Execution Result

{
  "type": "completed | error",
  "tool_names": ["list_employees", "list_attendance", "calculate_overtime"],
  "summary": "Agent からの最終メッセージ",
  "session_id": "session_xxx"
}

副作用

  • DB: executions レコード(pendingrunningcompleted | failed
  • DB: tasks.statuscompleted | failed
  • Slack: Execution カード(進捗更新 → 完了 or 失敗に chat.update

3. 状態遷移

3.1 Task 状態遷移

stateDiagram-v2
    [*] --> extracted
    extracted --> running : Process 承認
    extracted --> cancelled : 承認前にタスク取消
    running --> completed : L4 正常完了
    running --> failed : L4 異常終了
    running --> cancelled : ユーザー中止
    failed --> running : 再実行
    completed --> [*]
    failed --> [*]
    cancelled --> [*]
遷移元 遷移先 トリガー
extracted running Process 承認
extracted cancelled Prompt 却下 / Process 却下 / ユーザー中止
running completed L4 正常完了
running failed L4 異常終了
running cancelled ユーザー中止

3.2 Prompt 状態遷移

stateDiagram-v2
    [*] --> generating
    generating --> pending_approval : L2 生成完了
    pending_approval --> approved : ユーザー承認ボタン
    pending_approval --> rejected : ユーザー却下ボタン
    approved --> [*]
    rejected --> [*]
遷移元 遷移先 トリガー
generating pending_approval L2 生成完了
pending_approval approved ユーザー承認ボタン
pending_approval rejected ユーザー却下ボタン

3.3 Process 状態遷移

Prompt と同一パターン。

3.4 Execution 状態遷移

stateDiagram-v2
    [*] --> pending
    pending --> running : L4 セッション開始
    running --> completed : L4 正常完了
    running --> failed : L4 異常終了 / タイムアウト
    running --> cancelled : ユーザー中止
    completed --> [*]
    failed --> [*]
    cancelled --> [*]
遷移元 遷移先 トリガー
pending running L4 セッション開始
running completed L4 正常完了
running failed L4 異常終了 / タイムアウト
running cancelled ユーザー中止

4. 却下 → 再生成フロー

4.1 Prompt 却下再生成

  1. ユーザーが Prompt カードの [却下] ボタンを押下
  2. 理由入力モーダルを表示(views.open → テキスト入力)
  3. ユーザーが理由を入力して送信
  4. 新しい Prompt レコードを作成(version = 現行 + 1
  5. L2 を再実行(Task JSON + ツールカタログ + 却下理由)
  6. 新しい Prompt カードを投稿(既存カードは「再生成されました」に更新)

4.2 Process 却下再生成

  1. ユーザーが Process カードの [却下] ボタンを押下
  2. 理由入力モーダルを表示
  3. ユーザーが理由を入力して送信
  4. 新しい Process レコードを作成(version = 現行 + 1
  5. L3 を再実行(承認済み Prompt + ツールスキーマ + 却下理由)
  6. 新しい Process カードを投稿

4.3 再生成の制約

  • 再生成回数に上限は設けない(MVP)
  • 却下理由は LLM に渡されるが、DB にも保存する(rejection_reason カラム追加)
  • 却下された Prompt/Process レコードは rejected ステータスのまま保持(削除しない)

5. 実行中の中止機能

5.1 中止フロー

  1. Execution カードに [中止] ボタンを表示(status: running の間のみ)
  2. ユーザーが [中止] ボタンを押下
  3. Backend が Managed Agents の Session を終了(session.cancel or session.delete
  4. DB 更新:
  5. executions.statuscancelled
  6. tasks.statuscancelled
  7. Execution カードを「中止されました」に chat.update
  8. 中止後は再実行不可(新しいタスクとして依頼し直す)

5.2 中止の制約

  • Managed Agents API でセッション停止が可能であることが前提
  • ポーリングループ内で中止フラグをチェックし、次の poll 前に Session を終了
  • 中止リクエストから実際の停止までに最大 POLL_INTERVAL_SECONDS(3秒)のラグがある

6. エラーハンドリングと再実行

6.1 エラー分類

エラー種別 発生場所 対処
LLM API エラー L1-L3 Slack にエラー通知、ユーザーに再メンションを促す
LLM 出力パースエラー L1-L3 ValueError、Slack にエラー通知
Managed Agents セッションエラー L4 executions.statusfailed、再実行ボタン表示
MCP ツール実行エラー L4 Agent が自動リトライ or エラー報告
Slack API エラー 全体 リトライ(最大 3 回)、ログ出力
タイムアウト L4 MAX_POLL_ATTEMPTS 超過、failed + 再実行ボタン

6.2 再実行フロー

  1. Execution カードの failed 状態に [再実行] ボタンを表示
  2. ユーザーが [再実行] ボタンを押下
  3. 同じ承認済み Process で新しい Execution レコードを作成
  4. L4 を再実行
  5. 新しい Execution カードを投稿

7. Slack UI カード仕様

7.1 カード原則

  • 1 タスク = 最大 4 メッセージ(Task / Prompt / Process / Execution)
  • 各メッセージは chat.update で書き換え(スレッド肥大化防止)
  • rich_text ブロック不使用(後で section に置換できない制約)
  • Surface: message、使用ブロック: header / section / divider / context / actions
  • テキスト truncation: 3000 文字で切り詰め

7.2 Task カード (#1)

状態 ブロック構成 ボタン
generating Header: 「受け付けました」 / Section: 「タスクを分析中...」 なし
complete Header: タイトル / Section: 説明・優先度・タスク種別・タスクID なし

7.3 Prompt カード (#2)

状態 ブロック構成 ボタン
generating Header: 「実行方針」 / Section: 「実行方針を生成中...」 なし
pending_approval Header: 「実行方針」 / Section: Prompt 内容 [承認] [却下]
approved Header: 「実行方針(承認済み)」 / Section: Prompt 内容 / Context: 承認者・時刻 なし
rejected Header: 「実行方針(却下)」 / Section: Prompt 内容 / Context: 却下理由 なし
regenerated Header: 「実行方針(再生成済み)」 / Context: 「新しいバージョンが生成されました」 なし

7.4 Process カード (#3)

状態 ブロック構成 ボタン
generating Header: 「実行ステップ」 / Section: 「実行ステップを生成中...」 なし
pending_approval Header: 「実行ステップ」 / Section: ステップ一覧(ツール名 + 説明) [承認] [却下]
approved Header: 「実行ステップ(承認済み)」 / Section: ステップ一覧 / Context: 承認者・時刻 なし
rejected Header: 「実行ステップ(却下)」 / Context: 却下理由 なし
regenerated Header: 「実行ステップ(再生成済み)」 / Context: 「新しいバージョンが生成されました」 なし

7.5 Execution カード (#4)

状態 ブロック構成 ボタン
running Header: 「実行中」 / Section: ステップ進捗(✅ ⏳ ⬜) / Context: 進捗 N/M [中止]
completed Header: 「完了」 / Section: 全ステップ ✅ + サマリー / Context: 実行時間 なし
failed Header: 「エラー」 / Section: ステップ進捗 + ❌ + エラー内容 [再実行]
cancelled Header: 「中止」 / Section: ステップ進捗 / Context: 「ユーザーにより中止されました」 なし

8. Agent Container 仕様(Post-MVP)

MVP では Agent Container は未実装。下記は将来対応予定の仕様メモ。詳細な優先度は docs/post-mvp-roadmap.md を参照。

  • Slack の「Agents & AI Apps」機能を有効化し、Split Pane で起動できる 1:1 対話 UI
  • assistant_thread_started でサジェストプロンプト(勤怠集計 / 残業確認 / 従業員一覧)を提示
  • message.im で受けたメッセージを handle_mention と同じ L1-L4 パイプラインに流す
  • スレッド可視性は本人のみ、承認者は本人に限定される点がチャンネルメンションとの差分
  • 実装前提: im:history スコープ、App 設定で Agents & AI Apps を有効化
  • tasks.sourceagent_container 値を追加し、エントリーポイント識別子として記録する

9. Custom Tool 仕様

9.1 ツール一覧

# ツール名 実装 説明
1 list_employees 実 freee API 従業員一覧取得
2 list_attendance 実 freee API 勤怠データ取得(月指定)
3 calculate_overtime 実 freee API 残業時間計算
4 write_rows_to_google_sheet 実 Google Sheets API Sheet 書き込み
5 send_slack_dm 実 Slack API Slack DM 送信

9.2 共通入出力スキーマ

list_employees

{
  "name": "list_employees",
  "description": "従業員一覧を取得する",
  "parameters": {
    "type": "object",
    "properties": {
      "company_id": { "type": "string", "description": "freee 事業所 ID(省略時は接続されたテナントのデフォルト事業所)" },
      "department": { "type": "string", "description": "部署名でフィルタ(任意)" },
      "status": { "type": "string", "enum": ["active", "retired", "on_leave"], "description": "在籍ステータスでフィルタ(任意)" }
    }
  }
}

出力:

[
  {
    "id": "string",
    "name": "string",
    "department": "string",
    "email": "string",
    "status": "active | inactive"
  }
]

list_attendance

{
  "name": "list_attendance",
  "description": "従業員の勤怠データを取得する",
  "parameters": {
    "type": "object",
    "properties": {
      "company_id": { "type": "string", "description": "freee 事業所 ID" },
      "employee_id": { "type": "string", "description": "従業員 ID" },
      "month": { "type": "string", "description": "対象月 (YYYY-MM)" }
    },
    "required": ["employee_id", "month"]
  }
}

出力:

[
  {
    "employee_id": "string",
    "date": "YYYY-MM-DD",
    "clock_in": "HH:MM",
    "clock_out": "HH:MM",
    "break_minutes": 60,
    "work_minutes": 480,
    "overtime_minutes": 0
  }
]

calculate_overtime

{
  "name": "calculate_overtime",
  "description": "従業員の月間残業時間を計算する",
  "parameters": {
    "type": "object",
    "properties": {
      "company_id": { "type": "string", "description": "freee 事業所 ID" },
      "employee_id": { "type": "string", "description": "従業員 ID" },
      "month": { "type": "string", "description": "対象月 (YYYY-MM)" }
    },
    "required": ["employee_id", "month"]
  }
}

出力:

{
  "employee_id": "string",
  "month": "YYYY-MM",
  "total_work_minutes": 9600,
  "total_overtime_minutes": 120,
  "working_days": 20
}

write_rows_to_google_sheet

{
  "name": "write_rows_to_google_sheet",
  "description": "Google Sheets にデータ行を書き込む",
  "parameters": {
    "type": "object",
    "properties": {
      "spreadsheet_id": { "type": "string" },
      "range": { "type": "string", "description": "A1 表記 (例: Sheet1!A1)" },
      "rows": { "type": "array", "items": { "type": "array" } }
    },
    "required": ["spreadsheet_id", "range", "rows"]
  }
}

send_slack_dm

{
  "name": "send_slack_dm",
  "description": "Slack で DM を送信する",
  "parameters": {
    "type": "object",
    "properties": {
      "user_id": { "type": "string", "description": "Slack ユーザー ID" },
      "message": { "type": "string", "description": "メッセージ本文" }
    },
    "required": ["user_id", "message"]
  }
}

9.3 freee API 統合

認証

  • freee OAuth 2.0 フロー
  • Backend がトークンを保持(refresh token で自動更新)
  • 環境変数: FREEE_CLIENT_ID, FREEE_CLIENT_SECRET, FREEE_COMPANY_ID
  • アクセストークンは Backend プロセス内で管理、外部に渡さない

OAuth トークン取得方針 (MVP)

MVP では OAuth フローの Web UI は未実装。以下の手動手順でトークンを取得する:

  1. 手動スクリプト (scripts/freee-oauth.py) で freee OAuth 認可フローを実行
  2. 取得したアクセストークン・リフレッシュトークンを DB の integrations テーブルに保存
  3. 以降は Backend の FreeeTokenManager が自動リフレッシュを行う

OAuth 連携の Web UI は Web 管理画面の /integrations 画面 (Section 10.2 #4) で実装予定。

API マッピング

Custom Tool freee API エンドポイント
list_employees GET /hr/api/v1/employees
list_attendance GET /hr/api/v1/employees/{id}/work_records
calculate_overtime list_attendance の結果を集計(Backend 計算)

MVP では backend/src/integrations/freee_adapter.pyMOCK_MODE=true のときモックデータを返し、false のとき freee API を呼び出す。list_employeescompany_id は省略時に接続されたテナントのデフォルト事業所(adapter 側が管理)を使用する。

エラーハンドリング

  • 401: トークンリフレッシュ → リトライ
  • 429: レートリミット → Retry-After ヘッダに従いリトライ
  • 5xx: 最大 3 回リトライ(exponential backoff)
  • その他: エラー内容を Agent にテキストで返却

10. Web 管理画面仕様

10.1 技術スタック

項目 選定
フレームワーク Next.js 16 (App Router)
UI Tailwind CSS v4 + shadcn/ui
データ取得 Server Components + better-sqlite3 による SQLite 直接参照(Backend と同じ data/agent.db を読み書き)
認証 MVP: HTTP Basic 認証(環境変数 ADMIN_USER / ADMIN_PASSWORDweb/middleware.ts で強制)

10.2 画面一覧

# パス 画面名 概要
1 / パイプライン一覧 全タスクの一覧表示、ステータスフィルタ
2 /pipeline/[id] パイプライン詳細 Task → Prompt → Process → Execution の全フロー表示
3 /settings 設定 承認フロー ON/OFF、モデル選択、タイムアウト設定
4 /integrations 外部連携 freee/Google/Slack の接続状態表示・OAuth 連携管理

監査ログ画面 (/audit) は Post-MVP。Backend 側の audit_logs テーブルへの書き込みは実装済みだが、Web UI は未着手(docs/post-mvp-roadmap.md 参照)。

10.3 各画面の要件

パイプライン一覧 (/)

  • テーブル列: ステータスバッジ、タイトル、タスク種別、作成日時、実行時間
  • フィルタ: ステータス(all / extracted / running / completed / failed / cancelled)
  • ソート: 作成日時(降順がデフォルト)
  • ページネーション(20 件/ページ)

パイプライン詳細 (/pipeline/[id])

  • タイムライン表示: Task → Prompt (v1, v2...) → Process (v1, v2...) → Execution
  • 各ノードを展開すると詳細(Prompt テキスト、Process steps、Execution 結果)
  • 承認者・承認時刻・却下理由の表示
  • Execution の Agent イベントログ(ツール呼び出し・結果のタイムライン)

設定 (/settings)

設定項目 デフォルト 説明
prompt_approval_required boolean true Prompt 承認ゲートの有効/無効
process_approval_required boolean true Process 承認ゲートの有効/無効
model string claude-sonnet-4-6 使用する Claude モデル
l4_timeout_seconds integer 360 L4 実行タイムアウト
auto_approve_tools boolean true ツール実行の自動承認

外部連携 (/integrations)

  • freee: 接続状態(connected / disconnected)、OAuth 連携ボタン、最終同期日時
  • Google Sheets: サービスアカウント接続状態
  • Slack: Bot 接続状態、ワークスペース名

監査ログ (/audit) — Post-MVP

Backend では下記のイベントを audit_logs テーブルに書き込み済みだが、Web 画面は未実装。

  • テーブル列: タイムスタンプ、アクター(user/system/agent)、アクション、対象リソース、詳細
  • アクション種別: task.created, prompt.approved, prompt.rejected, process.approved, process.rejected, execution.started, execution.completed, execution.failed, execution.cancelled, settings.updated, integration.connected
  • フィルタ: 日付範囲、アクション種別、アクター

11. データモデル

11.1 テーブル定義

既存テーブル(tenants, tasks, prompts, processes, executions, slack_messages, tool_permissions)に加え、以下を追加。

audit_logs(新規)

カラム 説明
id TEXT (ULID) PK
tenant_id TEXT FK → Tenant
timestamp TIMESTAMP イベント発生日時
actor_type TEXT user / system / agent
actor_id TEXT Slack user ID or system
action TEXT task.created
resource_type TEXT task / prompt / process / execution / settings
resource_id TEXT 対象リソースの ID
details TEXT (JSON) 補足情報

settings(新規)

カラム 説明
id TEXT (ULID) PK
tenant_id TEXT FK → Tenant (UNIQUE)
config TEXT (JSON) 設定値の JSON
updated_at TIMESTAMP 最終更新日時
updated_by TEXT 更新者

integrations(新規)

カラム 説明
id TEXT (ULID) PK
tenant_id TEXT FK → Tenant
provider TEXT freee / google / slack
status TEXT connected / disconnected / error
credentials TEXT (JSON, encrypted) OAuth トークン等
metadata TEXT (JSON) プロバイダー固有情報
connected_at TIMESTAMP 接続日時
updated_at TIMESTAMP 最終更新日時

11.2 既存テーブルへの変更

prompts — カラム追加

カラム 説明
rejection_reason TEXT 却下理由(却下時のみ)
rejected_by TEXT 却下者(Slack user ID)

processes — カラム追加

カラム 説明
rejection_reason TEXT 却下理由
rejected_by TEXT 却下者

executions — カラム追加

カラム 説明
cancelled_by TEXT 中止者(Slack user ID)
cancelled_at TIMESTAMP 中止日時

executions — ステータス追加

ExecutionStatus enum に cancelled を追加。


12. 非機能要件

12.1 パフォーマンス

項目 目標値
L1 応答時間 5 秒以内
L2 応答時間 10 秒以内
L3 応答時間 10 秒以内
L4 実行時間 ステップ数依存(タイムアウト: 360 秒)
Slack カード更新 イベント検知後 2 秒以内
Web 管理画面初期表示 2 秒以内

12.2 セキュリティ

  • LLM 入力の <user_input> タグ隔離
  • 認証情報(freee OAuth トークン等)は Backend プロセス内で管理
  • Web 管理画面は Basic 認証(MVP)
  • HR 個人データの LLM API 送信は許容(Anthropic データ保持なしポリシーに依拠)
  • 監査ログで全操作を記録

12.3 可用性

  • MVP はシングルプロセス、自動復旧なし
  • SQLite の WAL モードで読み書き並行性を確保
  • 障害時は手動再起動

13. 受け入れ条件

13.1 Slack Bot + パイプライン

# 条件 検証方法
AC-01 Slack でメンション → Task カードが投稿される Slack で実行
AC-02 Task カードに正しいタイトル・説明が表示される 目視確認
AC-03 Prompt カードが生成中 → 承認待ちに遷移する Slack で実行
AC-04 Prompt [承認] → Process カードが表示される Slack で実行
AC-05 Prompt [却下] → 理由入力モーダルが開く Slack で実行
AC-06 却下理由入力 → 新しい Prompt が再生成される Slack で実行
AC-07 Process [承認] → Execution カードが表示され、実行が始まる Slack で実行
AC-08 Process [却下] → 理由入力モーダルが開く Slack で実行
AC-09 却下理由入力 → 新しい Process が再生成される Slack で実行
AC-10 Execution カードが進捗更新される(✅ ⏳ ⬜) Slack で実行
AC-11 L4 正常完了 → Execution カードが完了表示になる Slack で実行
AC-12 L4 異常終了 → Execution カードに [再実行] ボタンが表示される エラー注入
AC-13 [再実行] → 新しい Execution が開始される Slack で実行
AC-14 実行中に [中止] → Execution がキャンセルされる Slack で実行
AC-15 全カードが chat.update で書き換わり、スレッドにメッセージが増えない Slack で確認

13.2 freee API 統合

# 条件 検証方法
AC-20 freee OAuth 認証フローが完了し、アクセストークンが取得できる Web 管理画面から実行
AC-21 list_employees が freee API から従業員一覧を取得する E2E テスト
AC-22 list_attendance が freee API から勤怠データを取得する E2E テスト
AC-23 calculate_overtime が正しい残業時間を計算する ユニットテスト + E2E
AC-24 トークン期限切れ時にリフレッシュが自動実行される 期限切れトークンで検証
AC-25 freee API エラー時にわかりやすいエラーメッセージが返る エラー注入

13.3 Web 管理画面

# 条件 検証方法
AC-30 ダッシュボードに KPI が正しく表示される ブラウザで確認
AC-31 パイプライン一覧でステータスフィルタが機能する ブラウザで確認
AC-32 パイプライン詳細で Task → Execution の全フローが表示される ブラウザで確認
AC-33 設定画面で承認フローの ON/OFF が切り替えられる ブラウザで確認
AC-34 外部連携画面で freee の接続状態が表示される ブラウザで確認
AC-35 監査ログが時系列で表示され、フィルタが機能する(Post-MVP) ブラウザで確認
AC-36 Basic 認証なしではアクセスできない curl で確認

AC-35 と下記 AC-50〜AC-55 は Post-MVP スコープ。docs/post-mvp-roadmap.md を参照。

13.4 Agent Container(Post-MVP)

# 条件 検証方法
AC-50 サイドバーの App リストに HR AI Agent が表示される Slack で確認
AC-51 Agent Container を開くとサジェストプロンプトが表示される Slack で確認
AC-52 サジェストプロンプト選択 → パイプラインが開始される Slack で実行
AC-53 自由入力メッセージ → パイプラインが開始される Slack で実行
AC-54 Agent Container 内で承認・却下・再生成が動作する Slack で実行
AC-55 Agent Container 内で Execution の進捗更新・完了が表示される Slack で実行

13.5 全体

# 条件 検証方法
AC-40 Slack メンション → freee API → Sheet 出力 → 完了通知の E2E シナリオが完走する E2E テスト
AC-41 PM が社内デモとして関係者に見せられる品質である PM レビュー
AC-42 管理画面でデモ実行の結果が閲覧できる ブラウザで確認

14. 技術スタック

領域 技術 バージョン
言語 (Backend) Python 3.12+
言語 (Frontend) TypeScript 5.x
Slack 連携 slack-bolt latest
LLM (L1-L3) anthropic SDK latest
LLM (L4) Managed Agents API beta
DB (Backend) SQLite + aiosqlite -
DB (Web) SQLite + better-sqlite3 -
Web フレームワーク Next.js (App Router) 16+
UI Tailwind CSS v4 + shadcn/ui -
パッケージ管理 (Python) uv latest
パッケージ管理 (Node) pnpm latest
freee API REST (/hr/api/v1) v1
Google Sheets google-api-python-client latest
MCP Server FastMCP latest
トンネル (開発) ngrok -

15. 旧仕様との差分

本書は docs/mvp-requirements.md(v1.0 / 2026-04-15)を置き換える。主な差分:

項目 旧仕様 (v1.0) 本書 (v2.0)
HR ツール モック 3 個 実 freee API 3 個
却下フロー タスクキャンセル(再生成なし) 理由入力 → 再生成
実行中止 スコープ外 中止ボタン + Session 停止
再実行 スコープ外 失敗時の再実行ボタン
Web 管理画面 読み取り専用 1 ページ 6 画面(Pipeline/Settings/Integrations/Audit)
認証 なし Basic 認証
監査ログ なし 全操作記録
エントリーポイント チャンネルメンションのみ チャンネル + Agent Container

変更履歴

日付 バージョン 変更内容
2026-04-15 v1.0 初版(docs/mvp-requirements.md
2026-04-18 v2.0 全面改訂。実 freee API・却下再生成・中止・管理画面を MVP スコープに追加
2026-04-18 v2.1 Agent Container(Split Pane)を追加エントリーポイントとして追加
2026-04-19 v2.2 freee OAuth 手動スクリプト方針を追記 (issue #11)
2026-04-20 v2.3 実装との整合性を取るための更新。Agent Container・/audit UI・L4 進捗コールバックを Post-MVP に移動、freee API パスを /hr/api/v1 に修正、list_employees の company_id を string 化しデフォルト事業所対応、Web の認証・DB ドライバ(better-sqlite3)と Next.js 16 を明記、combined MCP Server 方針を反映