# データ契約の版管理・移行原則（横断契約）

- 日付: 2026-07-17
- 状態: draft（レビュー後、全データ契約に効く横断 SSOT とする）
- 前提: `notes-2026-07-13-edit-json-v1.md`（原則「`version` フィールドで段階進化。
  v0 の後方互換を壊さない」）/ `contract-2026-07-14-edit-json-v1-audio.md` §0
  （version 運用の実例 — 本書はこの運用を全契約へ一般化する）
- スコープ: プロジェクト内の全データ契約ファイルと `packages/schemas/` の JSON Schema。
  既存契約の内容（スキーマそのもの）は変えない。変えるのは「進化のさせ方」の規律のみ

## 1. 適用対象

- edit.json / 素材サイドカー（`.meta.json`・`.decisions.json`・`.analysis.json`）/
  `.akari/` 配下の状態ファイル（`workflow.json` ほか今後の新設を含む）/
  スキルが読み書きするプロジェクト内 JSON 全般
- 今後新設されるデータ契約ファイルは**初版から適用する**（`version` 無しで新設しない）

## 2. 三原則

### 原則 1 — 版必須・追加のみ進化（マイグレを書かずに済む進化が第一）

- 全データ契約ファイルはトップレベルに `version`（整数）を持つ
- 進化は**任意フィールドの追加のみ**。既存フィールドの削除・型変更・意味変更は禁止
- それが本当に必要になった時だけ `version` を bump する（= 破壊的変更の明示宣言）
- 読み手は tolerant reader — 未知フィールドは**保持する**（読み → 書きの往復で
  落とさない）、欠損フィールドは既定値で補う
- 型となる実例: edit.json 音声契約 §0（`audio` は Option 追加・`version: 0` 据え置き・
  整数 bump は構造的破壊変更のために温存）

### 原則 2 — 破壊的変更は明示マイグレのみ

- `version` を bump する契約は、**旧版 → 新版の変換手順（機械実行可能な形）を
  契約文書に同時に書く**。変換手順の無い bump は受け入れない
- 変換の実行主体はエージェント（スキル）。対象ファイルと変わる内容を提示 →
  **明示承認** → 変換。結果は git diff で全部見える。git 未管理プロジェクトでは
  変換前に `.akari/backup/` へ退避する
- **silent migration 禁止**: アプリ・スキルが読み込み時に黙って新形式へ変換して
  保存する経路を作らない

### 原則 3 — 新しすぎる版は「壊さず・正直に止まる」

- 読み手が自分の知る最新より大きい `version` を見たら、推測・変換をせず
  **読み取り専用に倒し**、「このファイルは新しい形式です。スキル / アプリを
  更新してください」と正直に報告する
- 実例: edit.json の validate が `version != 0` を拒否する現行挙動はこの原則の実装。
  拒否メッセージは「更新の案内」として出す（無言のエラーにしない）

## 3. 起草時点の棚卸し（適用ギャップ）

| ファイル / スキーマ | `version` | 対応 |
| --- | --- | --- |
| edit.json | あり（運用明文化済み） | — |
| `.akari/workflow.json` | あり（`1`） | — |
| `.analysis.json`（`analysis.schema.json`） | あり | — |
| `.meta.json`（`asset-meta.schema.json`） | **あり**（2026-07-30 追加。初版 1） | 完了。任意フィールドとして追加し、bump 基準と機械検査は素材ライブラリ契約「素材の版と互換性」に定義 |
| `.decisions.json` | 未整備 | 次のスキーマ改訂時に追加 |

ギャップの解消は各契約側のタスクとして扱う。本書が固定するのは原則のみ。

## 4. 新設時チェックリスト

1. トップレベル `version`（整数）を持つ。初版の整数値（0 起点 / 1 起点）は
   契約側で定めて明記する
2. 「追加のみ進化・tolerant reader」を契約文書に明記する
3. 破壊的変更時の変換手順を書く節を契約文書に確保する（bump するまで空でよい）
4. 読み手の forward-compat 挙動（原則 3）を実装する

