# 素材ライブラリ契約 v0

ライブラリの置き場は既定で作業場の `library/`。作業場が無いときは従来の `~/.akari/assets/` を使う。
`akari-assets list`（または `akari assets list`）の先頭行で実際の置き場を確認する。
以下の `<ライブラリの置き場>` はその表示先を指し、音源はその下の `audio/` に入る。

- 日付: 2026-07-13
- 状態: 設計確定
- 前提: 本体（エンジン）は合成だけ。素材とその知識は全部外側に置く

## 思想

- **Pool 等の外部基盤に依存しない。ゼロベースのファイルベース**。git リポジトリが正典
- **LLM Wiki の単純さ**: AI は INDEX.md を読む → カテゴリを深掘る → meta.json を読む、で
  完結。人間も同じ道を歩ける。検索エンジンは当面持たない
- 実証済みの型を踏襲する: shadcn レジストリ方式（コピーして手元で改変・JSON スキーマ）。
  先行のコンポーネント配布エコシステムが動画コンポーネントで同型を実証済み

## 入庫基準（最重要）

**「生成コストが高い、または生成不能なものだけ」を入れる。**

- 入れる: 3D モデル（スマホモックアップ等）、多要素の複雑モーション、デザイン完成度の
  高いテロップ/サムネ構図、音源、B ロール素材
- 入れない: 単純な字幕スタイル・素朴なアニメーション（自然言語で毎回生成できるものは
  ライブラリを肥やさない）
- ユーザーが保存するマイスタイルは別契約の `styles/` に置き、この入庫基準の対象外とする。
- 数は増やしすぎない。INDEX.md ナビが成立する規模を保つ

## 構造

```
assets/                     ← 当面はローカルディレクトリ。コミュニティ化で独立リポへ昇格
  INDEX.md                  ← 背骨。カテゴリごと 1 行説明
  scene3d/
    INDEX.md                ← 「smartphone-mockup — 手に持てる iPhone 風。製品紹介向け」
    smartphone-mockup/
      meta.json
      fragment.html         ← 実体（Three.js + glTF 参照、authoring 規約準拠）
      model.glb
      preview.png
  overlay/  （telop / board / mockup / motion を tags で区別）
  still/    （サムネ構図など）
  audio/    （bgm / sfx を tags で区別）
  broll/
  font/
```

> カテゴリ名は 2026-07-29 に主題軸（`3d` / `motion` / `telop` / `thumbnail`）から**配布物の形**へ
> 切り替えた。以下本文に残る旧名は歴史的記述であり、正となる語彙は §カテゴリ軸の再定義（本書末尾）。

- **階層はカテゴリ → 素材の 2 段で打ち止め**（Fab がカテゴリ縮退した教訓）。
  横断軸（雰囲気・シーン種別・アスペクト）は tags に逃がす
- 1 素材 = 1 ディレクトリ。実体 + meta.json + preview.png が最小 3 点セット

## meta.json スキーマ v0

```jsonc
{
  "id": "smartphone-mockup",
  "category": "scene3d",                  // ディレクトリと一致（単一。複数カテゴリ禁止）
  "title": "スマホ 3D モックアップ",
  "description": "手に持てる iPhone 風モックアップ。画面に任意動画/画像を差し込める",  // 検索用
  "when_to_use": "アプリ紹介・製品デモ・UI 解説のシーン",   // AI 検索の主シグナル
  "tags": ["product-demo", "tech", "16:9", "9:16"],
  "knobs": [                              // .mogrt Essential Graphics の型システムを踏襲
    { "cssVar": "--screen-src", "type": "media", "group": "content", "label": "画面に映す動画" },
    { "cssVar": "--rotate-y", "type": "slider", "min": -45, "max": 45, "unit": "deg", "group": "pose" },
    { "cssVar": "--body-color", "type": "color", "group": "style" }
  ],
  "ai_usage": "画面テクスチャと角度・色は自由に変えてよい。ベゼル形状のジオメトリは崩さない",  // 先行例の AI Usage 節を踏襲
  "requires": ["three.js", "gltf"],
  "provenance": { "origin": "案件 xxx / 2026-07-01", "generator": null },  // 生成物なら手とプロンプト
  "author": "akari",
  "license": { "spdx": "MIT", "scope": "commercial-ok", "attribution_required": false,
               "ai_training_allowed": true },   // Fab の NoAI タグに相当する予約（市場化で必ず問われる）
  "tier": "free"                           // free / pro。price は廃止予定の任意フィールド
}
```

