source-extractlisted
Install: claude install-skill ozzy-labs/opshub
# source-extract — 1 つの source から候補を抽出する (HITL)
opshub MCP の `source.get`(read tool、Step 1 widening で追加された PR #231)で対象 source の本文を取得し、`propose.generate`(`mode=source_extract`、Phase 12 H4 で追加された dispatch key、ADR-0016 改訂 §決定 (l)(b))で task / decision / reply_draft 候補を生成、ユーザーが個別承認したものだけ `propose.apply`(Phase 12 H1 で MCP に露出、`WriteCategory.PROPOSE_APPLY`、`read_only=false` + `idempotent=true`)で durable state に書き戻す。
`inbox-triage` と pair。inbox-triage が「集合 (inbox 全体)」を扱うのに対し、本 skill は「個別 (source 1 件)」を扱う。
## 何が起きるか
1. ユーザーが「この資料から task 抽出」「これに含まれる決定教えて」「<source_id> から候補を」と頼む
2. ホストが本 skill を発火
3. ホストが `source.get` で対象 source 本文を取得(Phase 11 で Outlook body deep retention / Office 文書本文抽出に対応)
4. ホストが `propose.generate`(`mode=source_extract`、`topic` = source 概要)を呼び、候補 (task / decision / reply_draft) を生成(`ProposalGenerated` event を durable log に書く)
5. ホストが候補をユーザーに整形して提示
6. ユーザーが個別承認した候補のみ `propose.apply` で保存(HITL、idempotent)
opshub 側で外部 SaaS に通知 / 投稿する経路は **存在しない**(ADR-0010 §禁止事項 7)。
## 呼び出し順
### Step 1: 対象 source を特定
ユーザー入力に `source_id` がある場合はそのまま使う。なければ `recall.search` / `search` で検索:
```text
tool: source.list
input:
source_type: "<word_document|teams_message|...>" # 任意
limit: 10
```
または:
```text
tool: search
input:
query: "<キーワード>"
limit: 10
```
`hits[]` から `source_id` を抜き出す。
### Step 2: source 本文を取得
```text
tool: source.get
input:
source_id: "<source ULID>"
```
戻り値の `body` / `summary` / `title` を host LLM が読み、抽出すべき候補のヒント(task 化できそうな action / 記録すべき decision 等)を