# NOIA_GRID 公開版と検証証拠

この仕様は記事の存在・改変・版の対応を検証するためのものです。著作者、初公開日、内容の正確性、再利用許諾を証明するものではありません。包括的なライセンスは未設定です。

## 保存と版番号

通常のサイト生成には `preview-<UUID>` を付けます。元データのsnapshot hashは出力版番号に流用しません。`seal` は新しい出力先にだけ確定版 `YYYY.MM.DD.N` を作成します。既に登録した番号と過去の番号は再使用できません。`canonical/release-evidence/` は保存対象の登録台帳です。消して番号を再使用してはいけません。

`data/manifest.json` は機械利用の入口、`data/evidence/release.json` は内容と履歴を固定する外側のmanifestです。前者の `source_release.release_manifest_sha256` は入力snapshotのhashであり、外側のmanifestのhashではありません。確定版の `generated_at` は `issued_at` に固定されます。UIだけを変更しても記事内容のhashは変わりません。

確定版の公開データは再生成で上書きしません。同じ配布byte列は保存版から取り出します。本文・metadata・Schema・公開用画像が変われば新しい配布版を確定してください。レコードには新しい版番号が入るため、公開版更新時のJSONL全行の変化は仕様です。内容自体の変化は `integrity.content_sha256` で区別できます。

## ハッシュ対象

`noia-evidence-json-v1` はUTF-8、キーをUnicode code point順に整列、空白なしのJSON、末尾LF一つです。Unicode正規化はしません。NaN・Infinity・重複キーは禁止です。これはRFC 8785/JCSではありません。数値の異なるシリアライズによる誤認を避けるため、同梱のPython検証実装と確定した配布byte列を保存してください。別方式へ変更するときは新しいprofileを導入します。

- `content_sha256`: タイトル、Markdown、順序付きBlock/Section、原式、表、発言者、表示補正、図の配置/文脈、表紙、editorial、audio/omitted_media。表示用画像URLを原画像SHA-256への参照へ置き換えます。Topic分類、配布先URL、公開版番号、書誌日時は含みません。画像byteの一致は別途manifestで確認します。
- `revision_sha256`: 公開された内容hash、Work/Edition/Revision ID、書誌日時、原典URL、rights、legacy metadata、Canonical package hash、lineageと前版の公開revision hash。Canonical packageそのもののhashとは別です。同じCanonical Revisionでも公開metadata訂正によりこのhashが変わり得ます。
- `previous_revision_sha256`: 同一EditionのCanonical親版が直前の公開版に存在する場合、その公開revision hash。それ以外はnullで `not_in_previous_release`、親がなければ `no_parent`。別Editionからの展開は `lineage.relation=derived_from` であり、訂正履歴へ混ぜません。非公開親版の本文・題名は出力しません。
- `record_sha256`: 実際のJSONL 1行、末尾改行を除くSHA-256。自分自身の中に含めず、記事hash一覧と既存byte locatorに置きます。
- Research Code: 同梱のcards.jsonにある各定義全体を上記profileでhash化。既存のdefinition hashと用途を混同しません。
- `release.json`: 配布data・公開media・記事/Research hash台帳・仕様/検証コード・過去manifestの実byte列を固定。HTML/CSS等の画面は対象外。原画像のhashは保持しますが、原画像byteそのものは公開版に含まれません。

## 独立した検証

サイト全体、またはmanifestが列挙した全ファイルを相対配置を維持して保存します。記事や画像を別の名前へ変更しないでください。

```powershell
python data/evidence/verify_release.py .
python data/evidence/verify_release.py . --expected-sha256 TRUSTED_MANIFEST_SHA256
```

1行目は自己整合性を検査します。2行目は別の信頼できる経路で得たhashと照合します。manifestと検証プログラムを同じ不明なサイトから得るだけでは、そのサイトの本人性を確認できません。検証コードを既知の実装と比較してください。外部証明と署名は別途検証します。

証拠ZIPは小さなmanifest・hash一覧・検証コード・公開鍵・証明ファイルだけです。記事全文/画像は含みません。ZIPだけを残して元の配布データを廃棄しないでください。ローカルではCanonical、masters、公開版の全byte列、登録台帳、コードを別媒体にも保存します。

## 確定・外部証明・署名