- `license` / `author` / `tier` は素材メタデータに記録する。`tier` は必須（free / pro）。
- **`knobs.unit` は「値に付く CSS 単位」**（2026-07-29 明確化）。`px` / `s` のように実際に
  値へ付く単位だけを書き、**無単位の倍率・比率（短辺比など）では `unit` を省略する**。
  意味は `label` に書く（例「木枠の太さ（短辺比。0 で枠なし）」）。この規律により、
  ツールが `--var board-width=940` を `940px` へ、比率のツマミは数値のまま渡せる
  （HTML 素材のパラメータ展開）。ここを混ぜると `width: 940` という無効な CSS が生まれ、
  **絵は変わるが「効いた」のではなく「壊れた」**という誤検知が検査側にも起きる
- `knobs.type` の語彙: `text` / `color` / `slider` / `dropdown` / `checkbox` / `media`
  （.mogrt と同じ心的モデル。世界中のモーションデザイナーが既に知っている語彙）
- `.mogrt` フォーマット自体は**採用しない**（AE ランタイム前提の専有コンテナ。実行不能）。
  型システムだけ借りる。将来「.mogrt → 本パッケージ」変換スキルの余地は残る

## 使用規律

- **コピーして使う。リンクしない**: 採用 = プロジェクトの `overlays/` へ複製 + 変数上書き。
  edit.json の自己完結（ライブラリが消えても過去案件が再現できる）を守る
- 使用時に provenance をプロジェクト側に記録（どのライブラリのどの版から来たか）

## 検索の段階計画

1. **今**: INDEX.md + grep（LLM ネイティブ。これで足りる規模を保つ）
2. **増えたら**: `catalog.json` を自動生成（Generated Wiki 層。機械フィルタ用）
3. **コミュニティ化**: 静的サイト + JSON インデックス（shadcn レジストリ同型）。
   MCP は**検索窓口としてのみ**後付け（正典は常に git リポ。Descript の
   「Don't ship your API as an MCP」の教訓）

## 収穫フライホイール（素材化スキル）

案件で作った良い成果物を、メタデータ付きパッケージにしてライブラリへ収穫する
「素材化」スキルを用意する。使うほどライブラリが肥える。これがスタイル学習の前段。

- **導出可能な値は自動抽出する**（Fab が 3D ファイルから頂点数等を自動抽出するのと同型）:
  fragment 内の CSS 変数一覧 → knobs 候補、`<script>` 依存 → requires、サイズ等は
  スキルが解析して埋め、人間/エージェントには判断が要る欄（when_use / ai_usage）だけ書かせる
- 将来の単一ファイル配布は dotLottie 方式（ZIP + manifest、仕様公開）を手本に
  `.akari-asset` として検討（今はディレクトリのまま）

## コミュニティ（将来。今は作らない）

- 投稿 = PR（git がそのまま受け皿）。品質はレビューステータス可視化 + 採用実績の自然選別

## カタログと取得スキル（2026-07-14 追記）

### 素材の3層モデル

```
① assets/   ローカル・個人ライブラリ（本書の本文）。実体をコピーして使う
② catalog/  クラウド管理のカタログ。配布するのは「メタデータ + 取得先 URL」のみ。
             バイナリそのものはホストしない
③ setup / fetch スキル  catalog/ を読み、ユーザー自身に取得元から入手させて ① へ落とす
```

- `catalog/` は `assets/` と同じ meta.json v0 契約を使う。バイナリを持たない代わりに
  `source` ブロックと `remote: true` を持つ
- 取得の実行主体は常にユーザー（またはユーザーに代わって動くエージェント）。カタログ自身は
  素材を配布・保管しない

### catalog エントリのスキーマ

meta.json v0 の必須フィールド一式に加えて、以下を持つ:

```jsonc
{
  // ...meta.json v0 の必須フィールドはそのまま...
  "remote": true,
  "source": {
    "url": "https://example.com/asset/123",       // 取得先ページ、または直接ファイル URL
    "acquisition": "direct",                        // direct | login | purchase
    "license_at_source": "CC0 1.0",                  // 取得元が明示するライセンス表記（原文ベース）
    "attribution_required": false,                   // 取得元での帰属表示要否
    "preview_url": "https://example.com/asset/123/preview.jpg"  // 任意。外部ホストのプレビュー画像
  }
}
```

