Skip to content

CIP-4: Delete

0. Abstract

本ドキュメントでは、Concrnt Document (CIP-1) を削除するための削除 Document の形式と、その処理を定義する。

1. Status of This Memo

このドキュメントは Document の削除の仕様を定義する。 Concrnt プロジェクトにより公開されるバージョン付き仕様であり、実装者およびプロトコル設計者を対象とする。

本 CIP はオプショナルな拡張であり、CIP-0, CIP-1, CIP-3 を前提とする。 削除の認可には CIP-12、削除の伝搬には CIP-7 を必要とする。

本仕様はドラフトであり、後方互換性のない変更が行われる可能性がある。

2. 表記規則

このドキュメントにおける以下の語は、必ず大文字で記述される場合、 BCP 14 [RFC2119] [RFC8174] にしたがって解釈される。

MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, OPTIONAL

3. 削除 Document

Concrnt Document の削除は、kind フィールドに "delete" を指定した Document を Commit エンドポイント (CIP-3) に送信することで行う。 削除 Document の value フィールドには、削除対象を CCURI で指定する。

{
"kind": "delete",
"schema": "https://...",
"value": "ccfs://<owner>/concrnt/<cdid>",
"author": "con1...",
"createdAt": "2025-11-23T12:34:56Z"
}

削除 Document は key フィールドを持ってはならない (MUST NOT)。schema は OPTIONAL である。

削除対象として指定できるのは以下である。

  • cckv:// URI: キーに紐づく record の削除
  • ccfs://<owner>/concrnt/<cdid> URI: CDID 指定による record または association の削除
  • 末尾に * を付与した cckv:// URI: 範囲削除 (§4)

削除のセマンティクスは次の通りである。

  • cckv URI による削除は、そのキーに保存されたすべての世代の Document (onUpdate: "retain" により保持された旧版を含む) を削除しなければならない (MUST)。
  • ccfs URI による削除は、当該版の Document のみを削除する。キーの現行版が ccfs 指定で削除された 場合、そのキーは保持された旧版に巻き戻らず、解決不能となる。

サーバーは削除の実行前に、リクエスタが対象 Document を削除する権限を持つことを ポリシー評価 (CIP-12) によって確認しなければならない (MUST)。 削除の認可におけるリクエスタは、proof によって確証された削除 Document の author であり (MUST)、 トランスポート上の認証主体 (CIP-2) を用いてはならない (MUST NOT)。 伝搬された削除 (§6) は origin サーバーが代理配送するため、両者は一般に異なる。

削除対象が存在しない場合 (範囲削除で範囲に 1 件も一致しない場合を含む)、権威サーバーは HTTP 404 Not Found を返さなければならない (MUST)。 これは権威サーバーでの処理についての規定であり、伝搬された削除を受信した側の扱いは §6.1 (no-op) による。

4. 範囲削除 (Range Delete)

削除対象の cckv:// URI の末尾に * を付与することで、キー階層の配下を一括で削除できる。

  • cckv://<owner>/<key>* — <key> 自身と、その配下のすべての子孫キーを削除する。
  • cckv://<owner>/<key>/* — <key> 自身は削除せず、配下のすべての子孫キーのみを削除する。
{
"kind": "delete",
"value": "cckv://con1alice/posts/2025*",
"author": "con1alice",
"createdAt": "2025-11-23T12:34:56Z"
}

