From folio
生成された SRS プレゼン pack (generated.html + contract.yaml) の ceiling 検証を回す唯一の正規 entry point。folio-architect Phase F と同型の main-session orchestrator (skill→subagent 一段=nesting 制約下で唯一配布可能な形) で、floor(verify-srs)→precheck→anchors→3 lens 並列 spawn (fidelity-srs ∥ persona-walk-srs ∥ completeness-critic-srs)→dedup→Pass2 finding-refuter→severity remap→LLM verdict 合成→ceiling-commit-check (機械の default-block gate)→3 バンド verdict card + 5-state (STALE / FLOOR-FAIL / CEILING-FAIL / READY / GREEN) を出し、--accept で人間が fail-closed に toppling する。findings は synth 鵜呑みせず各 lens 返り値を raw 一次監査する。user が明示的に起動する (disable-model-invocation)。
How this skill is triggered — by the user, by Claude, or both
Slash command
/folio:folio-verifyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **応答言語**: 本 SKILL の出力 (verdict card・状態・要約・user 向けメッセージ) は **user の使用言語** (default = global CLAUDE.md = 日本語) で行う。folio canonical 用語 (`floor` / `ceiling` / `contract` / `anchor manifest` / `data-slot-id` / `EARS` / `RTM` / `upheld` / `refuted` / `uncertain` / `PENDING` / `ESCALATE` / 5-state 名等) は英語のまま維持する。
応答言語: 本 SKILL の出力 (verdict card・状態・要約・user 向けメッセージ) は user の使用言語 (default = global CLAUDE.md = 日本語) で行う。folio canonical 用語 (
floor/ceiling/contract/anchor manifest/data-slot-id/EARS/RTM/upheld/refuted/uncertain/PENDING/ESCALATE/ 5-state 名等) は英語のまま維持する。
生成 SRS プレゼン HTML の完全性判定は floor (機械) + ceiling (意味) の二層で、GREEN ⟺ (floor 全通過) AND (ceiling 合格)。本 SKILL は ceiling 側を回す常設 orchestrator。floor が決定的に測れない「捏造 / 読みやすさ / 意味的完全性」を、独立コンテキストの LLM reviewer に判定させ、その構造化 verdict を 数える / 束ねる だけで裁定へ渡す。
貫く原則 (最重要・全判断の根拠): 機械は自由文の「意味」を判定しない。各 reviewer が自分の構造化 verdict (JSON block) を emit し、skill はそれを 数える / 束ねる / enum remap する だけ。skill が prose を決定的パースして severity/verdict を抽出するのは folio-mzn が排除すべき当のアンチパターン → 禁止。列挙値の機械変換 (severity enum remap)・件数集計・順序担保は機械 OK (partial-enumeration trap の回避 = 自由文の意味検証を決定的プログラムで解くな)。
Pass1 の 3 lens と Pass2 の finding-refuter を 並列 spawn する側は main-session でなければならない (subagent は subagent を spawn できない = nesting 制約)。よって本 SKILL は folio-architect と同じく SKILL のまま置き、disable-model-invocation: true で Claude が検証を予期して自動起動する事故を防ぐ。起動は user が明示的に /folio-verify <generated.html> <contract.yaml> で行う。
本 SKILL は folio CLI を canonical bin path ~/.claude/plugins/folio/.claude-plugin/bin/folio で呼ぶ (consumer project でも folio self-host でも同じ bin に解決する canonical layout・folio-architect と同型)。見つからない場合は command -v folio を fallback とし、どちらも無ければ consumer に install を案内して abort (fail-closed)。以降、folio verify-srs / folio ceiling-precheck / folio ceiling-anchors / folio ceiling-commit-check はこの canonical path 経由で呼ぶ (bare folio や repo-relative path は consumer cwd で解決しないため禁止)。
<generated.html> — 判定対象の生成 SRS プレゼン HTML (generator が assemble + inject-prose で産出した派生成果物)。<contract.yaml> — 機械 SSoT (canonical)。ceiling の全 intent anchor はここに接地する。対応 pack (wired 集合) の SSoT は capability-registry.yaml であり、本文に literal 列挙しない (散文と registry のドリフト防止)。doc_type の判定と ceiling lens 集合 (expected_lenses) は registry から型別解決する (§0)。floor は folio verify --type <type>、ceiling-anchors は contract から doc_type を自動判定して型別 anchor 表を出す (contract_suffix → canonical doc-type 写像。arch suffix は canonical architecture へ alias)。
未 wire の残余: spec 系 3 instance (
folio-rules/folio-relations/folio-verification.spec.yaml) は registry key 粒度と ceiling pair 帰属が未解決の設計判断ゆえ後続 cell (folio-vhew) で扱う。wired != trueの type はfolio verify --typeが fail-closed で弾く。
各ステップを 順に 実行する。ceiling は floor の後にしか回さない (起動順序不変条件を機械 = precheck で担保)。
<contract.yaml> の doc_type を判定し、ceiling lens 集合 (expected_lenses) を capability-registry.yaml から解決する (literal 固定しない・型別 SSoT)。
REG=~/.claude/plugins/folio/.claude-plugin/design-system/generator/capability-registry.yaml
DOC_TYPE=<contract basename *.<type>.yaml の suffix (arch→architecture へ alias) か .meta.doc_id prefix から判定>
WIRED="$(yq -r ".doc_types.\"$DOC_TYPE\".wired" "$REG")" # true 以外は未対応 type として停止
mapfile -t EXPECTED_LENSES < <(yq -r ".doc_types.\"$DOC_TYPE\".ceiling[]" "$REG")
EXPECTED_LENSES = registry の .doc_types.<type>.ceiling = 型別 lens 集合。SRS のみ 3 lens (fidelity-srs / persona-walk-srs / completeness-critic-srs = gate J/I/K)、非 SRS 型は 2 lens (fidelity-<type> / persona-walk-<type> = gate J/I)。以降の Pass1 spawn (§3)・expected_lenses (§7)・commit-check (§8) は全てこの解決集合に従う (literal 固定せず registry を読む)。wired != true の type は本 SKILL の対象外 (folio verify --type が未配線として弾く)。現在の未配線残余 = spec 系 3 instance (後続 cell folio-vhew)。FLOOR="$(~/.claude/plugins/folio/.claude-plugin/bin/folio verify --type "$DOC_TYPE" <generated.html> <contract.yaml>)"; floor_rc=$?
folio verify --type <type> は doc_type 別 floor gate へ dispatch (SRS=taxonomy §5.2 gate A-H + visual-first / adr=ADR-pack floor 同型)。exit 0 = floor PASS (stdout に RESULT: floor PASS + CEILING=PENDING) / 1 = floor FAIL / 2 = tool error。捕捉した stdout をそのまま ceiling-precheck へ渡す:
printf '%s' "$FLOOR" | ~/.claude/plugins/folio/.claude-plugin/bin/folio ceiling-precheck; pc_rc=$?
pc_rc==1 (floor FAIL / floor PASS+PENDING を検出できず) → 状態 FLOOR-FAIL で停止 (ceiling へ進まない)。pc_rc==3 (SKIP masquerade = floor PASS を宣言したが gate SKIP あり = floor 不完全) → 状態 FLOOR-FAIL で停止 (honest-SKIP ≠ PENDING・renderer 在環境で floor を完成させてから再検証)。pc_rc==2 (tool error) → tool error として停止 (誤 GREEN に倒さない)。pc_rc==0 (真の CEILING=PENDING) → ceiling を続行。以降 floor:"PENDING" を commit-check 入力へ carry する。precheck は文字列痕跡の照合だけ (意味判定なし)。floor の advisory PENDING を 偽装 (honest-SKIP) から守る fail-closed gate であり、これを踏まないと「floor 不完全なのに ceiling GREEN」の masquerade が通る。
ANCHORS="$(~/.claude/plugins/folio/.claude-plugin/bin/folio ceiling-anchors <contract.yaml>)"; an_rc=$?
ceiling-anchors は contract の各 prose slot を SSoT source に対応づけた anchor manifest (JSON: {doc_type, contract, anchors:[{slot, ssot_path, ssot_value}]}) を stdout へ出す。exit 0 = 成功 / 2 = tool error (入力不在 / doc_type 非対応 / 構造不正)。exit 2 は tool error として停止する。
ceiling-anchors は doc_type を contract から自動判定し型別 anchor 表を出す (対応集合は registry と同期・各型の slot↔SSoT 対応は agents/fidelity-<type>.md §2 が canonical)。この manifest を completeness-critic-srs (Pass1・SRS のみ) と finding-refuter (Pass2) に必須入力として渡す (両者は location→contract の解決を manifest で行う)。fidelity-<type> は自前の slot↔SSoT 表 (fidelity-.md §2) で、persona-walk-<type> は北極星で直接 anchor するため manifest を要さない (contract + HTML を渡す・manifest を渡しても無害だが依存しない)。いずれの lens も 期待集合を生成 HTML の DOM から作らず contract(SSoT) から取る ことが要 — さもなくば「生成器が落とした要素は期待集合からも消える = 永遠に検出できない」verify-laundering になる。
§0 で解決した EXPECTED_LENSES の各 lens を 1 メッセージ内で並列 spawn する (全 Agent tool 呼び出しを同一 response にまとめる = 並列実行・folio-architect Phase F と同型)。lens 数は型別 (SRS=3 / 非 SRS=2)。下表は SRS の 3 lens を例に示す (非 SRS 型は folio:fidelity-<type> = gate J + folio:persona-walk-<type> = gate I の 2 lens。severity 語彙は同型で completeness-critic は不在):
| scoped name | gate | 軸 | severity 語彙 |
|---|---|---|---|
folio:fidelity-<type> | gate J | 捏造 / 脱落 / 誇張 / drift (prose ↔ contract) | critical / high / medium / low (canonical) |
folio:persona-walk-<type> | gate I | 非エンジニア読書体験 (何が要件か / なぜ / どう検証) | blocker / major / minor / polish (native) |
folio:completeness-critic-srs | 第 3 lens (SRS 専用) | 意味的完全性 (実質空 / 的外れ / 意味カバレッジ欠落) | critical / high / medium / low (canonical) |
各 lens へ {生成 HTML, contract.yaml} を渡す (+ completeness-critic-srs には anchor manifest も必須入力として渡す・§2。SRS のみ)。fidelity-<type> / persona-walk-<type> は manifest を要さない (§2)。全 lens は read-only (自ら Edit しない) ため並列で安全に走る。model は各 agent frontmatter の opus。
各 lens の返り値末尾の 機械可読 JSON block を読む ({"agent":..,"findings":[{"id","severity","axis","location"}],"summary":{..}})。prose の finding 記述ではなく JSON block を一次ソースにする (prose 決定的パースは禁止・貫く原則)。ただし synth を鵜呑みにせず、各 lens の raw 返り値 (JSON + prose evidence) を skill が直読して一次監査する。
ran_lenses の決定 (fail-closed): JSON block を正常に emit して 完走した lens だけを ran_lenses に入れる。lens が死ぬ / spawn 失敗 / JSON block を出さない → その lens を ran_lenses から除外する。すると commit-check が machinery≠clean (ran ⊉ expected) を検出して BLOCKED に倒れる = fail-closed。欠けた lens を skill が推測で補完してはならない。
expected_lenses の SSoT 注記: ceiling reviewer 集合は doc-type 別で
capability-registry.yamlの.doc_types.<type>.ceilingが SSoT (§0 で解決)。SRS=3 lens (fidelity-srs=gate J +persona-walk-srs=gate I +completeness-critic-srs=gate K・翼数 SSoT は taxonomy §5.3 +verify-srs.sh:24 で folio-mzn.1.4 に 2→3 翼 amend 済)、adr=2 lens (fidelity-adr=gate J +persona-walk-adr=gate I)。本 SKILL は literal 固定でなく registry から解決した型別集合を expected に配線する (機械判定 expected⊆ran を型別 expected で満たし・緩めない)。
lens 間で同一観察が別型で二重発火しうる (completeness の「off-target = 被覆ゼロ」と fidelity の「drift = 対象取り違え」は isolated reviewer には境界が曖昧・両方から valid に上がりうる)。commit-check は flat な findings を default-block 判定するだけで内容 dedup しないため、skill が commit-check へ渡す前に lens 横断で保守的に意味 dedup する (同一 location + 同一観察のみ・keep 寄り)。
★ dedup は safety-load-bearing でない (MUST 明記): この dedup は verdict-card の可読性のためであり、重複を残しても over-BLOCK になるだけで false-GREEN は不能 (重複 finding は commit-check をより厳しく block 方向にしか効かない)。よって迷ったら keep する。real finding を落としうる aggressive dedup を足してはならない — 「似ているから」で別 location / 別観察の finding を畳むと真の欠陥を消して false-GREEN を作る。dedup は同一 location + 同一観察の literal な重複だけに限る。
Pass1 findings のうち GREEN を反転しうる severity のみを抽出する (lens 別 severity 語彙で規定・下表)。GREEN を止めない下位 severity (fidelity/completeness の medium/low・persona-walk の minor/polish) は Pass2 から除外する (記録には留める)。
| Pass1 lens | GREEN を反転しうる = Pass2 対象 | GREEN を止めない = 非対象 |
|---|---|---|
fidelity-srs / completeness-critic-srs | critical / high | medium / low |
persona-walk-srs | blocker / major | minor / polish |
★ literal 文字列で絞るな:
critical/highという fidelity 側の文字列だけで literal に絞ると persona-walk のblocker/major(= ceiling 片翼 gate I の GREEN 反転) が 1 件も選ばれず素通りする (fail-open)。必ず上表の lens 別対応で選ぶ。blockerは gate I が二値で断ずる北極星 miss ゆえ fidelity の critical/high と同格で必ず Pass2 に載る。
抽出した各 finding に {finding, lens, axis, contract.yaml, 生成 HTML, anchor manifest} を付けて folio:finding-refuter を spawn する (1 finding = 1 spawn が基本形・同一 pack の複数 finding をまとめて渡してもよい)。refuter は finding の axis で判定 anchor を分岐する (agents/finding-refuter.md §4 axis 別 anchor):
fidelity-<type> / completeness-critic-srs 由来) → SSoT (contract) を intent anchor に SSoT↔HTML を突合。persona-walk-<type> 由来) → anchor は SSoT でなく北極星 (非エンジニアが頑張れば読めるか) で HTML を persona 読み直し。各 finding の出所 lens / axis を refuter へ渡し、正しい anchor を選ばせること (fidelity 軸を北極星で見ると SSoT 逸脱を見逃し、readability 軸を SSoT 突合で見ると gate I の北極星 miss を洗浄する)。refuter は verdict upheld / refuted / uncertain を返す (refute bias = 中立 evidence-based・裏付けが取れたときだけ refute・判断不能は uncertain として fail-closed)。verdict を finding にマージする。
★ verdict 欠落の扱い (commit-check が構造的に fail-closed 化・folio-6p0):
ceiling-commit-checkは「verdict==refuted / 明示 medium・low」以外を全て block する default-block ゆえ、GREEN 反転帯 (critical/high/blocker/major) の finding で refuter が verdict を返し損ねても (spawn 失敗等)、その finding は refuted でない → BLOCKED に倒れる (旧ceiling-adjudicateのselect(upheld|uncertain)黙殺穴を構造的に封鎖・silent drop しない)。帯未満 (medium/low) の finding は verdict に依らず非 block ゆえ既定 verdict を要さない。★literal な verdict 既定付与に頼らず、commit-check の default-block が「未検証 = refuted でない = block」を保証する。
commit-check は canonical severity {critical, high, medium, low} で block 帯 (critical/high = refuted 必須) / 非 block 帯 (medium/low) を判定する。persona-walk-<type> の native 語彙を canonical へ enum remap する:
blocker → critical major → high minor → medium polish → low
fidelity-<type> / completeness-critic-srs は既に canonical ゆえ remap 不要。★この map は commit-check の帯判定に load-bearing: blocker→critical / major→high で「北極星 miss」が GREEN 反転帯 (refuted 必須) に入り、minor→medium / polish→low で下位 severity が非 block 帯 (medium/low) に正しく入る (remap しないと minor/polish が非正準 severity 扱いになり commit-check が over-block する)。remap は列挙値の機械変換 = 機械 OK (severity を skill が推定/再判定するのではなく、agent が付けた native ラベルを 1:1 で対応づけるだけ・counting=機械 / labeling=LLM の境界を保存)。
commit-check 入力 schema を組む (下記 §8 ceiling-commit-check が読む schema):
{"expected_lenses":["<§0 で registry から解決した EXPECTED_LENSES を列挙>"],
"ran_lenses":["<実際に完走した lens>"],
"floor":"PENDING",
"findings":[{"id":"F1","agent":"<lens 名>","severity":"<canonical>","verdict":"upheld|refuted|uncertain"}]}
expected_lenses = §0 で capability-registry.yaml から解決した型別 lens 集合 (EXPECTED_LENSES・SRS=3 / 非 SRS=2)。literal 固定しない — commit-check の machinery-clean (expected⊆ran) を型別 expected で判定させる (機械判定は緩めない)。ran_lenses = 実際に spawn/完走した lens (§3 fail-closed)。floor = precheck が真 PENDING を確認したので "PENDING" (step 1)。findings = dedup 後・severity canonicalize 後・verdict マージ後の全 finding。refuted も含めてよい (commit-check は refuted を「clear 済」として非 block 扱いにする)。★境界 (最重要・folio-6p0): 機械は verdict を裁定しない。open-ended な LLM ラベル (severity/verdict) を決定的プログラムで裁定へ写像すると partial-enumeration trap に陥り false-GREEN を生む (旧 ceiling-adjudicate は uncertain-high・非正準 verdict・verdict 欠落 の 3 度 fail-open した)。よって裁定を 2 つに分離する:
(a) verdict 合成 = 本 SKILL (LLM orchestrator) の判断。全 lens の findings + refuter verdicts を raw で一次監査し、「どの finding が GREEN を止めるか (未 refute の critical/high/blocker/major)」「clearly-broken (FAIL 相当) か human-judgment 待ち (ESCALATE 相当) か」を意味で判断して verdict card の narrative を組む (§9)。この判断は決定的プログラムでなく LLM が行う (確信は ensemble + 敵対 refute から来る・thesis「別建ての決定的安全網を後付けしない」)。
(b) commit-check = 機械の単一 default-block 保証 (LLM 合成 (a) が緩んでも GREEN を通さない hard gate):
printf '%s' "$NORMALIZED" | ~/.claude/plugins/folio/.claude-plugin/bin/folio ceiling-commit-check; commit_rc=$?
stdout COMMIT=OK|BLOCKED + blocking finding 列挙。exit 0=OK / 1=BLOCKED / 2=tool error。COMMIT=OK の条件は「machinery-clean (expected⊆ran ∧ floor=PENDING) ∧ 全 GREEN 反転帯 finding が verdict==refuted」。refuted / 明示 medium・low 以外は全て block ゆえ、uncertain-high も 非正準 verdict も verdict 欠落も全て BLOCKED に倒れる (悪いケース列挙でなく良いケースの普遍要求 = 穴が原理的に開かない)。
★fail-closed (絶対):
commit_rc != 0(BLOCKED も tool error も) は一律「GREEN 不可」として扱う (機械故障を GREEN に倒さない)。LLM 合成 (a) は commit-check (b) を override できない —commit_rc != 0なら card がどう narrate しようと READY/GREEN にしてはならない。機械が守るのはこの 1 点 (default-block) のみで、verdict の意味的裁定は (a) の LLM が担う。
3 バンドで提示する: floor (verify-srs + precheck の結果) / ceiling (LLM 合成 narrative + commit-check の COMMIT=OK/BLOCKED + 各 lens findings 要約) / 人間 (--accept の要否と可否)。そのうえで 5-state のいずれかを確定する:
commit_rc != 0)。未 refute の GREEN 反転帯 finding が残る / machinery≠clean / tool error のいずれか。LLM 合成 (§8a) が「clearly-broken (FAIL 相当)」か「human-judgment 待ち (ESCALATE 相当)」かを narrate し、blocking finding と欠けた machinery を card に明示する (GREEN にはできない)。commit_rc == 0) かつ未 --accept。人間の toppling 待ち。--accept 済 (by user@time を記録)。★fail-closed の要 (旧 adjudicate exit-2 穴の封鎖): state は commit-check の exit code で決める。
commit_rc==0のみ READY、それ以外 (1=BLOCKED / 2=tool error) は全て CEILING-FAIL。「BLOCKED でも tool error でもない=READY」という default-READY 解釈をしてはならない (機械故障を GREEN に倒す fail-open)。ESCALATE/FAIL の区別は LLM narrative の UX であって、機械 gate は OK/BLOCKED の二値。
--accept は commit-check を再走し commit_rc == 0 (COMMIT=OK) のときだけ許可する (state=READY 相当):
printf '%s' "$NORMALIZED" | ~/.claude/plugins/folio/.claude-plugin/bin/folio ceiling-commit-check; commit_rc=$?
# commit_rc==0 のときだけ GREEN を許可。それ以外 (1=BLOCKED / 2=tool error) は一律拒否 (fail-closed・override 不可)。
拒否時は commit-check の blocking(...) 行 (どの finding が block したか) を示して GREEN にしない。成功時のみ verify-state を GREEN (承認済 by user@time) で書き込む。これが本 SKILL の fail-closed な肝 — 未 refute の GREEN 反転帯 finding (critical/high/blocker/major の upheld・uncertain・非正準・欠落 verdict) を人間が「まあいい」で GREEN に倒す事故を、機械の default-block コミット述語で構造的に防ぐ (LLM 判断でも人間判断でも override 不可)。
検証結果を .folio/verify-state/<pack>.json に記録する (runtime state ゆえ .folio/ = 既に .gitignore 済・inventory.json と同様に VCS 追跡しない)。記録項目:
{html, contract, html_hash, contract_hash, commit_status, findings_summary,
state, accepted_by, accepted_at}
staleness (STALE state) 判定は 現 hash vs 記録 hash の比較で行う (html/contract が検証後に変われば記録は無効化)。
ceiling は複数 round 回してよい (skeleton は最大 2 round)。各 round で Pass1 lens が上げた finding を seen-set で消し込み、新規 finding が出なくなったら停止する。1 round でも可だが、見落としを構造的に詰める loop-until-dry を intended pattern とする (seen-set の dedup 基準は「上げた finding 全体」であって「confirmed のみ」ではない = refuter に棄却された finding を毎 round 蒸し返して収束しない事故を避ける)。
name: folio-verify かつ disable-model-invocation: true であること。verify --type / ceiling-anchors / ceiling-precheck / ceiling-commit-check) と 型別 ceiling agent を参照していること: lens 集合を literal 固定せず capability-registry.yaml の .doc_types.<type>.ceiling から解決 (§0)。SRS=fidelity-srs/persona-walk-srs/completeness-critic-srs (3)・adr=fidelity-adr/persona-walk-adr (2) + Pass2 finding-refuter。disable-model-invocation: true。user が明示的に /folio-verify で起動する。capability-registry.yaml が SSoT (ceiling-anchors / lens 集合を registry から型別解決・本文に literal 列挙しない)。未配線残余 = spec 系 3 instance (後続 cell folio-vhew)。.claude-plugin/design-system/generator/{verify-srs,ceiling-precheck,ceiling-anchors,ceiling-commit-check}.sh (schema の SSoT・重複コピペせず file を読む).claude-plugin/bin/folio (subcommand: verify --type / ceiling-anchors / ceiling-precheck / ceiling-commit-check) + capability-registry.yaml (型別 floor_mode / ceiling lens 集合の SSoT)agents/{fidelity,persona-walk}-<type>.md (SRS は + completeness-critic-srs.md)。出力 JSON block・severity 語彙agents/finding-refuter.md (§1 GREEN 反転帯対応表 / §4 axis 別 anchor / §5 verdict JSON)skills/folio-architect/SKILL.md (disable-model-invocation・canonical bin path・Phase F 並列 spawn)design-intent/research/srs-component-taxonomy.html §5.1 (判定式 GREEN ⟺ floor AND ceiling) / §5.3 (gate I/J/K)npx claudepluginhub shuu5/folio --plugin folioGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Implements work from a spec or tickets using TDD at agreed seams, with regular typechecking and test runs, followed by code review.