- `source.acquisition` の語彙: `direct`（そのまま DL 可能）/ `login`（会員登録が要る）/
  `purchase`（購入が要る）
- `remote: true` のエントリは実体ファイル（fragment.html / preview.png / バイナリ等）を
  一切持たない。`source` ブロックが実体の代わりに立つ
- スキーマは `schemas/asset-meta.schema.json` に後方互換で追加済み。`source` / `remote` は
  任意フィールドなので、既存の `assets/` 側 meta.json は無改修で有効なまま

### catalog/ の構造

`assets/` と同型（カテゴリ→エントリの2段 + INDEX.md 背骨）:

```
catalog/
  INDEX.md              ← 背骨。カテゴリごと1行説明
  3d/
    INDEX.md
    <id>/
      meta.json          ← 実体ファイルは持たない
  font/
    INDEX.md
    <id>/
      meta.json
  ...
```

- 階層は `assets/` と揃えてカテゴリ→エントリの2段で打ち止め（同じ心的モデルで辿れることを
  優先する）
- **font カテゴリを新設する**: 特定の書体は入庫基準（「生成コストが高い、または生成不能な
  ものだけ」）に厳密に適合する。自然言語生成では特定フォントのグリフそのものは再現できない
  ため、常に取得元からの入手が前提になる。フォントはバイナリを直接同梱せず、常に
  `remote: true` として扱う（再配布ライセンスは取得元次第のため）
- category enum は `3d` / `motion` / `telop` / `audio` / `broll` / `font` に拡張する
  （後方互換。既存カテゴリの意味は変えない）

### パッケージマネージャ同型

catalog は「取得先の索引」であって「配布そのもの」ではない。Homebrew の formula や npm の
`package.json` が実体を持たず取得手順だけを記述するのと同じ型を踏襲する。各自の環境に
「取らせる」ことで、バイナリの再配布・著作権の問題を構造的に回避する。

### CC0 ファースト方針

catalog に載せる素材は、取得元のライセンスが CC0 相当（帰属表示不要・商用利用可・改変可）の
ものを優先する。帰属表示が必要な素材も載せてよいが、その場合は必ず
`source.attribution_required: true` を立てる。

### attribution_required → 将来のクレジット自動挿入

`source.attribution_required` は現時点では表示用のフラグに留まるが、将来は書き出し時の
クレジット欄（エンドロール等）へ自動挿入する仕組みへ接続する設計余地として予約する。

### remote エントリでの preview の扱い

`remote: true` のエントリは実体もサムネイルも同梱しない。かわりに `source.preview_url`
（任意フィールド）に、取得元がホストするプレビュー画像の URL を記録できる。ビューワー /
エージェントはこの URL を参照専用で表示し、AKARI Video 側では画像を保持・再配布しない。
`preview_url` を欠くエントリは `source.url` のページ自体をプレビュー代わりに開く運用でよい。

## アセットのスコープ階層（2026-07-14 追記）

素材はディレクトリなので、設定ファイルの階層探索（プロジェクト → 上位 → ユーザーグローバル）と
同じスコープモデルが成立する。層ごとに生存範囲を分ける。

| 層 | 場所 | 生存範囲 |
|---|---|---|
| `local` | `<プロジェクト>/assets/` | そのプロジェクトのみ |
| `shared` | プロジェクトから上位へ辿った各ディレクトリの `.akari/assets/`（2026-07-25 第三裁定で確定） | そのディレクトリ配下の全プロジェクト（事業・組織単位。複数層可） |
| `user` | `<ライブラリの置き場>/`（2026-07-25 第三裁定で確定） | そのマシンの全プロジェクト |
| `builtin` | 本リポの `assets/` | 製品出荷デフォルト |
| `catalog` | 本リポの `catalog/`（remote） | 取得して任意の層へ入庫 |

- **検索順序**: `local` → `shared`（近い順）→ `user` → `builtin` → `catalog`。
  同一 id が複数層にあるときは**近い層が勝つ**（shadowing）
