feat: add Astro reference site and organize book contents
Reference site / build (push) Canceled after 0s
Reference site / build (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
# 4. クライアント
|
||||
|
||||
## 役割
|
||||
|
||||
Clientは、Hostが提供するWorldspaceを利用する実装主体である。WIP Protocolを利用しつつ、Objectが参照するInterface集合を解決し、用途に応じたView、Tool、API等の上位インターフェースへ投影する。
|
||||
|
||||
ClientはHostから得た情報をinteractionごとに破棄するだけでなく、rootからindexable edgeを辿って構成したエントリツリーと、必要に応じて選択したエントリを保持し、上位層にとっての**既知の空間**を構成する。
|
||||
|
||||
## Known Space
|
||||
|
||||
Known Spaceは、Clientが**現在保持しているエントリの集合**である。過去に発見したすべてのエントリを単調に蓄積する集合ではない。
|
||||
|
||||
Known SpaceとDiscoverable SpaceはClientが過去の観測から構築したcacheであり、Host上の現在状態を同期したreplicaではない。HostはClientのcache状態を追跡または更新しない。
|
||||
|
||||
Clientは、観測結果が同じeffective Worldspace viewに属する範囲でcacheを共有する。接続先、認証主体、tenant、その他のsecurity contextによって異なるWorldspaceが公開され得る場合、それらのKnown Space、Object observation、Interface cacheを混在させない。具体的なcache namespaceの構成はClientおよびTransport Bindingに委ねる。
|
||||
|
||||
次のような経路で得られたエントリをKnown Spaceへ追加できる。
|
||||
|
||||
- `observe`で取得したエントリ
|
||||
- Operation結果の`entry`型pathを`depth = 0`で`observe`して取得したエントリ
|
||||
|
||||
Operationを通して発見されたpathは、必ずしもKnown Spaceへ追加する必要はない。Clientは現在の結果として一時的に扱うことも、取得後に必要なエントリだけを選択して保持することもできる。
|
||||
|
||||
既知エントリ間の移動や参照はClient側で処理できる。既知の空間を辿るたびにHostへ問い合わせる必要はない。
|
||||
|
||||
## 取得・保持・提示の分離
|
||||
|
||||
ユーザーやAIがpathを知っていること、ClientがObjectを観測・保持していること、Clientがindexable edgeも観測・保持していることは別の状態である。
|
||||
|
||||
ClientはKnown Spaceにない有効なpathも取得対象にできる。過去に観測していないことだけを理由に取得を拒否せず、現在のHostの公開状態に従って`observe`する。取得前に仮のObjectをKnown Spaceへ登録する必要はない。Pathを知っていること自体は公開可視性や実行権限を保証しない。
|
||||
|
||||
観測したObjectのどの情報を提示するかは、上位インターフェースの責務である。ClientがObject情報を保持していても、配置だけを提示する場面ですべての説明やInterfaceを展開する必要はない。提示済みの情報とcache内容を同一視しない。
|
||||
|
||||
Objectを観測・保持したことだけでは、そのpathを既知のtreeへ接続するindexable edgeを得たことにはならない。Treeの構成には観測済みのedgeを使い、pathのprefixや階層関係からedgeを推測しない。
|
||||
|
||||
## Entry TreeとObject observation
|
||||
|
||||
Clientは、観測したObjectをcanonical path上のEntryへ対応付け、観測済みのindexable child edgeとともに保持できる。具体的なcache表現は規定しない。Clientは`ObjectObservation`に近い入れ子構造またはforestを保持しても、path index、flatなObject store、Entry Treeへnormalizeしてもよい。
|
||||
|
||||
EntryのpathとchildrenはWorldspace上の配置contextであり、Object identityそのものには含まれない。同じObjectが複数のEntryから観測される場合、Clientはshared record、複製したsnapshot、その他の内部表現を使用できる。ただし、保存形式によって`ref`、validator、Object representationのconsistencyを変えてはならない。
|
||||
|
||||
- 同じ有効な`ref`を持つ観測は、同じWorldspace内の同じObjectを表す。Clientは一つのObject stateを共有しても、Entryごとにsnapshotを保持してもよい。
|
||||
- `ref`がないこと、または異なることから、複数のEntryが同じObjectか異なるObjectかを判断しない。Clientはrepresentationが同じという理由だけでObject identityを推測しない。
|
||||
- Objectの`interfaces`はmembershipをsetとして扱い、同じ参照の重複を`InvalidResponse`として拒否する。ClientはHostの立項順を保持し、InterfaceやOperationの提示順に使用してよい。
|
||||
- 同じ`ref`と同じvalidator valueを持つObjectを再観測したとき、validatorが存在するにもかかわらずObject representationが異なる場合、Clientはresponseを`InvalidResponse`として扱う。同じ`ref`でvalidatorが異なる場合、またはvalidatorが存在しない場合は、同一Objectの新しい観測として扱い、最後に受理した成功観測をその`ref`の現在状態とする。
|
||||
|
||||
このcache表現はClient内部の実装であり、Objectと別のWIP resourceまたはProtocol上のEntry resourceを導入するものではない。
|
||||
|
||||
## Interface cache
|
||||
|
||||
Interface参照は`{ scope, name }`のrecordであり、同じeffective Worldspace view内の`(scope, name)`の完全一致で比較する。Local nameだけ、表示用の短縮表記、JSON serializationのbyte列をcache keyにしない。Scopeが異なれば別参照であり、Host内部のUpstream座標へ読み替えない。
|
||||
|
||||
Clientは各Objectの配置pathに対して[scopeの祖先制約](2.1-object-tree-schema.md#interface-scope)を検証する。参照の解決には完全なscopeとnameを使い、祖先Objectの順次取得、同名Interfaceの探索、shadowingを導入しない。Scopeの適合だけでInterface membershipやauthorizationを推測しない。
|
||||
|
||||
Objectの公開情報はOperation定義を直接含まず、Interface参照のordered setを持つ。Clientは必要な参照を`fetch_interface`で解決し、取得したInterface Descriptorとoptionalなvalidatorを観測としてcacheする。
|
||||
|
||||
```rust
|
||||
struct CachedInterface {
|
||||
scope_ref: Option<String>,
|
||||
descriptor: InterfaceDescriptor,
|
||||
validator: Option<Vec<u8>>,
|
||||
}
|
||||
```
|
||||
|
||||
Clientは同じ有効期間内でvalidatorが存在する観測を`(interface, validator)`の組で識別し、Interface参照ごとに最後に成功した観測をcurrent entryとして保持できる。Validatorが存在しないInterface参照は、その参照が有効な間Descriptorがimmutableなので、参照だけをcache keyに使用できる。
|
||||
|
||||
`scope_ref`は`fetch_interface`が返すscope Objectのoptionalな`ref`であり、参照の第三成分ではなく観測metadataとして保持する。観測に存在する場合はcallの`interface.scope_ref`へコピーし、なければ省略する。Clientはscope Objectや祖先を追加取得する必要がない。Scope Objectを別途観測して紐付きを確認できなくなった場合は、古いDescriptorの`scope_ref`だけを更新せず、Interface observationを取得し直す。
|
||||
|
||||
Scope Objectがそのpathから消えたことを確認したClientは、そのscopeのInterface cacheを破棄できる。Scope Objectの`ref`が以前の紐付きを確認できない値へ変わった場合や`ref`がなくなった場合も、旧観測を新しいcallへ使用しない。有効期間が終了した旧観測と、同じpathへ再公開された新しい観測を区別する。Scopeの移動先を追跡してcacheを付け替えない。
|
||||
|
||||
`ref`のないscopeが同じpathで差し替わる場合、Clientがそのidentityや有効期間の切り替わりを追跡できないことは仕様上許容される。欠落を不正なresponseとしたり、疑似identityを生成したりしない。得られた情報によるDescriptor・validatorの検証は引き続き行うが、検出不能な差し替えの防止は保証しない。
|
||||
|
||||
削除の確認とClient-localなcache evictionを混同しない。Indexable edgeが一覧から消えただけでは、直接観測可能な非indexable Objectとして存続している可能性があり、scope Objectの削除を断定しない。削除の即時検出、監視、全Interfaceの先行再取得は要求しない。破棄可能なcacheであっても、実行中callの結果検証に必要なDescriptorは完了まで保持する。
|
||||
|
||||
一つのInterface Descriptorに宣言されたOperationの集合が、そのInterfaceのOperation一覧である。Objectは複数のInterfaceを組み合わせられ、複数のObjectも同じInterfaceを共有できる。
|
||||
|
||||
ClientはDescriptorが必要なInterface参照とcacheを比較し、未知のInterfaceだけを取得する。Objectの`interfaces`からDescriptor interestを先行して導出しても、Operationを選択した時点で必要な参照だけを取得してもよい。Interface validator mismatch等で更新が必要になった参照は再取得する。複数の`fetch_interface`が必要な場合、それぞれを個別のrequestとして並行実行できる。
|
||||
|
||||
異なるInterfaceで同じOperation名が存在しても、Clientは構造化Interface参照とOperation名の組で識別する。UIやAI Toolのqualified表示は[Text Viewの参照表記](4.2-text-view.md#参照表記)に従う。Operation callではsignature全体をparseせず、Interface参照とOperation名を別fieldとして送る。
|
||||
|
||||
実行中のOperationが使用するDescriptor observationは、resultのvalidationが完了するまで保持する。新しいvalidatorのDescriptorを観測しても、古いvalidatorで開始済みのcallに必要なDescriptorを早期に破棄しない。
|
||||
|
||||
## Discoverable Space
|
||||
|
||||
Clientは、Hostから`observe`で取得したindexableなエントリツリーをDiscoverable Spaceとして保持する。Discoverable Spaceとして扱う間、Clientはその観測済みtreeの構造を保持する必要がある。
|
||||
|
||||
Discoverable SpaceはKnown Spaceの部分集合であり、AI向けの`tree`など、indexableな配置の探索に利用する。Worldspace rootまたはClientが選択した起点からindexable edgeで到達できる、materialize済みの範囲によって構成される。
|
||||
|
||||
Clientが`observe`結果をmergeし、`children`が存在するparent nodeから以前のindexable edgeが返されなくなった場合、その子エントリをDiscoverable Spaceから除外する。その結果、保持しているどの起点からも到達不能になったsubtreeは、その場で破棄できる。ただし、別の経路から到達できるエントリ、Clientがpinしたエントリ、実行中のOperationが参照しているエントリは引き続き保持してよい。`children`が省略されたnodeはedge削除の根拠にしない。
|
||||
|
||||
Operationを通して発見されたpathは、それだけではDiscoverable Spaceへ追加しない。そのエントリを起点として`depth > 0`で`observe`した場合に、そのindexableな範囲をDiscoverable Spaceへ追加できる。
|
||||
|
||||
## 一時的な発見とpin
|
||||
|
||||
Clientは、Operation Resultの`entry`型として発見したpathを、そのObjectを即時に観測せず、現在の結果として提示・利用できる。結果のpathを提示することと、Objectを取得することは別であり、発見したすべてのpathの即時取得は要求しない。
|
||||
|
||||
Objectの公開情報が必要になった時点で、Clientは必要なpathを観測できる。対象Objectだけが必要なら`depth = 0`を使う。Client policyとして先行取得してもよく、その場合はOperationのreturn typeからentry pathを抽出して重複を除去し、保持済みの観測と比較して必要な取得を行う。複数の`observe`が必要な場合、それぞれを個別のrequestとして並行実行できる。
|
||||
|
||||
一時的に取得したエントリは、結果の利用が終わった時点で破棄してよい。
|
||||
|
||||
後続のInteractionでも必要なエントリは、Client側でpinしてKnown Spaceへ保持できる。PinはClient内部の保持方針であり、Host上のObject lifetimeやWIP Protocol上の状態を変更しない。
|
||||
|
||||
単純なClientは発見したエントリをすべて保持してもよいが、WIPはそれを必須としない。具体的な容量制限やeviction algorithmはClient実装に委ねる。
|
||||
|
||||
## Objectとchildrenの観測
|
||||
|
||||
Clientは`observe(path, depth)`を使い、対象Objectだけが必要なら`depth = 0`、indexableな配下も必要なら正のdepthを指定する。一つのinteractionでrequested depthまでを取得するため、Clientが各nodeについてdata-dependentな取得requestを逐次発行する必要はない。
|
||||
|
||||
Response nodeの`children`が省略されている場合、そのnodeのchildrenは未観測であり、空であるとは扱わない。`children`が存在する場合、その一覧は完全であり、空arrayならindexable childが存在しない。Clientは起点pathと各Objectの`name`からchild pathを導出する。`children`が存在するnodeをcacheへmergeするときは、そのEntryで観測済みのdirect child edgeをresponseの完全な一覧で置き換える。`children`が省略されたnodeは構造について新しい情報を持たないため、既存edgeを削除したり、観測済みの一覧を未観測へ戻したりしない。
|
||||
|
||||
件数の非常に多い集合の個々の要素は、通常indexableな子エントリとして露出しない。個別要素は対象の集合を扱うObjectの`query`や`list`等のOperationを通して発見することを想定する。
|
||||
|
||||
## Interestと取得計画
|
||||
|
||||
Clientの上位層は、特定pathについて必要な観測depth、または特定Interface参照についてDescriptorが必要であることを、Client-localな**interest**として示せる。InterestはProtocol dataではなく、Hostはその状態を追跡しない。Interestの追加または削除は、保持済み観測のProtocol上の意味や有効性を変更しない。Interestがなくなった観測を保持するかevictするかはClient policyに委ねる。
|
||||
|
||||
Clientはinterestを、現在有効なObject observation、children coverage、Interface Descriptor observation、および進行中の取得requestと比較し、不足するlogical interactionだけを発行できる。要求されたdepthまでのcoverageがすでに存在する場合、または進行中のrequestによって満たされる場合、同じinterestの調整処理は重複requestを発行しない。Depth境界で`children`が省略されたnodeは、その配下に対する正のdepthのinterestを満たさない。
|
||||
|
||||
Clientは、interestを満たすためのidempotentな調整と、既存の観測を置き換える明示的な再観測を区別できる。明示的な再観測は、現在有効な観測または同じ対象の進行中requestがあっても新しいrequestを発行し、それ以前のrequestをsupersedeしてよい。
|
||||
|
||||
Clientは、保持する観測、進行中request、並列度、request rateへboundedな上限を設ける。上限によって新しい取得を開始できない場合、interest自体をProtocol failureとして扱わず、別のrequestの完了、容量の解放、またはinterestの変更後に再評価できる。具体的な優先順位、並行実行、prefetch範囲、fairness、cache容量、eviction algorithmはClient実装に委ねる。
|
||||
|
||||
Clientは、上位層から直接示されたinterestに加えて、観測したObjectのInterface参照やindexable child edgeから次のinterestを先行して導出してよい。WIPは全量取得、暗黙の再帰展開、または特定のprefetch範囲を要求しない。取得計画とevictionは、interestの変更や明示的な再観測がないまま同じ観測を繰り返し破棄して再取得する、自己維持的なloopを作ってはならない。
|
||||
|
||||
複数の取得requestを並行実行するClientは、各responseを元のrequestとそのeffective Worldspace viewへ対応付ける。Clientがある観測状態のownershipを後続requestへ移した場合、supersedeされたrequestのresponseでその状態を上書きしない。Overlapping observationを部分的にmergeする場合も、後続requestが所有するObjectまたはchild coverageを以前のresponseで置き換えない。Success、Protocol failure、Transport failure、またはlocal cancellationによって終了したrequestを、進行中として残してはならない。
|
||||
|
||||
`observe`または`fetch_interface`の失敗を自動的に再試行するかはClient policyに委ねるが、retry回数、間隔、並列度はboundedでなければならない。取得requestのretry policyを`call_operation`の再実行へ適用せず、OperationについてはProtocolのfailure semanticsに従う。
|
||||
|
||||
## Objectの同一性
|
||||
|
||||
`ref`は、同じ主体に公開された一つのWorldspace内で、複数の観測またはエントリが同じObjectを表すことを示すoptionalなopaque markerである。
|
||||
|
||||
同じ有効な`ref`は同じObjectを保証する。異なるまたは欠落した`ref`からObjectが異なるとは判断しない。Clientは異なるWorldspaceの`ref`を比較せず、`ref`を永続的なprimary keyまたはNavigationに使用しない。
|
||||
|
||||
Backend UIDが適している場合、Hostはそれを直接または変換して`ref`に利用できる。ただし、Clientは`ref`がbackend UIDであること、またはsessionやHost restartをまたいで安定することを仮定しない。
|
||||
|
||||
## 観測整合性
|
||||
|
||||
Clientは、Hostが提供した`ref`とvalidatorの保証範囲で、観測とOperation実行の整合性を管理する。Scopeの`ref`や対象Objectのvalidatorがない場合に、pathだけから観測時と同じObjectであると保証してはならない。Optional metadataの欠落自体は有効な公開形態であり、identity追跡不能を理由にProtocol違反としない。
|
||||
|
||||
Objectが`validator`を持つ場合、Clientは観測したpathとvalidatorを対応付ける。条件付きOperationでは両者をtargetとしてHostへ渡し、validatorの比較と実行をHost上でatomicに行わせる。ValidatorはAIやユーザーに直接管理させず、Transport BindingでもProtocol struct上のfieldとして保持する。HTTP ETag等のrepresentation metadataをWIP validatorの代用として解釈しない。
|
||||
|
||||
ClientはOperationに選択したInterface参照と、`fetch_interface`で観測したoptionalな`scope_ref`およびInterface validatorもrequestへ含める。MutableなInterfaceがvalidatorを返す場合は必須preconditionとして使用し、`InterfaceValidatorMismatch`ではInterfaceだけを再観測する。`InterfaceMismatch`ではObjectを再観測して現在のInterface集合を取得し、scopeの紐付きが変わった可能性もあるため、使用したInterface observationも無効化して必要なら再取得する。
|
||||
|
||||
Operation responseが新しいObject validatorを返した場合、Clientは対応するObject observationへ反映する。
|
||||
|
||||
## Failure handling
|
||||
|
||||
ClientはHostが返すProtocol errorの`code`で回復actionを決定し、人間向け`message`やTransport statusからcodeを推測しない。各interactionで許可されていないcode、schemaに違反するsuccess / error response、同じvalidatorに矛盾するrepresentationは`InvalidResponse`として拒否する。Validだが未対応のInterface Descriptor formatは`UnsupportedDescriptorFormat`として区別する。
|
||||
|
||||
- `NotFound`では対象Entryをstaleとして扱い、必要に応じて親を再観測する。
|
||||
- `InterfaceNotFound`では参照元Objectを再観測できる。
|
||||
- `InterfaceMismatch`では対象Objectを再観測し、使用したInterface observationも無効化して必要なら再取得する。
|
||||
- `InterfaceValidatorRequired`または`InterfaceValidatorMismatch`では対象Interfaceを再観測する。
|
||||
- `ValidatorRequired`または`ValidatorMismatch`では対象Objectを再観測する。
|
||||
|
||||
同じOperationを再試行するなら、先に新しい観測を取得しなければならない。
|
||||
|
||||
- `InvalidRequest`または`InvalidArguments`では同じrequestを変更せずに再送しない。
|
||||
- `ResourceLimitExceeded`ではlogical request shapeやobservation depth等を削減できるが、Operationを自動再実行しない。
|
||||
- `PermissionDenied`では公開済みOperationが実行拒否されたことを示し、Object自体が閲覧禁止で存在するとは推測しない。
|
||||
|
||||
`OperationOutcomeUnknown`では、Operationが未実行またはrollback済みであることが保証されない。ClientはOperationを自動再実行せず、対象Objectをstaleとして再観測するか、domain固有の照会手段を提示する。`Internal`、Transport timeout、connection lossの場合もOperationを自動再実行しない。Response不達はProtocol errorへ変換せず、Transport failureとOperation outcomeが不明な状態をClient内部で保持する。WIPはOperationをObject stateへのeffectで分類してretry可否を推測しない。
|
||||
|
||||
ClientがOperation結果の`entry`を付随的に取得する場合、その取得の成否は元のOperationの成否と分けて扱う。参照先の`observe`が失敗しても、成功済みOperationを失敗扱いしたり、そのOperationを再実行したりしてはならない。取得失敗は、その参照先への別のinteractionの失敗として提示・処理する。
|
||||
|
||||
HTTP authentication failureとWorldspace endpoint全体のaccess denialはTransport layerのfailureであり、WIPの`PermissionDenied`へ変換しない。
|
||||
|
||||
## 想定実装
|
||||
|
||||
Clientは用途に応じて複数の上位インターフェースを提供できる。
|
||||
|
||||
- GUI上のWorldspace View
|
||||
- [AI Tools](4.1-ai-tools.md)
|
||||
- PTC / REPL向けスクリプティングAPI
|
||||
|
||||
これらは同一のKnown Space、Discoverable Space、Object identity、観測整合性管理を共有してよい。
|
||||
|
||||
PTC / REPL bindingでは、Operationを通常のメソッド呼び出しへ投影してよい。
|
||||
|
||||
```python
|
||||
issue.close(reason="duplicate")
|
||||
```
|
||||
|
||||
この場合もClientがInterfaceとOperationを解決して`call_operation`を利用し、Object identityと観測整合性を管理する。AI Toolsの3操作は、そのAI向けインターフェースの契約であり、PTC / REPLの呼び出し構文を制限しない。
|
||||
Reference in New Issue
Block a user