4.1 対象の選択規則

  • 範囲のマッチングはキーのパス階層 (CIP-0 §7.2。区切りはバイト 0x2F のみ) によって行う。 文字列の前方一致ではない。すなわち cckv://con1alice/item* の対象は item 自身と item/... 配下 のみであり、兄弟キー item2 は決して対象にならない (MUST)。
  • * は削除対象の末尾の範囲指定子としてのみ使用できる。それ以外の位置に * を含む 削除対象は不正であり、拒否しなければならない (MUST)。 (キー自体に * を含む Document は存在しない。CIP-0 §7.2)
  • 範囲削除の対象は cckv スキームでなければならず (MUST)、key 部が空であってはならない (MUST)。 エンティティ配下全体 (cckv://<owner>* 等) を範囲削除の対象にすることはできない。

4.2 処理セマンティクス

範囲削除は all-or-nothing で処理されなければならない (MUST)。

  1. サーバーは、範囲に一致するすべての現存 Document を列挙する。
  2. 列挙した各 Document に対して個別に削除のポリシー評価 (CIP-12) を行う。 1 件でも権限のない Document が含まれる場合、範囲削除全体を失敗させ、 いかなる Document も削除してはならない (MUST NOT)。
  3. すべての対象について権限が確認できた場合にのみ、列挙した集合を削除する。 列挙後に新たに作成された Document は、この削除の対象に含めてはならない (MUST NOT)。

削除された各 Document について、単一削除と同様に、削除イベントの発行、配布先への伝搬 (§6)、 Removed Node (CIP-8 §7) への掲載を行う。

レスポンス (CIP-3 §3.3) として返す対象は、削除された対象を URI の辞書順 (昇順) で並べたときの 先頭の Document である (<key> 自身が対象に含まれる場合、それが先頭となる)。

5. リプレイ防御

削除の永続性は、CIP-3 §3.4 のリプレイガード (backdate window とコミットログによる重複排除) に よって担保される。削除された各 Document、および削除コマンド (kind: "delete") 自身の CDID は コミットログに残るため、捕捉されたそれらの Document を再コミットしても no-op となり適用されない。

削除コマンドは、ユーザーから直接届いた場合も、author のサーバーが配布先へ代理で転送した場合 (§6) も、 同じく通常のコミットとして記録する。コミットの所有者は削除対象の名前空間の owner である (CIP-3 §3.1)。 ただし実際に何も削除しなかったコミットは記録しない (§6.1、CIP-3 §3.4)。

すべてを記録し続ける必要はない。削除された Document が onUpdate: "retain" でない場合、その Document の コミットと削除コマンド自身のコミットは、CIP-3 §3.4 の保持期間 (backdate window) を過ぎた後に GC してよい (MAY)。保持期間を過ぎた Document の再コミットは backdate window により拒否されるため、 リプレイガードは保たれる。onUpdate: "retain" の Document を削除した場合は、履歴を再生できるように その Document のコミットと削除コマンドのコミットの両方を保持する (SHOULD)。

伝搬された削除を受信したサーバーのコミットログの記録条件は §6.1 で規定する。 これを超える追加の防御は、受信側サーバーに要求されない。

6. 削除の伝搬

削除が受理された場合、サーバーは削除イベント (deleted / unassociated, CIP-11) を発行する。 削除対象の Document が distributes を持つ場合は、削除を各配布先へ伝搬する (CIP-7)。

リモートへ削除を伝搬する場合、配送される Signed Document の references には、 削除された対象の Signed Document を同梱しなければならない (MUST)。 これにより、受信側は追加の問い合わせなしに削除対象を特定できる。

伝搬の配送は配送先サーバーごとに 1 つとし、そのサーバーが管理する配布先に配布されている 削除対象すべてを references に同梱しなければならない (MUST)。 削除対象ごとに配送を分割してはならない (MUST NOT) — 分割された配送は同一の削除 Document (同一 CDID) を持つため、受信側の重複排除 (§6.1) により 2 件目以降が no-op となり、参照行が削除されずに残る。

削除対象が association である場合は、関連先 (associate) の Signed Document も 同梱しなければならない (MUST)。受信側は unassociated イベントの構成にこれを必要とし、 欠落した配送を拒否してよい (MAY)。

6.1 受信側の処理 (参照行のスイープ)

削除対象の権威サーバーではないサーバー (配布先を管理するサーバー) は、 伝搬された削除を、自身が保持する自動生成 Reference Document (CIP-7 §4.1) のスイープとして 処理する。処理は create / associate の配布処理と対称であり、以下の手順による。

  1. 対象の復元: references から削除対象の Signed Document を取り出す。 単一削除では削除対象 URI と同一のキーのエントリ、範囲削除では範囲に一致するキーのエントリが 対象である。対象が 1 件も同梱されていない削除は、エラーとせず no-op として成功を返す (MUST)。 このときコミットログを記録してはならない (MUST NOT) — 後から対象を同梱した正当な配送が、 重複排除によって無視されてしまうことを防ぐためである。
  2. 参照行のアドレス指定: 各対象について、同梱された Document からその href (kind: "record" は Document の key、key を持たない Document はその ccfs URI。CIP-7 §4.1) を再導出し、hash-based CDID (CIP-1 §6.3) にエンコードする。 対象の署名済み distributes の各配布先 <dest> について、自動生成 Reference Document のキー <dest>/<CDID> をローカルストレージから引く。行が存在しない配布先 (リモートの配布先・未配送の配布先) は単にスキップする。 引いた行が自動生成 Reference Document であること — schema が reference.json、proof の type が document-reference、value.href が対象 Document の URI と一致すること — を確認しなければ ならない (MUST)。一致しない行 (ユーザーが同名キーに直接コミットした record 等) はスキップする。 アドレス指定の束縛は対象の href 粒度である。同梱された Document の正当性は署名・proof の検証 (手順 1 の前提としての References 検証) が、行と対象の同一性は上記の value.href 一致チェックが、 削除の認可は手順 3 の行ごとのポリシー評価が担保する。異なる href を持つ偽造・改変された Document は異なるキーを導出するため、無関係の保存済み行には一致しない。
  3. 行ごとのポリシー評価: 存在した各 Reference 行について、保存済みの Reference Document を self として削除のポリシー評価 (CIP-12) を行う (MUST)。拒否された行は削除せずに残し、残りの行の 処理は継続する (配布先のポリシーによる拒否は、削除全体を失敗させない)。 デフォルトポリシーの下では、Reference Document の author (= 削除対象の author) と 配布先名前空間の所有者のみが削除を許可される。
  4. 削除と広告: 許可された行を削除し、Removed Node (CIP-8 §7) への掲載と削除イベントの発行を 自身の購読者に対して行う。受信側サーバーは削除を再連合してはならない (削除の再配送は権威サーバーのみが行う)。

受信側サーバーは、1 件以上の参照行を実際に削除した場合にのみコミットログを記録する (MUST)。 これが同一の削除が複数回配送された場合の重複排除になる。行を 1 件も削除しなかった場合は 記録しない (CIP-3 §3.4)。

伝搬された削除によって削除できるのは、手順 2 でアドレスされた自動生成 Reference Document のみである。 それ以外のローカル Document を伝搬削除の対象としてはならない (MUST NOT)。

権威サーバー自身も、対象本体の削除と同一トランザクションで、自身が管理する配布先の参照行に対して 同じスイープ (手順 2〜4) を行う。これにより、配布先が同一サーバー上にある場合も参照行が孤児化しない。

7. Security Considerations

  • 範囲削除は 1 コミットで多数の Document を削除できる。対象ごとのポリシー評価 (§4.2) を 省略してはならない (MUST NOT)。
  • 範囲マッチングを文字列前方一致で実装すると、兄弟キー (item* に対する item2) を誤って削除する。 実装は必ずパス階層でマッチングすること (§4.1)。
  • 伝搬された削除の受信処理 (§6.1) において、参照行の削除自体は CDID によるアドレス指定と ポリシー評価で保護される。一方、削除イベント (CIP-11) の発行は references の同梱内容に基づく ため、第三者の作為的な配送により、実際には何も削除されていない対象の deleted / unassociated イベントが発行されうる。イベントは助言的な通知であり、クライアントは対象の実際の状態を resolve で確認すること (CIP-11 §4)。
  • 配送の再試行 (CIP-7 §4.2.1) により、配布 (Reference のコミット) より削除の伝搬が先に到着する 順序逆転が起こりうる。この場合、削除済み Document を指す参照行が残る。受信側サーバーは、 処理した削除対象のキー <dest>/<CDID> を一定期間記録し、その間に到着した同キーへの Reference コミットを no-op としてもよい (MAY)。ただしキーは href から導出され安定である (CIP-7 §4.1) ため、 記録期間中に同一キーへ Document が再作成・再配布された場合、その正当な参照コミットも no-op となりうる — 記録期間は再試行ウィンドウ程度に留めること。

8. References

  • RFC 2119 – Key words for use in RFCs to Indicate Requirement Levels
  • RFC 8174 – Clarifications to RFC 2119
  • CIP-3 – Commit (リプレイガード、コミットログ)
  • CIP-7 – Distribution (配布と伝搬)
  • CIP-8 – Chunkline (Removed Node)
  • CIP-12 – Policy (削除の認可)

この文書は concrnt/CIPs-translated の ja/4-delete.md から生成されています。原文(英語)は concrnt/CIPs を参照してください。