- 全層が**同じ構造**（`<category>/<id>/` + 層直下の `INDEX.md`）と同じ meta.json v0 を使う。
  `validate-asset.mjs` も層を問わず同じものを使う
- **「コピーして使う」原則は不変**: どの層から採用してもプロジェクトの `overlays/` へ複製する。
  スコープは検索範囲の話であり、層をまたぐ参照・symlink は作らない
- **harvest（素材化）は登録先の層を必ず人間に確認する**。判断の目安:
  プロジェクト固有の文言・素材が残る → `local` / 事業・チーム内で再利用 → `shared` /
  どのプロジェクトでも使う自分の定番 → `user`。`builtin` への昇格は PR 経路
  （コミュニティ化と同じ道）
- ~~ディレクトリ名 `.akari-video/` は初期案（要オーナー確認。`.akari` 等への変更余地あり）~~ →
  ~~2026-07-25 の同日再裁定で `.akari-video` のまま確定~~ →
  **2026-07-25 第三裁定で `.akari` に再確定**（末尾「ディレクトリ名の裁定」追記を参照）
- 編集後のフィードバックが入口になる: 「このテロップよかった、登録して」→ harvest スキルが
  発動し、スコープを聞いて入庫する。コーナーキャプションやサムネ構図
  （HTML 文字組テンプレ）も同様に登録できるよう、category に `thumbnail` を追加する

## ディレクトリ名の裁定（2026-07-25 追記・第三裁定で確定）

~~**確定裁定（2026-07-25 再裁定）: プロジェクト外の置き場所は `~/.akari-video/` をベースに
統一する。** 初期案保留（旧「`.akari-video/` は初期案」項）はこれで解消。~~

**履歴（2026-07-25 第三裁定）: 当時の user 素材は `~/.akari/` 直下だった。2026-09-21 から素材は作業場 `library/` に移行し、マシン状態のみ `~/.akari/` に残す。**
`~/.akari/` 直下には他ソフトウェアの既存物が併存する場合があるため、共存規約
（本節末尾を参照）を必ず守る。

同日中に裁定が三転した経緯（第一〜第三裁定の変遷と撤回理由）は、
オーナーのローカル環境の詳細を含むため非公開の内部記録で管理する（本リポには置かない方針）。

確定事項（2026-07-25 第三裁定で更新。カッコ内は第二裁定時点の値）:

- `user` 層: `<ライブラリの置き場>/`（第二裁定時点: `~/.akari-video/assets/`）
- `shared` 層: 上位ディレクトリの `.akari/assets/`（第二裁定時点: `.akari-video/assets/`）
- レシピ: `~/.akari/recipes/`（recipe v0 の現行表記のまま・変更不要。出所は
  `docs/contract-2026-07-25-recipe-v0.md` §2 に追記）
- ドロップフォルダ既定: `~/.akari/audio-drop/`（`~/.config/akari-video/audio-drop` から変更。
  XDG 系ツリーも基底へ寄せる裁定は維持し、向き先のみ第三裁定に追従）
- 以後のプロジェクト外置き場所（styles 等）もすべて `~/.akari/` 配下に置く

残作業（本タスク `2026-07-25-akari-home-base-alignment`〔第三裁定版〕で実施）:

1. recipe v0 のパス参照: 置換は行わない（現状 `~/.akari/recipes/` のまま = 第三裁定下では
   正しい）。`docs/contract-2026-07-25-recipe-v0.md` §2 に出所リンクを 1 行追記する
2. `register-drop-folder.mjs` の `dropDir` 既定値を `~/.akari/audio-drop/` へ
3. 射程外（現状維持）: `~/.config/akari-video/` の `credentials.env` / `voice-profiles`
   （認証情報の置き場は別論点。本裁定では動かさない）
4. 第二裁定時点の基底（`~/.akari-video/`）に残る既存実データの移設はオーナーが別途実施

## `~/.akari/` の共存規約（2026-07-25 第三裁定で新設）

`~/.akari/` 直下には他ソフトウェアの既存物が併存する場合がある。AKARI Video が
`~/.akari/` 直下で行ってよいのは**自分が所有する新規サブディレクトリ（`recipes/` `assets/`
`audio-drop/` 等）の作成と管理のみ**とする。

- **不可触**: `~/.akari/` 直下にある自分の所有物以外のファイル・ディレクトリには
  読み書きとも一切手を出さない