## 5. 契約ファイル名の `-vN` と edit.json スキーマ版の語彙衝突（2026-08-18 追記）

契約ファイル名の `-vN` サフィックス（例: `contract-2026-08-12-still-image-cut-source-v0.md`）は
**その契約文書自身のリビジョン**であり、本書が定めるデータ契約の `version` フィールド
（edit.json 等のスキーマ版）とは無関係である。両者は独立に増減する — 契約文書が改訂されても
edit.json の `version` は変わらないし、edit.json が `version: 1` に上がっても関連契約が
`-v1.md` へリネームされるわけではない。

「still-image-cut-source-v0（契約の第 1 版）を読んで edit.json は v1（スキーマ版）で書く」の
ような読み替えは誤読を招く。edit.json のスキーマ版に言及する契約文書は、本文冒頭で
**「edit v0」「edit v1」の表記**を使い分け、ファイル名の `-vN` と区別できるようにする（例:
「本契約は edit v1 の `sources[]` を対象とする」）。読み手（エージェント・人間）も、契約
ファイル名の `-vN` を見て自動的にスキーマ版だと解釈しない。

## 6. edit.json v0/v1 凍結変換器の終了方針（2026-08-18 オーナー裁定）

- 変換器は機能追加禁止・バグ修正のみとする。未知の v0/v1 ケースに対応を
  追加せず、「このプロジェクトは変換できません」と理由付きで止まる。
- AKARI Video 本体から変換器を外す期限は、製品版 `1.0.0` の公開日または
  `2026-12-31` のいずれか早い方とする。
- 期限到達時は変換器を破棄せず、単体 npm パッケージ `akari-migrate` へ切り出して
  1 回だけ publish し、以後更新しない。publish 自体は本移行タスクでは行わず、
  本体から外す作業の一部とする。
- 本体から外した後のエラー文言は次で固定する。

  > このプロジェクトは古い形式です。`npx akari-migrate@<版> <dir>` で変換してから開いてください。

### 6.1 音声トラック化（2026-08-21・凍結前の最後の追加）

task `2026-08-20-v2-audio-tracks` に限り、「機能追加禁止・バグ修正のみ」の明示承認済み・1 回限りの例外として、v0/v1 の `audio.sfx[]`・`audio.narration[]`・`audio.bgm` を v2 の audio lane `tracks[].items[]` へ移す変換を追加した。出力側の `at` / `duration` は整数フレームへ確定し、素材側の `in` / `out` と fade / `bgm.in` は秒のまま保持する。実尺が旧形式だけでは決まらない音声は `duration: 0` センチネルとし、この変換器では ffprobe しない。トップレベル `audio` は `master` が宣言されている場合だけ残す。

これは凍結前に許可された最後の機能追加である。今後この変換器へさらに変換能力を足さず、§6 の期限どおり本体から分離・削除する。

### 6.2 filter レイヤー転写と emphasis_words 移送（2026-08-23・1 回限りの例外）

task `2026-08-23-migrate-filter-emphasis-exception` に限り、2026-08-23 オーナー裁定による「機能追加禁止・バグ修正のみ」の明示承認済み・1 回限りの例外として、v0/v1 の独立した `kind: "filter"` レイヤーを v2 の filter source へ転写し、トップレベル `emphasis_words[]` を edit.json v2 から除外して object ルートの `captions.json.emphasis_words[]` へ移送する変換を追加した。media 系レイヤー（`video` / `baked`）に直付けされた `filter` は v2 に等価表現が無いため転写対象外とし、理由付きで変換を停止する。移送時は edit.json と captions.json の原文をそれぞれ退避し、1 手の revert で両方を復元する。移送先が無い、配列ルートである、または既に `emphasis_words` を持つ場合は理由付きで停止する。

2026-08-21 の廃止裁定は fieldtest 60 本を母集団とし、本番リールでの使用が調査圏外だったという母集団瑕疵があったため、本例外で既存データを損失なく移す。

これ以後この変換器へさらに変換能力を足さず、§6 の期限どおり本体から分離・削除する。
