run-handout-extract · git:20260818.f27350e · 2026-08-18 · sha256 d49953539b0a1c04
run-handout-extract git:20260818.f27350eA
Immutable. This exact content is served forever at /api/v1/blob/d49953539b0a1c04.
---
name: run-handout-extract
prefix: run
kind: run
hierarchy: L1
description: 既存の単一 HTML から構成データを逆抽出したいとき、手書き HTML をテンプレート化したいときに使う。
output_language: ja
source: plugin-plans/guide-doc-generator/component-inventory.json#C02
allowed-tools: [Read, Write, Bash]
depends_on: [C11, C12, C16, C20]
combinators:
- with-goal-seek
- with-feedback-contract
goal_seek:
engine: inline
fork: subagent
max_loops: 5
responsibilities:
- id: R1-scan
prompt_required: true
summary: "対象 HTML を決定論抽出器にかけ、復元できた部品と復元不能な箇所を切り分ける"
- id: R2-complete
prompt_required: true
summary: "復元不能箇所の補完方針を判断し構成データを確定する"
- id: R3-roundtrip
prompt_required: true
summary: "確定した構成データを再レンダリングし、構成データ等価を判定して逆抽出レポートを返す"
responsibility_refs:
- prompts/R1-scan.md
- prompts/R2-complete.md
- prompts/R3-roundtrip.md
script_refs:
- ../../scripts/extract-handout-config.py
- ../../scripts/validate-handout-config.py
- ../../scripts/render-handout.py
- ../../scripts/verify-handout-selfcontained.py
feedback_contract:
criteria:
- id: IN1
loop_scope: inner
text: "逆抽出した構成データが validate-handout-config.py を通り、復元不能箇所が補完方針つきでレポートへ列挙される"
verify_by: script
- id: OUT1
loop_scope: outer
text: "復元した構成データを再レンダリングした HTML が元 HTML と構成データ等価であることを round-trip テストが確認する"
verify_by: test
---
# run-handout-extract
## Purpose & Output Contract
既存の単一 HTML を構成データへ戻し、別テーマの新規資料の出発点にできる状態を作る。
出力は 2 つだけである。
1. **構成データ JSON** — `--out` で指定したパスに 1 ファイル。書式は C12 の規約に従う。
2. **逆抽出レポート** — `--report` で指定したパスに 1 ファイル。次の 3 要素を必ず含む。
- 復元した部品一覧 (各部品の fidelity が exact か heuristic か)
- 復元不能箇所と採った補完 (キーパス / 理由 / 補完方針)
- round-trip 差分 (JSON Pointer / expected / actual)
資料内容の書き換え・改善提案はしない。資料の生成は C07 (`/handout-build`) の責務であり、
本 skill は構成データを出すところで止まる。
### ゴール (Goal)
既存の単一 HTML から構成データ JSON が復元され、その構成データを再レンダリングした HTML が
元 HTML と構成データ等価であることが round-trip テストで確認された状態。
### 目的・背景 (Why)
手書きで作られた過去の資料を資産化するには、HTML から構成データへ戻す経路が要る。
戻せて初めてテンプレートとして反復配布できる。
### 完了チェックリスト
- [ ] 既存 HTML の走査
- [ ] 構成データの復元
- [ ] 復元不能箇所の補完判断
- [ ] round-trip 等価の確認
## ゴールシーク実行
### ゴールシークループ
R1-scan → R2-complete → R3-roundtrip を 1 周とし、OUT1 が満たされるまで最大 5 周する。
**R1-scan.** `extract-handout-config.py --html <入力> --out <構成データ> --report <レポート>` を
Bash で起動する。HTML の走査と部品同定は C20 が唯一の実装であり、本 skill は
自前で HTML を parse しない。C20 の stderr に出る `W-EXTRACT-HEURISTIC` (クラス名推定で
復元した部品) と `E-EXTRACT-UNRECOVERABLE` (復元できなかったキーパス) を、
そのまま R2 の作業台として受け取る。
**R2-complete.** 復元不能箇所ごとに補完方針を 1 つ選び、レポートへ キーパス / 理由 / 補完方針 の
3 点セットで記録する。補完方針は 推測値の充填 / 空のまま残置 / 利用者への確認 のいずれかであり、
黙って欠落させることはしない。`lead_line` / `judgment_axis` / section goal / `reader` /
`prior_knowledge_level` / `essential_problem` / `doc_type` は、`data-hb-*` マーカーが無い限り推測しない
(C20 の never_guessed 規則)。推測しない箇所は null のまま残す。
推測で埋めた値と HTML から実際に読み取った値は、レポートの fidelity (exact / heuristic) で必ず区別する。
**R3-roundtrip.** 確定した構成データを `render-handout.py` で再レンダリングし、
`verify-handout-selfcontained.py` で自己完結性を確認したうえで、元 HTML との等価を判定する。
判定は正規化後の構成データ等価で行う。比較対象射影は provenance ブロックを除いた残りであり、
HTML のバイト一致は課さない (バイト一致が課されるのは同一構成データからの再生成だけである)。
不一致は `E-ROUNDTRIP-DIFF` として JSON Pointer と expected / actual を全件出し、
差分ありを等価と読める要約にしない。
### ゴールシーク配線
- inner ループ: R2 の確定結果を `validate-handout-config.py` にかける。FAIL のときは
欠落キーパスを提示し、検証を通すために値を捏造することはしない。穴の空いた構成データは
書き出したうえで「そのままでは生成に使えない」と明示し、空の構成データを成功として返さない。
- outer ループ: R3 の round-trip 判定。EQUIVALENT でなければ R1 の読み落としか R2 の補完誤りへ戻る。
### ゴールシーク検証
各周の終わりに IN1 と OUT1 の充足を判定し、未充足なら次周へ入る。5 周で未達なら
未達のまま結果を返す (通ったことにしない)。
## Criteria acceptance
- **IN1** (inner / script): `validate-handout-config.py` が exit 0 を返し、復元不能箇所が
補完方針つきでレポートへ列挙されていること。
- **OUT1** (outer / test): round-trip テストが構成データ等価を確認したこと。
## Gotchas
- 逆抽出結果を `/handout-build --config <出力パス>` へ渡すのは利用者の判断であり、
本 skill が生成まで進めることはない。
- `data-hb-generated="true"` の部分木 (nav / hero / sprite / footer / メモ UI) は
C20 が読み飛ばす。復元された構成データにこれらが parts として現れたら C11 側のバグである。