- **予約名の禁止**: home レベル（`~/.akari/` 直下）で `cache/` という名前は将来も
  使わない（他ソフトウェアの所有名と衝突するため）。AKARI Video 自身のキャッシュは
  プロジェクト内 `.akari/cache/` に置く（project-structure v0 契約を参照）
- **既存物の扱い**: 併存する既存物の整理・移設は AKARI Video 側の契約・タスクの射程外

## 素材の版と互換性（2026-07-30 導入）

`docs/contract-2026-07-17-data-contract-versioning.md` §3 の棚卸しで「`.meta.json` は `version`
無し → 任意フィールドとして追加」と残っていた宿題を果たす。任意フィールドを 2 つ足す。

```jsonc
"version": 1,               // 素材の版。整数。初版は 1
"min_app_version": "0.5.0"  // 任意。この素材が要求する AKARI Video の最低版
```

### なぜ必要か

**過去案件は壊れない**（「コピーして使う・リンクしない」原則により、採用時にプロジェクトへ
複製されるため）。版が要るのは次の 3 場面である。

1. **新しい版へ乗り換えるとき** — ツマミが改名・削除されていると `edit.json.overlays[].vars` の
   指定が**黙って効かなくなる**。エラーにならないのが最も危ない
2. **買った人へ更新を届けるとき** — 何が変わり、どの指定が壊れるかを伝える手段が要る
3. **道具と素材の相性** — 古い版のアプリ / CLI で新しい素材を開いたときに、推測せず
   正直に止まるため（versioning 契約 原則 3 と同型）。要求が無い素材では `min_app_version` を省略する

### bump の基準

| 破壊的（`version` を上げる） | 破壊的ではない |
|---|---|
| ツマミの削除・改名 | ツマミの追加 |
| `type` の変更 | `label` / `description` / `tags` の更新 |
| `unit` の変更・付け外し | `ai_usage` / `provenance` の更新 |
| `min` / `max` の範囲縮小 | 範囲の拡大 |
| `id` / `category` の変更 | プレビュー・デモの差し替え |
| クラス名・スロット構造の変更 | 見た目の微調整（既定値を変えない範囲） |

改名は「削除 + 追加」として現れる。**改名したら必ず bump し、`ai_usage` に旧名を書き残す**。

### 機械で bump 漏れを止める

工房側に `harness/knob-diff.mjs` を置く（内部リポ）。git の前版 `meta.json` と比較して破壊的
変更を列挙し、`version` が上がっていなければ exit 1 で止める。**人の記憶に頼らない**のが要点で、
実際に 2026-07-30 の `unit` 宣言 15 個の削除は、手作業では破壊的と気づかないまま通っていた
（このツールを後から同じ履歴に当てると 7 件を破壊的として検出する）。

将来 `edit-lint` 側へ、プロジェクトが採用した素材の版と現行版を突き合わせる検査を足す
（採用時の版をプロジェクトへ記録する仕組みが前提。本契約「使用規律」の provenance 記録を実装してから）。

## 同梱基準 — 何をリポに置き、何を取りに行かせるか（2026-07-29 オーナー裁定）

**原則: 取得はオンライン、使用はローカル。** レンダー時に外部から実体を引く経路は作らない。

- オンラインでやるのは**検索・プレビュー表示・購入/ライセンス検証・更新通知**まで
- 実体は取得時にローカル層（`local` / `shared` / `user`）へ固定し、**使用は常にローカル**
- 理由 3 点: (1) `edit.json` 自己完結の決定論が壊れる（素材が更新・削除されると過去案件を再現できない）
  (2) レンダー中に外部 GET を挟む経路を作らない (3) 第三者素材は再配布不可のものがあり、
  ユーザー自身の環境に取得させる構造（`remote: true`）が権利面の解でもある
- この原則により、将来マーケットプレイス化しても**本契約の構造は変わらない**。`catalog/` が
  外部化されるだけで、`meta.json` がそのまま API の形になる

### builtin（本リポ `assets/`）に同梱してよいもの

1. 素材ゼロでも製品が動くための最小シード
2. **環境差を吸収するために必要なもの** — 書体がこれに当たる。Mac / Windows でグリフを揃える
   土台であり、`packages/render-cut/src/captions.mjs` が焼き込みキャプションで `@font-face` 固定する。
   実測 32 MB あるが**同梱のまま維持する**（2026-07-29 裁定）
