Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 71 additions & 6 deletions docs/0-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,24 @@ GitHub Webhook イベントを受信・永続化し、MCP プロトコル経由
GitHub ──POST──> Cloudflare Tunnel ──> FastAPI :8080 ──persist──> events.json
^
|
MCP Server (stdio) ──read/write
^
|
AI Agent (Claude)
┌─────────────────────────────┴─────────────────────────────┐
| |
| trigger-events/<id>.json
| ^
| |
MCP Server (stdio) ──read/write direct trigger queue
^ |
| |
AI Agent (Codex / Claude) optional trigger command
```

二つのプロセスモードを持つ単一エントリポイント:
- `python main.py webhook` — HTTP 受信サーバー
- `python main.py mcp` — MCP ツールサーバー

Webhook モードは、イベント永続化に加えて optional な direct trigger queue を持つ。
trigger command が設定されている場合、保存済みイベントごとに直列実行される。

## Functional Requirements

### F1. Webhook 受信
Expand Down Expand Up @@ -71,6 +79,8 @@ GitHub ──POST──> Cloudflare Tunnel ──> FastAPI :8080 ──persist
| F3.2 | 各イベントは id, type, payload, received_at, processed フィールドを持つ |
| F3.3 | ファイルエンコーディングは UTF-8 で書き込む |
| F3.4 | レガシーエンコーディング(cp932, shift_jis, utf-8-sig)からの自動マイグレーションを行う |
| F3.5 | trigger 実行を行う場合、イベントに `trigger_status`, `trigger_error`, `last_triggered_at` を追記できる |
| F3.6 | trigger 実行用に `trigger-events/<event-id>.json` を保存できる |

**イベント構造:**

Expand All @@ -80,7 +90,10 @@ GitHub ──POST──> Cloudflare Tunnel ──> FastAPI :8080 ──persist
"type": "issues",
"payload": {},
"received_at": "ISO8601+timezone",
"processed": false
"processed": false,
"trigger_status": "succeeded|failed|skipped|null",
"trigger_error": "",
"last_triggered_at": "ISO8601+timezone|null"
}
```

Expand All @@ -102,6 +115,8 @@ GitHub ──POST──> Cloudflare Tunnel ──> FastAPI :8080 ──persist
"type": "issues",
"received_at": "ISO8601",
"processed": false,
"trigger_status": "succeeded|failed|skipped|null",
"last_triggered_at": "ISO8601|null",
"action": "opened",
"repo": "owner/repo",
"sender": "username",
Expand All @@ -111,7 +126,43 @@ GitHub ──POST──> Cloudflare Tunnel ──> FastAPI :8080 ──persist
}
```

### F5. 推奨ポーリングフロー
### F5. Direct Trigger Execution

| ID | 要件 |
|----|------|
| F5.1 | webhook モードは optional な trigger command を受け付ける |
| F5.2 | trigger command は保存対象イベントごとに 1 件ずつ直列実行する |
| F5.3 | trigger command にはイベント JSON 全体を stdin で渡す |
| F5.4 | trigger command には `GITHUB_WEBHOOK_*` 環境変数でイベント要約を渡す |
| F5.5 | trigger command 成功時はデフォルトでイベントを `processed=true` にする |
| F5.6 | `keep_pending_on_trigger_success` 指定時は成功しても pending のまま残す |
| F5.7 | trigger command 失敗時はイベントを pending のまま残し、`trigger_status=failed` を記録する |
| F5.8 | trigger command が notify-only fallback を選んだ場合は `trigger_status=skipped` を記録し、pending のまま残す |

**trigger command へ渡す環境変数:**

- `GITHUB_WEBHOOK_EVENT_ID`
- `GITHUB_WEBHOOK_EVENT_TYPE`
- `GITHUB_WEBHOOK_EVENT_ACTION`
- `GITHUB_WEBHOOK_EVENT_REPO`
- `GITHUB_WEBHOOK_EVENT_SENDER`
- `GITHUB_WEBHOOK_EVENT_NUMBER`
- `GITHUB_WEBHOOK_EVENT_TITLE`
- `GITHUB_WEBHOOK_EVENT_URL`
- `GITHUB_WEBHOOK_EVENT_PATH`
- `GITHUB_WEBHOOK_RECEIVED_AT`

### F6. Bundled Codex Wrapper

| ID | 要件 |
|----|------|
| F6.1 | `codex_reaction.py` を bundled helper として提供する |
| F6.2 | helper は `codex exec -C <workspace>` による direct execution を行える |
| F6.3 | helper は `codex exec resume <thread-or-session-id>` による resume mode を行える |
| F6.4 | helper は event JSON path を prompt に含め、workspace の `AGENTS.md` を読む前提で起動する |
| F6.5 | workspace に `.codex-webhook-notify-only` がある場合、helper は direct execution を行わず notify-only fallback を返す |

### F7. 推奨ポーリングフロー

| ステップ | 操作 |
|---------|------|
Expand All @@ -137,6 +188,9 @@ GitHub ──POST──> Cloudflare Tunnel ──> FastAPI :8080 ──persist
| N2.1 | ポート | `--port` / 環境変数 | 8080 |
| N2.2 | シークレット | `--secret` / `WEBHOOK_SECRET` | なし(検証スキップ) |
| N2.3 | イベントプロファイル | `--event-profile` / `WEBHOOK_EVENT_PROFILE` | all |
| N2.4 | trigger command | `--trigger-command` / `WEBHOOK_TRIGGER_COMMAND` | なし |
| N2.5 | trigger working directory | `--trigger-cwd` / `WEBHOOK_TRIGGER_CWD` | なし |
| N2.6 | success 時に pending を維持するか | `--keep-pending-on-trigger-success` | false |

優先順位: CLI 引数 > 環境変数 > デフォルト

Expand All @@ -147,6 +201,7 @@ GitHub ──POST──> Cloudflare Tunnel ──> FastAPI :8080 ──persist
| N3.1 | イベントはファイル全体をメモリにロードする(大量イベントには不向き) |
| N3.2 | イベント検索は線形探索(インデックスなし) |
| N3.3 | 単一プロセス想定(webhook と mcp は別プロセスで起動) |
| N3.4 | direct trigger は単一 worker による直列実行であり、同時実行はしない |

## Dependencies

Expand All @@ -163,3 +218,13 @@ GitHub ──POST──> Cloudflare Tunnel ──> FastAPI :8080 ──persist
|---------------|------|
| Cloudflare Tunnel | GitHub からのインバウンド HTTPS を localhost に転送 |
| GitHub Webhook | イベント送信元 |
| optional trigger command | 保存済みイベントごとの direct reaction |

## Files

| パス | 用途 |
|-----|------|
| `events.json` | 永続化された webhook イベント本体 |
| `trigger-events/<event-id>.json` | trigger command に渡す保存済みイベント JSON |
| `main.py` | webhook receiver / MCP server / direct trigger queue |
| `codex_reaction.py` | Codex direct execution / resume / notify-only fallback helper |
Loading