diff --git a/2-core-model.md b/2-core-model.md index fd00bd4..7455033 100644 --- a/2-core-model.md +++ b/2-core-model.md @@ -40,11 +40,11 @@ Objectは、探索に必要な公開情報とInterface参照を持つ。Host内 **エントリ**は、そのObjectをTree上の位置として見たときの呼び名である。 -エントリがObjectへの参照を別途持つ、という二重構造は前提としない。 +エントリがObjectへの参照を別途持つ、という二重構造はProtocolの交換形式として前提としない。Clientはcache実装上、Objectをflat storeへnormalizeし、Entry Treeから内部keyで参照してよい。 Tree上の位置はpathで表される。Pathはrootから各Objectの`name`を順に`/`で連結して構成する。Pathは恒久的なIdentityではなく、その時点でのnavigation coordinateである。 -同じ親の直下ではObjectの`name`は一意であり、非root Objectの`name`は空であってはならない。同じObjectが複数の位置に現れる場合、一つのObjectが異なる`name`とpathを持つ複数のエントリとして観測され得る。Objectの公開情報、name、path、Tree上の配置については[2.1. Object tree / Schema](2.1-object-tree-schema.md)で扱う。 +同じ親の直下ではObjectの`name`は一意であり、非root Objectの`name`は空であってはならない。同じObjectが複数の位置に現れる場合、そのObjectは同じ`name`を持ち、異なる親を経由する複数のpathで観測され得る。Objectの公開情報、name、path、Tree上の配置については[2.1. Object tree / Schema](2.1-object-tree-schema.md)で扱う。 ## Interface @@ -71,16 +71,20 @@ Clientは、次の4操作によってWorldspaceを観測および操作する。 ## `ref` -Objectは必要に応じて`ref`を公開できる。 +Objectは、同じ主体に公開された一つのWorldspace内でObjectの同一性を示すために、optionalな`ref`を公開できる。 -`ref`は内部IDそのものではなく、WIP上で同一Objectとして再参照するための外部Handleである。 +`ref`はopaque stringであり、Objectのprimary key、永続的なUID、navigation coordinateではない。Backendに適切なUIDがある場合、Hostはそれを直接または変換して使用できるが、WIPはbackend data形式から得られるUIDの公開を要求しない。 -- Objectが`ref`を持つことは必須ではない。 -- 複数回のInteractionを通して同一Objectとして扱われることを意図する場合、同じ有効な`ref`を公開する。 -- `ref`のscopeや有効期間はWorldspaceまたは実装が定めてよい。 -- `ref`はグローバルかつ永続的なUIDである必要はない。 -- 同じObjectが複数のエントリとして観測される場合、同じ`ref`によって同一性を示せる。 -- `ref`はnavigation coordinateではない。Objectの取得にはentry pathを使用する。 +- 同じWorldspace内で同じ有効な`ref`を持つObjectは、同じObjectを表す。 +- Hostは同じ有効な`ref`を異なるObjectへ付与してはならない。 +- `ref`が異なる、または片方に存在しない場合、同じObjectかどうかについて保証しない。 +- Hostが複数のエントリを同じObjectとしてClientへ認識させる場合、同じ`ref`を使用する。 +- `ref`の比較は、一つの主体に公開された同じWorldspace内でのみ意味を持つ。 +- 異なるWorldspace間で同じ文字列の`ref`が同じObjectを表すとはみなさない。 +- Session、再接続、Host restart、Worldspace再構築をまたぐ永続性を要求しない。 +- `ref`からObjectを取得するinteractionは提供しない。Objectの取得にはpathを使用する。 + +`ref`は完全なidentity systemではなく、Hostが明示した場合だけ複数の観測またはエントリを同一Objectとしてcorrelateするためのmarkerである。 ## 観測整合性 @@ -108,7 +112,7 @@ Validatorが一致しない場合、Clientは現在のObjectに対してOperatio WIPでは次の二つを分けて扱う。 -- **Object identity (`ref`)** — 複数の観測にまたがって同一Objectであることを明示するための任意の外部Handle。 +- **Object identity (`ref`)** — 一つのClient-facing Worldspace内で、複数の観測またはエントリが同じObjectを表すことを明示するoptionalなmarker。 - **Observation consistency** — `ref`の有無にかかわらず、観測したpath上のObjectと操作対象のObjectが一致していることを保証する仕組み。 したがって、`ref`を持たないObjectであっても安全な操作対象になり得る。`ref`は同一性を公開する仕組みであり、validatorはHostが定める現在状態との一致を条件付きOperationで検証する仕組みである。 diff --git a/2.1-object-tree-schema.md b/2.1-object-tree-schema.md index f71a2c1..0c63182 100644 --- a/2.1-object-tree-schema.md +++ b/2.1-object-tree-schema.md @@ -9,7 +9,7 @@ Objectは少なくとも次の公開情報を持つ。 - **name** — 親Objectの下でのpath segment。 - **description** — Objectが何を表すかを説明する情報。 - **interface** — Objectで利用できるOperationを定義するInterfaceへの参照。 -- **ref** — 同じObjectを複数の観測にまたがって識別するための任意の外部Handle。 +- **ref** — 同じClient-facing Worldspace内で複数の観測またはエントリが同じObjectを表すことを示すoptionalなmarker。 - **validator** — HostがObjectの現在状態へ付与する任意のopaque value。 具体的な型、必須性、resource limitは[3. Protocol](3-protocol.md)で定義する。 @@ -18,6 +18,17 @@ Objectの本文、状態、domain metadata等のApplication dataを、共通のp `description`は探索時に対象を理解するための短い公開情報であり、長い本文やdomain entityの完全な表現を格納する場所ではない。 +### 同じ`ref`を持つObject + +同じClient-facing Worldspace内で同じ`ref`を持つObjectは、一つの共有された現在状態を持つ。同じObjectを異なるpathへ配置したことを理由に、path固有の`name`、`description`、Interfaceを返してはならない。 + +- 同じ`ref`と同じvalidator valueを持つObjectは、validatorが存在する場合、`name`、`description`、Interfaceを含むObject representationが一致しなければならない。 +- 同じ`ref`と異なるvalidatorを持つObjectは、同一Objectの異なる状態として扱う。 +- Hostは異なるpathから同じ`ref`を観測した場合も、一つの現在状態を一貫して返す。 +- Clientは最後に成功した観測を、その`ref`を持つObjectの現在状態として扱う。 + +同じObjectを異なる親の下へ配置する場合もObjectの`name`は共通である。Pathは親から各Objectの`name`を辿って構成するため、同じObjectは異なる親を経由して異なるpathに現れ得る。 + ## Interface参照 Objectは一つのInterfaceを参照する。 @@ -77,7 +88,7 @@ fetch("/projects/example") -> Object.name == "example" ``` -同じObjectが複数のpathへ配置される場合、同じ`ref`を持ちながら配置ごとに異なる`name`を持ち得る。Objectをrenameまたは別の親へ移動すると、そのObjectとdescendantのpathは変化する。Pathは恒久的なObject identityとして使用しない。 +同じObjectが複数のpathへ配置される場合、同じ`ref`と`name`を持ち、異なる親を経由して異なるpathに現れる。Objectをrenameすると、そのObjectを参照するすべての配置とdescendantのpathが変化する。Pathは恒久的なObject identityとして使用しない。 `ref`、path、Interface参照は異なる役割を持つ。 diff --git a/3-protocol.md b/3-protocol.md index 1274906..a5abb25 100644 --- a/3-protocol.md +++ b/3-protocol.md @@ -93,11 +93,22 @@ Nameに`/`を許可しないため、Protocolはpath segment escapeを定義し `Object.interface`と`FetchInterfaceRequest.interface`はInterface Descriptorへのopaqueな参照として解釈する。同じInterface参照が有効である間、Hostは異なるDescriptorを返してはならない。Descriptorを変更した場合は新しいInterface参照をObjectで公開する。 -`Object.ref`は複数の観測にまたがって同一Objectであることを示す任意のopaque stringである。Navigationには使用せず、すべてのObjectに存在するとは限らない。Scopeと有効期間はWorldspaceまたはHost実装が定める。 +`Object.ref`は、同じ主体に公開された一つのWorldspace内で、複数の観測またはエントリが同じObjectを表すことを示すoptionalなopaque stringである。 + +- 同じ有効な`ref`は同じObjectを表す。 +- Hostは同じ有効な`ref`を異なるObjectへ付与してはならない。 +- 異なるまたは欠落した`ref`からObjectが異なるとは判断しない。 +- 異なるWorldspace間で`ref`を比較しない。 +- Session、再接続、Host restart、Worldspace再構築をまたぐ永続性を要求しない。 +- Navigationには使用せず、`ref`からObjectを取得するinteractionは提供しない。 + +Backendに適切なUIDがある場合、Hostはそれを直接または変換して使用できるが、Protocolはbackend UIDの存在または公開を要求しない。 `Object.validator`は、HostがそのObjectの現在状態へ付与するoptionalなopaque bytesである。Clientは内容を解釈せず、観測に基づくOperationを条件付きで実行するときに、pathとともに`target.validator`へコピーする。 -Hostはvalidatorの生成方法を自由に選べる。Generation、content hash、database revision等を使用してよい。Hostは、どの状態変化によってvalidatorを無効にするかについて、そのObjectとInterfaceに対して一貫した方針を適用する。 +Hostはvalidatorの生成方法を自由に選べる。Generation、content hash、database revision等を使用してよい。ValidatorはObject identityとHostが保護する現在状態の両方へ結び付け、target pathが別Objectを指す場合は、内容が同じでも一致させてはならない。Content hashを使用する場合はObject identityをhashへ含めるか、Hostがidentityを別途検証する。 + +Hostは、どの状態変化によってvalidatorを無効にするかについて、そのObjectとInterfaceに対して一貫した方針を適用する。Validatorはpathに固有ではなく、同じ`ref`を持つObjectの現在状態に付与する。 ValidatorはAIやユーザーへ公開するApplication dataではなく、Client runtimeがObjectとともに保持するprotocol metadataである。 @@ -152,6 +163,17 @@ Objectで利用できるOperationを定義するInterface Descriptorへの参照 Objectの現在状態にHostが付与する任意のopaque value。ClientはObjectとともに保持し、その観測に基づく条件付きOperationのtargetへ使用する。 +### 同じ`ref`を持つObjectの整合性 + +同じWorldspace内で同じ`ref`を持つObjectは、一つの共有された現在状態を表す。 + +- 同じ`ref`と同じvalidator valueを持つObjectは、validatorが存在する場合、`name`、`description`、`interface`を含む全fieldが一致しなければならない。 +- 同じ`ref`と異なるvalidatorを持つObjectは、同一Objectの異なる状態として扱う。 +- HostはObjectが配置されたpathを理由に、同じ`ref`へ異なる`name`、`description`、`interface`を同時に公開してはならない。 +- Clientは最後に成功した観測を、その`ref`を持つObjectの現在状態として扱う。 + +同じObjectを複数のpathへ配置する場合、各配置は同じObjectの`name`を使用する。異なる親を経由することでpathが異なる。 + `Object`はchildrenとpathを直接持たない。これらはObject identityに固有とは限らず、Objectを観測したentryまたはTree traversalのcontextに属するため、requestまたはTree responseで表す。 Objectの意味とApplication dataとの境界は[2. Core Model](2-core-model.md)と[2.1. Object tree / Schema](2.1-object-tree-schema.md)で扱う。 diff --git a/4-client.md b/4-client.md index f3c3db4..d2fb3c9 100644 --- a/4-client.md +++ b/4-client.md @@ -21,6 +21,42 @@ Operationを通して発見されたpathは、必ずしもKnown Spaceへ追加 既知エントリ間の移動や参照はClient側で処理できる。既知の空間を辿るたびにHostへ問い合わせる必要はない。 +## Object storeとEntry Tree + +ClientはKnown Spaceを、flatなObject storeとEntry Treeへnormalizeして保持できる。 + +```rust +struct CachedWorldspace { + objects: HashMap, + entries: HashMap, +} + +struct CachedObject { + name: String, + description: Option, + interface: String, + r#ref: Option, + validator: Option>, + metadata_stale: bool, +} + +struct CachedEntry { + object: InternalObjectKey, + children: Vec, +} +``` + +`InternalObjectKey`はClient内部だけで使用し、Protocolへ公開しない。 + +- 観測したObjectが`ref`を持ち、同じWorldspaceのObject storeに同じ`ref`が存在する場合、既存のCachedObjectを更新してEntryから参照する。 +- `ref`がない場合、ClientはEntryごとにInternalObjectKeyを発行し、異なるpath間でObjectをdeduplicateしない。 +- Entry Treeはpathと親子関係を保持し、Object storeはObjectの現在状態を保持する。 +- 同じObjectを複数のEntryが参照しても、Object stateをEntryごとに複製しない。 + +同じ`ref`と同じvalidator valueを持つObjectを再観測したとき、validatorが存在するにもかかわらずObject representationが異なる場合、Clientはresponseを`invalid_result`として扱う。同じ`ref`でvalidatorが異なる場合、またはvalidatorが存在しない場合は、同一Objectの新しい観測として最後に成功した観測でCachedObjectを更新する。 + +このnormalizeはClientのcache実装であり、Objectと別のWIP resourceまたはProtocol上のEntry resourceを導入するものではない。 + ## Interface cache Objectの公開情報はOperation定義を直接含まず、Interface参照を持つ。Clientは未知のInterface参照を`fetch_interface`で解決し、取得したInterface Descriptorを参照ごとにcacheする。 @@ -61,9 +97,11 @@ Clientは、機械的にエントリを探索する必要がある場合、個 ## Objectの同一性 -Objectが`ref`を公開している場合、Clientはそれを用いて複数のエントリや複数回の観測が同一Objectを指していることを追跡できる。 +`ref`は、同じ主体に公開された一つのWorldspace内で、複数の観測またはエントリが同じObjectを表すことを示すoptionalなopaque markerである。 -`ref`はHost内部のIDそのものとは限らず、WIP上でObjectを再参照するための外部Handleとして扱う。 +同じ有効な`ref`は同じObjectを保証する。異なるまたは欠落した`ref`からObjectが異なるとは判断しない。Clientは異なるWorldspaceの`ref`を比較せず、`ref`を永続的なprimary keyまたはNavigationに使用しない。 + +Backend UIDが適している場合、Hostはそれを直接または変換して`ref`に利用できる。ただし、Clientは`ref`がbackend UIDであること、またはsessionやHost restartをまたいで安定することを仮定しない。 ## 観測整合性 @@ -71,6 +109,8 @@ Clientは、エントリを観測した後にOperationを実行するまでの Objectが`validator`を持つ場合、Clientは観測したpathとvalidatorを対応付ける。条件付きOperationでは両者をtargetとしてHostへ渡し、validatorの比較と実行をHost上でatomicに行わせる。ValidatorはAIやユーザーに直接管理させない。HTTPS Bindingは、semanticsが適合する場合にHTTP ETag等へ対応付けてよい。 +Operation responseが新しいvalidatorを返した場合、Clientは対象のCachedObjectへ反映する。Operationによって`name`、`description`、Interface等の公開情報が変化し得る場合、ClientはCachedObjectのmetadataをstaleとして扱い、利用前に`fetch`で再観測する。 + 対象が変化していた場合、Clientは新しいObjectに対してOperationを自動再試行せず、対象が変化したことを上位インターフェースへ通知して再観測を要求する。 ## 想定実装 diff --git a/draft/unresolved-issues.md b/draft/unresolved-issues.md index ecb17e2..f380911 100644 --- a/draft/unresolved-issues.md +++ b/draft/unresolved-issues.md @@ -6,7 +6,6 @@ 対象: [2.1. Object tree / Schema](../2.1-object-tree-schema.md) -- 一つのObjectが複数pathへ配置された場合、`description`をObject固有または配置固有のどちらとするか。 - Partial visibility、redaction、authorization failureの表現。 ## 2.2. Interface / Operation @@ -27,9 +26,7 @@ ### Field semantics -- `ref` fieldのencoding、scope、有効期間。 - `interface` fieldで使用するopaque参照のscopeと有効期間。 -- Validatorの生成、期限、再利用、およびObjectごとの無効化方針をどこまで標準化するか。 ### Type / Value @@ -49,7 +46,6 @@ 対象: [WIP over HTTPS](wip-over-https.md) - Protocol primitive、Object、Interface Descriptor、ValueのJSON encoding。 -- Validatorをresponse body、HTTP ETag / If-Match、または両方へどうmappingするか。 - Protocol failureのHTTP statusとerror body。 - Batch件数、request / response byte size、timeoutの上限。 - Batch envelope自体が不正な場合のHTTP statusとerror body。