3. 目安: 1 素材 5 MB 以下 / builtin 合計 50 MB 程度まで。超えるものは `catalog/` へ

### `catalog/`（取得先索引）へ出すもの

重く、かつ環境差の吸収に不要なもの —— 3D モデル・HDRI・音源・B ロール。

- 実測（2026-07-29）: `assets/scene3d/` は 20 MB で、うち `studio-2k.hdr`（6.4 MB）が
  2 エントリに**同一内容で重複同梱**されている
- **外出しは `asset_dependencies`（素材間依存の宣言）の導入とセットで行う。** 現行の自己完結契約
  （validator が素材ディレクトリ外への参照を fail させる）のままバイナリだけ抜くと検証が壊れる。
  依存を宣言できるようになれば、共有 HDRI を 1 本にまとめたうえで取得スキルが依存を先に解決できる

### テンプレートのサンプル出力

`templates/<name>/sample-project/` の見本 mp4・ナレーション wav は**同梱を許容する**（2026-07-29 裁定。
実測 5 MB）。テンプレートは今後増える見込みだが、「複製してすぐ動く・完成形が見える」価値が
数 MB のコストを上回るという判断。ただし 1 テンプレあたりの見本は最小限に保つ。

## カテゴリ軸の再定義（2026-07-29）

`category` を**主題**（何を表すか）から**配布物の形**（どう配られ、どう消費されるか）へ切り替える。
主題は無限に増えて enum が追いつかないため（実際 `lut` が enum 外に生え、`assets/` 側は 4 カテゴリが
空のまま新カテゴリ要求が発生していた）、増えない軸へ移す。

| v1 category | 形の定義 | 判定 | 旧 category |
|---|---|---|---|
| `overlay` | 時間を持つ HTML 断片 | `fragment.html` を `overlays[]` から合成。断片ルートに時刻を置かず、素材本来の長さは `data-akari-natural-duration`（秒）に記録 | `telop` / `motion` |
| `still` | 時間を持たない静止画（画像 1 枚 + 任意でツマミ用の HTML シート） | **既定は直下の画像（`preview.png` 以外の 1 枚）を `sources[]` の media クリップとして置く**。`fragment.html` は色相などのツマミを使うとき・画像が 1 枚に決まらないときだけ（2026-10-12 改訂）。HTML シートは決定的スクショで画像に焼ける | `thumbnail` |
| `scene3d` | 3D モデル + 表示断片、またはベイクレシピ | `fragment.html` + glTF、または `scene.py` | `3d` |
| `audio` | 音声トラックに載るバイナリ | `edit.json` の `audio.bgm` / `sfx` が参照 | `audio`（変更なし） |
| `broll` | 映像トラックに載る実写バイナリ | `sources[]` が参照 | `broll`（変更なし） |
| `font` | 書体バイナリ | `@font-face` / 焼き込みが参照 | `font`（変更なし） |

- **主題は `tags` に逃がす**。`lower-third` / `board` / `chalkboard` / `frame` / `mockup` /
  `thumbnail` / `motion` / `bgm` / `sfx` などはすべて tags であり、カテゴリにしない
- **カテゴリを増やさない**のが本改訂の要点である。新しい主題（ホワイトボード、ノート風、付箋…）は
  既存カテゴリ + tags で表す。カテゴリ追加を提案するときは「既存 6 つのどの形にも当てはまらない
  配布・消費のされ方か」を先に示す
- `audio` を `media` に畳む案は見送った。`<ライブラリの置き場>/audio/`（user 層）に実データがあり、
  リポ外のユーザー資産の移設を伴うため。`audio` と `broll` は消費経路（音声トラック / 映像トラック）が
  異なるので、形の軸としても分けたままで筋が通る
- 移行時の実績: `assets/` 3 件・`catalog/` 3 件のディレクトリ移動と `category` 値の書き換え、
  検証は `validate-asset.mjs` を全エントリで再実行

## `presets/` — 本契約の対象外（2026-07-29 新設）

リポ直下の `presets/` は**素材ライブラリではない**。本契約（meta.json v0）の対象外であり、
`validate-asset.mjs` も走らせない。