OpenTimestampsは追加機能です。通常の保存・公開版検証はPython標準ライブラリだけで動きます。追加環境は `python -m venv .tools/ots`、そのPythonで `pip install -r scripts/evidence-requirements.txt` として分離してください。

Windowsでこの専用環境を使う場合、`--ots` を省略すると `scripts/ots_windows.py` を自動選択します。これはPythonに同梱されたOpenSSL DLLへの参照を補うだけで、公式ライブラリや証明方式は変更しません。公開する検査ログは定型の結果だけに制限し、ローカルのファイル名やRPC認証情報は含めません。

通常のrestoreは登録済みの確定公開版も元と同じ相対位置へ複製・検証します。登録台帳だけを復元して確定版byte列を省略しないでください。確定途中に中断した版番号はreservationに残し、別の内容で再使用しません。

アーカイブの作業フォルダで実行します。新規フォルダに作成し、既存268記事版を上書きしません。

```powershell
python -m archive.evidence seal SOURCE_SITE NEW_SITE --release-id YYYY.MM.DD.N
python -m archive.evidence verify NEW_SITE
python -m archive.evidence timestamp NEW_SITE stamp --ots PATH_TO_OTS
python -m archive.evidence timestamp NEW_SITE upgrade --proof SAVED_PROOF.ots --ots PATH_TO_OTS
python -m archive.evidence timestamp NEW_SITE verify --proof SAVED_PROOF.ots --ots PATH_TO_OTS
python -m archive.evidence sign NEW_SITE --secret-key PRIVATE_KEY --public-key PUBLIC_KEY --minisign PATH_TO_MINISIGN
python -m archive.evidence verify-signature NEW_SITE --signature SIGNATURE_FILE --public-key TRUSTED_PUBLIC_KEY --minisign PATH_TO_MINISIGN
```

seal/verifyはローカル処理です。timestampはOpenTimestampsの外部サービスへdigestを送る明示操作です。Python clientの独立検証にはBitcoin Coreが必要です。申請/upgradeの成功を検証成功と扱いません。成功したverifyだけを `verified` にします。時刻は証明の意味・精度に従い、取得時刻・生成時刻から推測しません。原典の公開日へ遡及しません。検証できない場合も元の証明を保持します。

署名は既存のMinisign鍵を指定します。鍵は自動新設しません。暗号化秘密鍵のpassphraseは端末へ直接入力し、JSONや引数へ保存しません。秘密鍵をサイト、Git、配布ZIPに置いてはいけません。公開鍵を公式プロフィール等で告知し、鍵の交換時は旧鍵/新鍵による移行記録と失効理由を別途保存してください。署名検証と本人との結び付きの確認は別です。

タイムスタンプ対象はmanifestそのものです。後から付けた署名の作成時刻までは証明しません。署名の存在時刻も必要な場合は署名を含む別の証明対象を追加します。

proofsは内容hash付きの別ファイルとして追記保存します。eventsも追記式です。`status.json` とZIPは表示/ダウンロード用の再生成物で、manifestには含めません。証明更新のたびに本文・manifestを書き換えません。鍵や外部サービスが使えなくても、本文の公開/ローカル検証は継続できます。

## 検証結果の意味

`proof_state=bitcoin_attestation_present` はBitcoinのブロックに対する照合情報が証明ファイルに含まれるという意味で、検証成功ではありません。`awaiting_verification` はその照合をまだ行っていない状態、`verification_unavailable` はBitcoin Coreへ接続できなかった状態です。`failed` はそれらと区別する取得/検証失敗です。公開statusに書かれた値だけを信頼せず、必要に応じて署名・タイムスタンプを再検証してください。

Hash chainは既知の過去のmanifestに対する整合性を示します。第三者が保持するhashや外部timestampがなければ、全履歴の作り直し・別履歴・最新状態の巻き戻しを単独では排除できません。`issued_at` は運営者が記録する確定日時です。証明の取得状態・検証日時・方法は独立したイベントです。ブラウザ上の状態表示は最終検査結果の表示であり、ブラウザ自身が独立検証した主張ではありません。

アルゴリズムや鍵を更新するときは古いbyte列と証明を残し、新しい方式の証拠を追加してください。配布データの削除要請等があった場合は公開範囲を別途判断し、公開履歴を無断で書き換えない運用とします。