| | `assets/` `catalog/`（本契約） | `presets/`（対象外） |
|---|---|---|
| 使い方 | 人 / AI が選び、プロジェクトへ**コピーする** | **名前で参照し続ける**（コピーしない） |
| 改変 | コピー先で自由に改変する | 改変しない。差し替えるか再生成する |
| 解決の主体 | 人 / AI（INDEX.md → meta.json を読む） | **コード**（解決パスが実装に埋まっている） |
| 記述形式 | `meta.json` v0 | 各表の形式（`template.json` / `.cube` + `index.jsonl`） |

現在の収録:

- ATF テロップの参照表と描画器は退役。HTML 素材版は Lab で取得する。既存の baked は再生互換を維持する。
- `presets/luts/` — 3D LUT 2 件（自前生成）。`packages/render-cut/src/plan.mjs` が
  `edit.json` の `output.look.lut`（区切り文字を含まない名前）から
  `presets/luts/<id>/<id>.cube` を解決する

### 移設の経緯

両者はもともと `catalog/` 配下にあったが、`catalog/` の契約（`remote: true` で**実体を持たない**
取得先索引）と実体が矛盾していた。テロップは `meta.json` を持たない別形式、LUT は実ファイルを
同梱したうえで本契約に合わない `meta.json` を持たされており、`validate-asset.mjs` が 1 件あたり
8 件の赤を出していた（`category: "lut"` が enum 外・`knobs` が文字列配列・`license.spdx` が null・
`remote: false` なのに `source` を持つ 等）。LUT 側の `meta.json` は移設に伴い
`presets/luts/index.jsonl` へ置き換えた。

### 新しい表を足すときの判定

**人が選んでコピーするか / コードが id で引くか**で置き場を決める。前者は `assets/` か `catalog/`、
後者は `presets/`。後者をここへ足すときは、解決するコードのパスと 1:1 で対応させ、その参照箇所を
表の INDEX.md に明記する。


## 手持ち素材の登録（2026-09-22）

`akari-assets add --plan / --apply` は利用者の生ファイルを置き場へ複製する。
出どころは meta.json の既存 tags に記録し、スキーマは増やさない。

| 機械用タグ | 意味 |
| --- | --- |
| `origin:own` / `origin:site` | ローカル取り込み / サイトからの取り込み |
| `site:<id>` | サイト識別子 |
| `folder:<名前>` | 取り込み元として渡されたフォルダ名 |
| `license:subscription` | サブスクリプション由来 |
| `pack:<id>` | 素材セット。置き場直下の packs.json は catalog/packs.json と同型 |

一覧ではこれらを `machineTags` に分け、表示・検索用の `tags` に残さない。
出どころはカタログ掲載（lab）、明示 origin タグ（site / own）、AKARI 配布元の source.url（lab）、
その他の source.url あり（site）、それ以外（own）の順で決める。
AKARI 配布元は URL を解析し、ホスト github.com かつパスの最初のセグメントが AkariLabs、
またはホスト akari.video とそのサブドメインで判定する。移行期間中は旧公式ホストとそのサブドメインも受け入れる。壊れた URL は site とする。
素材ディレクトリの `CREDIT.txt` はクレジット文面 1 行。文面がある場合は
`license.attribution_required: true`、source がある場合はその attribution_required も true にする。

取り込みの既定は `license.scope: "private-owned"`、`spdx: "LicenseRef-user-owned"`、
`ai_training_allowed: false`、`tier: "free"`。利用者の手持ち素材として保管するための値であり、
素材そのものの著作権帰属・商用可否・再配布権を認定するものではない。
サイト由来は source ブロックに配布ページと元の利用条件を残す。

ローカル取り込みは全カテゴリに preview.png を置く。音は ffmpeg の波形、映像は先頭フレームを使い、
ffmpeg 不在・失敗時は Node 組み込みの zlib で生成した決定的なプレースホルダ PNG にする。
PNG の画像は元画像を複製し、その他の画像・font・scene3d はプレースホルダを使う。
still は画像を相対参照する fragment.html、scene3d はモデルを参照する data-akari-3d-scene 宣言の
fragment.html を生成する。これらを含む素材全体が validate-asset の exit 0 を通った場合だけ登録し、
非 0 の場合は failures に記録して素材を残さない。title は元ファイル名から拡張子を除いたものにする。
