From 1a2f98544c32d2c393de40470f4493bb37a35df6 Mon Sep 17 00:00:00 2001 From: Hare Date: Wed, 30 Sep 2026 16:41:55 +0900 Subject: [PATCH] docs: unify object observation interaction --- 2-core-model.md | 7 +- 2.1-object-tree-schema.md | 49 ++++----- 2.2-operation.md | 4 +- 3-protocol.md | 99 +++++++----------- 4-client.md | 29 +++--- 4.1-ai-tools-example.md | 4 +- draft/dynamic-worldspace-projection.md | 63 +++++------- draft/rust-api-model.md | 39 +++----- draft/typescript-api-model.md | 41 +++----- draft/unresolved-issues.md | 2 +- draft/wip-over-https.md | 133 +++++++++---------------- 11 files changed, 182 insertions(+), 288 deletions(-) diff --git a/2-core-model.md b/2-core-model.md index 4d43271..cb039e1 100644 --- a/2-core-model.md +++ b/2-core-model.md @@ -60,16 +60,15 @@ InterfaceとOperationの意味論は[2.2. Interface / Operation](2.2-operation.m ## Core interaction -Clientは、次の4操作によってWorldspaceを観測および操作する。 +Clientは、次の3操作によってWorldspaceを観測および操作する。 -- `fetch(path)` — 一つのpathで現在公開されているObjectを取得する。 -- `fetch_tree(path, depth, limit)` — 指定pathを起点にindexableな子ObjectをTreeとして取得する。 +- `observe(path, depth)` — 指定pathのObjectと、指定した深さまでのindexableな子Objectを一つの観測として取得する。`depth = 0`では対象Objectだけを取得する。 - `fetch_interface(interface)` — Interface参照から現在のInterface Descriptorとoptionalなvalidatorを取得する。 - `call_operation(target, interface, operation, arguments)` — `path`とoptionalなObject validatorを持つtarget、およびObjectが現在公開する一つのInterface observationを指定してOperationを実行する。 この節は各操作の意味だけを定める。Parameterとreturn valueの具体的なstructはProtocolで定義する。 -複数の`fetch`や`fetch_interface`は、それぞれ独立したCore interactionである。Transport Bindingは、個別に実行した場合と同じ意味を保ったまま複数のinteractionを一つのrequestへbatchしてよい。Batchingによって新しいCore interactionや暗黙の先読みを導入しない。 +複数の`observe`や`fetch_interface`は、それぞれ独立したCore interactionである。Transport Bindingは、個別に実行した場合と同じ意味を保ったまま複数のinteractionを一つのrequestへbatchしてよい。Batchingによって新しいCore interaction、subrequest間のdata dependency、または暗黙の先読みを導入しない。 ## `ref` diff --git a/2.1-object-tree-schema.md b/2.1-object-tree-schema.md index b3befba..3f0b1e5 100644 --- a/2.1-object-tree-schema.md +++ b/2.1-object-tree-schema.md @@ -88,8 +88,8 @@ Pathには空segment、`.`、`..`を含めない。Root以外のpathは末尾に 非root pathについては、最後のsegmentと取得したObjectの`name`が一致しなければならない。 ```text -fetch("/projects/example") - -> Object.name == "example" +observe("/projects/example", depth = 0) + -> ObjectObservation.object.name == "example" ``` 同じObjectが複数のpathへ配置される場合、同じ`ref`と`name`を持ち、異なる親を経由して異なるpathに現れる。Objectをrenameすると、そのObjectを参照するすべての配置とdescendantのpathが変化する。Pathは恒久的なObject identityとして使用しない。 @@ -123,7 +123,9 @@ Parent / child関係はWorldspaceにおける**所有または内包**を表す 一つのObjectが複数pathへ配置される場合、そのObjectから見えるchildrenは配置ごとに異なり得る。したがって、childrenを`ref`が示すObject identityの一部とはみなさない。 -Protocolでは`Object`自体にchildrenとpathを含めず、`fetch_tree`の`ObjectTreeNode`としてObjectとchildrenをまとめる。ValidatorはObjectに含まれる。各nodeのpathは、request pathを起点にObjectの`name`を辿って導出する。このwrapperはObjectとは別のdomain entityを導入するものではなく、Tree traversalのresponse shapeである。 +Protocolでは`Object`自体にchildrenとpathを含めず、`observe` responseの`ObjectObservation`としてObjectとoptionalなchildren observationをまとめる。ValidatorはObjectに含まれる。各nodeのpathは、request pathを起点にObjectの`name`を辿って導出する。このwrapperはObjectとは別のdomain entityを導入するものではなく、指定depthまでの観測結果を表すresponse shapeである。 + +`children` fieldが省略されているnodeではchildrenを観測していない。`children` fieldが存在する場合、そのarrayはその主体へ公開された直接のindexable childrenをすべて含み、空arrayは観測時点でindexable childが存在しなかったことを表す。 ## Objectの可視性 @@ -131,46 +133,31 @@ Hostは、主体に認識させるObjectだけでClient-facing Worldspaceを構 主体に認識させないObjectは、そのWorldspaceに存在しないものとして扱う。 -- `fetch_tree`では、そのObjectと、そのObjectだけを経由して到達するsubtreeを省略する。 +- `observe`では、そのObjectと、そのObjectだけを経由して到達するsubtreeをresponseから省略する。 - 省略されたObjectやchild数を示すredaction markerは返さない。 -- そのpathを指定した`fetch`には、Host内部での存在理由にかかわらず`NotFound`を返す。Object取得に対する`PermissionDenied`は使用しない。 -- `truncated`は、その主体へ公開されたindexable childrenについて判定する。非公開Objectを省略したことだけを理由に`true`にしない。 +- 非公開pathを起点とする`observe`には、Host内部での存在理由にかかわらず`NotFound`を返す。Object観測に対する`PermissionDenied`は使用しない。 Objectを公開しながら、特定Interfaceを集合から除外すること、公開したInterfaceから一部のOperationを除外すること、公開されたOperationの実行を認可時に拒否することはできる。Operationの可視性と`PermissionDenied`の使い分けは[2.2. Interface / Operation](2.2-operation.md)で定義する。 Objectの`description`には、その主体へ公開できる説明だけを含める。安全な説明を公開できない場合はoptionalな`description`を省略できるが、Protocolはfield-level redaction markerを定義しない。Objectの本文やdomain dataの部分的な開示は、各Operationのresult schemaとdomain semanticsで表現する。 -## `fetch` +## `observe` -`fetch(path)`は、指定されたpathで現在公開されている一つのObjectを観測する。 +`observe(path, depth)`は、指定pathのObjectと、そのObjectからindexable child edgeを指定depthまで辿った範囲を一つの観測として取得する。 ```text -fetch(path) -> Object +observe(path, depth) -> ObjectObservation ``` -返されたObjectは、Host内部のdomain entityの完全なcopyではない。そのClientへ現在公開されているname、description、Interface参照のordered set、任意の`ref`とvalidator等のprotocol projectionである。Clientは非rootのrequest pathについて、最後のsegmentとObjectの`name`が一致することを検証する。 +起点Objectをdepth `0`とする。`depth = 0`では起点Objectだけを返し、そのnodeの`children` fieldを省略する。成功responseはrequested depthまでの公開されたindexable childrenを完全に含み、requested depthより深いObjectを含めない。 -ClientはObjectがvalidatorを持つ場合、そのObjectとrequest pathを対応付けて保持し、条件付きOperationのtargetを構築できる。 +- Nodeのdepthがrequestの`depth`より小さい場合、`children` fieldを必ず含める。 +- 観測した直接のindexable childが存在しない場合、`children`は空arrayとする。 +- Nodeのdepthがrequestの`depth`と等しい場合、`children` fieldを省略する。省略はemptyを意味しない。 +- 同じparent nodeのchildrenは、互いに異なる`name`を持つ。 +- Clientはrequest pathとchildrenの`name`から各nodeのpathを導出する。 -## `fetch_tree` - -`fetch_tree(path, depth, limit)`は、指定pathを起点にindexableな子ObjectをTreeとして取得する。 - -```text -fetch_tree(path, depth, limit) -> ObjectTree -``` - -探索順序は**Breadth-First Search (BFS)**とする。 - -- `depth`は起点Objectを`0`とする最大深さ。 -- `limit`はresponse全体に含めるObject数の上限。 -- 起点Objectはlimitへ含める。 -- `depth`または`limit`によって、その主体へ公開されたindexable childを省略した場合は、responseで`truncated = true`を返す。 -- 要求範囲内でその主体へ公開されたindexable childをすべて含む場合は、`truncated = false`を返す。 - -Tree responseは各nodeにObjectを含み、Clientはrequest pathとchildrenの`name`から各Objectのpathを導出する。各ObjectはHostが発行したvalidatorを持ち得るため、Clientは導出したpathとvalidatorから条件付きOperationのtargetを構築できる。 - -Depth、limitの有効範囲、Tree node、truncationの具体的なstructはProtocolで定義する。 +各ObjectはHostが発行したvalidatorを持ち得るため、Clientは導出したpathとvalidatorから条件付きOperationのtargetを構築できる。Responseを部分的な成功として返す`limit`や`truncated`は定義しない。Requested depthまでの完全な観測をresource budget内で構築できない場合、Hostはsuccess responseの代わりに`ResourceLimitExceeded`を返す。 ## Indexable children @@ -198,6 +185,6 @@ IssueQueryResult.items: [entry] 複数のObjectやInterface Descriptorをまとめて取得する機能は、Core Model上の新しいinteractionではない。 -Transport Bindingは、個別に実行した場合と同じ意味を保つ形で、複数の`fetch`、`fetch_tree`、`fetch_interface`を一つのrequestへまとめてよい。 +Transport Bindingは、個別に実行した場合と同じ意味を保つ形で、複数の`observe`と`fetch_interface`を一つのrequestへまとめてよい。 WIPは自動的な全量取得、暗黙の再帰展開、Clientが要求していない先読みを要求しない。 diff --git a/2.2-operation.md b/2.2-operation.md index 34aeca1..a544827 100644 --- a/2.2-operation.md +++ b/2.2-operation.md @@ -87,7 +87,7 @@ Operationの存在を公開しつつ実行だけを認めない設計も可能 したがって、Hostは主体に対して次を独立に選択できる。 -- Object自体を公開せず、Objectへの`fetch`とOperation callを`NotFound`にする。 +- Object自体を公開せず、そのObjectへの`observe`とOperation callを`NotFound`にする。 - Objectを公開するが、特定Interfaceを集合から除外する。 - Objectを公開し、特定Operationを含まないInterfaceを使用する。 - Object、Interface、Operationを公開するが、そのOperationの実行を`PermissionDenied`にする。 @@ -158,7 +158,7 @@ Operation Resultには、Descriptorの`entry`型として新しいエントリ `entry`は同じWorldspace内のcanonical absolute pathである。Clientはreturn typeに従って`entry`型の位置を認識する。通常の`string`やopaqueな`json`に含まれるpathらしい文字列を、エントリとして推測してはならない。 -Clientは発見したpathを必要に応じて`fetch`または`fetch_tree`する。Operation ResultへObject公開情報やInterface Descriptorを先行同梱しない。 +Clientは発見したpathを必要な深さで`observe`する。Operation ResultへObject公開情報やInterface Descriptorを先行同梱しない。 Operationの実行対象と、結果として発見されたエントリのTree上の位置は独立している。発見されたエントリは実行対象の子である必要はなく、親、兄弟、またはWorldspace内の任意の位置にあってよい。 diff --git a/3-protocol.md b/3-protocol.md index 92ec37d..0788c77 100644 --- a/3-protocol.md +++ b/3-protocol.md @@ -164,7 +164,7 @@ Object validatorはAIやユーザーへ公開するApplication dataではない 同じObjectを複数のpathへ配置する場合、各配置は同じObjectの`name`を使用する。異なる親を経由することでpathが異なる。 -`Object`はchildrenとpathを直接持たない。これらはObject identityに固有とは限らず、Objectを観測したentryまたはTree traversalのcontextに属するため、requestまたはTree responseで表す。 +`Object`はchildrenとpathを直接持たない。これらはObject identityに固有とは限らず、Objectを観測したentryのcontextに属するため、request pathと`ObjectObservation`で表す。 Objectの意味とApplication dataとの境界は[2. Core Model](2-core-model.md)と[2.1. Object tree / Schema](2.1-object-tree-schema.md)で扱う。 @@ -378,66 +378,43 @@ Valueは、Operation declarationのTypeExprと照合して検証する。 Transport Bindingがframing、media type、authentication等を受理した後、Hostはinteraction固有のObject / Interface解決より前にlogical requestを検証する。 1. Request structとして解釈できない、required fieldがない、未知fieldがある、Path等のfield semanticsに違反する場合は`InvalidRequest`。 -2. Field長、nesting、collection件数、`fetch_tree`のdepth / limit等がHostのboundedな上限を超える場合は`ResourceLimitExceeded`。 +2. Field長、nesting、collection件数、`observe`のdepth等がHostのboundedな上限を超える場合は`ResourceLimitExceeded`。 3. 検証済みrequestについて、各interaction固有のtarget resolutionとpreconditionを評価する。 `InvalidArguments`は`call_operation` request自体がvalidであり、固定したOperation declarationに対して`arguments`が適合しない場合だけに使用する。Transport route、authentication、media type、framing等のfailureはCore interactionのProtocol failureではない。 -## `fetch` +## `observe` -一つのpathで現在公開されているObjectを取得する。 +一つのpathで現在公開されているObjectと、そのObjectから指定depthまでのindexable childrenを一つの観測として取得する。 ```rust -struct FetchRequest { - path: String, -} - -type FetchResponse = Object; -``` - -Requestの`path`はresponseに重複して含めない。Root path `/`ではObjectの`name`が空文字列でなければならず、非root pathでは最後のsegmentとObjectの`name`が一致しなければならない。Clientは一致しないresponseを`InvalidResponse`として扱う。 - -指定pathのObjectがその主体のClient-facing Worldspaceへ公開されていない場合、Host内部での存在理由にかかわらず`NotFound`を返す。`fetch`はObject取得の認可失敗として`PermissionDenied`を返さない。Objectを返すこと自体が、そのpathとObjectの公開情報を主体へ認識させるためである。 - -返されたObjectが`validator`を持つ場合、Clientはrequest pathとObjectを対応付けてcacheし、条件付きOperationの`target`を構築できる。Batch Transport Bindingも各itemのrequestとresponseを一意に対応付けなければならない。 - -## `fetch_tree` - -一つのpathを起点に、indexableなObjectをBreadth-First Searchで取得する。 - -```rust -struct FetchTreeRequest { +struct ObserveRequest { path: String, depth: u32, - limit: u32, } -struct ObjectTreeNode { +struct ObjectObservation { object: Object, - children: Vec, + children: Option>, } -struct FetchTreeResponse { - root: ObjectTreeNode, - truncated: bool, -} +type ObserveResponse = ObjectObservation; ``` -- 起点Objectはdepth `0`とする。 -- `limit`はrootを含むresponse全体のnode数に適用する。 -- Root nodeのObjectはrequest pathが指すObjectであり、Root pathが`/`でない場合は最後のsegmentとObjectの`name`が一致する。 +起点Objectをdepth `0`とする。`depth = 0`は対象Objectだけを観測する通常の形であり、root nodeの`children`を省略する。 + +- Root nodeのObjectはrequest pathが指すObjectである。Root pathが`/`の場合はObjectの`name`が空文字列でなければならず、非root pathでは最後のsegmentとObjectの`name`が一致しなければならない。 - Request pathのObjectがその主体へ公開されていない場合は`NotFound`を返す。 - 各childのpathは、parent pathへchild Objectの`name`を追加して導出する。 - 同じparent nodeのchildrenは、互いに異なる`name`を持つ。 -- `children`はWorldspace上の直接の子だけを含む。 -- `depth`または`limit`によって、その主体へ公開されたindexable childを省略した場合、`truncated = true`とする。 -- 要求範囲内でその主体へ公開されたindexable childをすべて含む場合、`truncated = false`とする。 +- Nodeのdepthがrequestの`depth`より小さい場合、`children`は必須であり、その主体へ公開された直接のindexable childrenをすべて含む。Childが存在しない場合は空listとする。 +- Nodeのdepthがrequestの`depth`と等しい場合、`children`を省略する。省略された`children`からemptyを推測してはならない。 +- Requested depthより深いnodeをresponseへ含めない。 - その主体へ公開されていないObjectはresponseへ含めず、存在や省略を示すmarkerも返さない。 -- 非公開Objectを省略したことだけを理由に`truncated = true`としてはならない。 -各nodeのObjectがvalidatorを持つため、Clientはrequest pathとObjectの`name`から各pathを導出し、Treeから発見したObjectを再度`fetch`せずに条件付きOperationのtargetを構築できる。 +Success responseはrequested depthまで完全である。Node数によるpartial success、`limit`、`truncated`は定義しない。Hostが完全なresponseをresource budget内で構築できない場合は`ResourceLimitExceeded`を返す。 -`limit`は1以上とし、`0`は`InvalidRequest`とする。Hostはdepthとlimitへ実装上の上限を設定し、有効範囲内だが上限を超えたrequestには`ResourceLimitExceeded`を返す。 +各nodeのObjectがvalidatorを持つ場合、Clientはrequest pathとchildrenの`name`から導出したpathに対応付けてcacheし、条件付きOperationの`target`を構築できる。Batch Transport Bindingも各itemのrequestとresponseを一意に対応付けなければならない。 ## `fetch_interface` @@ -595,28 +572,28 @@ enum ProtocolErrorCode { 各interactionが返してよいcodeは次に限定する。 -| Code | `fetch` | `fetch_tree` | `fetch_interface` | `call_operation` | -| --- | --- | --- | --- | --- | -| `InvalidRequest` | ✓ | ✓ | ✓ | ✓ | -| `ResourceLimitExceeded` | ✓ | ✓ | ✓ | ✓ | -| `NotFound` | ✓ | ✓ | — | ✓ | -| `InterfaceNotFound` | — | — | ✓ | — | -| `InterfaceMismatch` | — | — | — | ✓ | -| `InterfaceValidatorRequired` | — | — | — | ✓ | -| `InterfaceValidatorMismatch` | — | — | — | ✓ | -| `OperationNotFound` | — | — | — | ✓ | -| `ValidatorRequired` | — | — | — | ✓ | -| `ValidatorMismatch` | — | — | — | ✓ | -| `InvalidArguments` | — | — | — | ✓ | -| `PermissionDenied` | — | — | — | ✓ | -| `Internal` | ✓ | ✓ | ✓ | ✓ | -| `OperationOutcomeUnknown` | — | — | — | ✓ | +| Code | `observe` | `fetch_interface` | `call_operation` | +| --- | --- | --- | --- | +| `InvalidRequest` | ✓ | ✓ | ✓ | +| `ResourceLimitExceeded` | ✓ | ✓ | ✓ | +| `NotFound` | ✓ | — | ✓ | +| `InterfaceNotFound` | — | ✓ | — | +| `InterfaceMismatch` | — | — | ✓ | +| `InterfaceValidatorRequired` | — | — | ✓ | +| `InterfaceValidatorMismatch` | — | — | ✓ | +| `OperationNotFound` | — | — | ✓ | +| `ValidatorRequired` | — | — | ✓ | +| `ValidatorMismatch` | — | — | ✓ | +| `InvalidArguments` | — | — | ✓ | +| `PermissionDenied` | — | — | ✓ | +| `Internal` | ✓ | ✓ | ✓ | +| `OperationOutcomeUnknown` | — | — | ✓ | Hostがinteractionに許可されていないcodeを返した場合、Clientはそのerror responseを`InvalidResponse`として扱う。 Validatorおよび観測関連errorの回復対象は次のとおりである。 -- `NotFound`では、Clientは対象Entryをstaleとして扱い、必要に応じて親Treeを再観測する。 +- `NotFound`では、Clientは対象Entryをstaleとして扱い、必要に応じて親を再観測する。 - `InterfaceNotFound`では、ClientはそのInterface observationを使用せず、参照元Objectを再観測できる。 - `ValidatorRequired`または`ValidatorMismatch`では、Clientは対象Objectを再観測する。 - `InterfaceMismatch`では、Clientは対象Objectを再観測し、現在公開されているInterface参照の集合を取得する。 @@ -625,13 +602,13 @@ Validatorおよび観測関連errorの回復対象は次のとおりである。 同じOperationを再試行するなら、先に新しい観測を取得しなければならない。 - `InvalidRequest`または`InvalidArguments`では、Clientは同じrequestを変更せずに再送しない。 -- `ResourceLimitExceeded`では、Clientはrequest size、depth、limit等を削減できるが、`call_operation`を自動再実行しない。 +- `ResourceLimitExceeded`では、Clientはrequest sizeやobservation depth等を削減できるが、`call_operation`を自動再実行しない。 `call_operation`が`OperationOutcomeUnknown`以外のProtocol failureを返した場合、HostはOperationのeffectがcommitされていないことを保証する。`OperationOutcomeUnknown`は、HostがOperationの未実行またはrollbackを保証できず、validなsuccess responseも返せないことを示す。Clientは対象Objectをstaleとして扱い、Operationを自動再実行せず、再観測またはdomain固有の照会手段を利用者へ提示する。 `Internal`はHost内部のfailureであり、`call_operation`ではeffectがcommitされていないと保証できる場合だけ返す。Clientは`Internal`を理由にOperationを自動再実行しない。Transport timeoutやconnection lossでresponse自体を受け取れない場合もOperation outcomeは不明になり得るが、それはProtocol failureではなくTransport failureとして扱う。 -Objectを主体へ公開しない場合、HostはそのObjectをClient-facing Worldspaceに存在しないものとして扱い、`fetch`、`fetch_tree`、`call_operation`へ`NotFound`を返す。Objectの存在を秘匿する目的で`PermissionDenied`を返してはならない。 +Objectを主体へ公開しない場合、HostはそのObjectをClient-facing Worldspaceに存在しないものとして扱い、`observe`と`call_operation`へ`NotFound`を返す。Objectの存在を秘匿する目的で`PermissionDenied`を返してはならない。 `PermissionDenied`は、現在公開されているInterfaceに宣言されたOperationについて、その存在を公開しつつ実行を認めない場合に使用する。Operation自体をInterfaceから除外している場合は`OperationNotFound`を返す。Operation argumentが参照するdomain resourceの不存在やbusiness rule failureを、対象Objectの`NotFound`へ変換しない。 @@ -651,10 +628,10 @@ HostとClientは、untrusted inputによるresource exhaustionを避けるため - Type declaration、Operation、parameter、field、caseの数。 - TypeExprとValueのnesting depth。 - Record field数とList要素数。 -- `fetch_tree`のdepthとlimit。 +- `observe`のdepthとresponse node数。 - Protocol error messageの長さ。 -各実装はこれらにboundedな上限を設定する。上限を超えたrequestは、interaction固有のtarget resolutionまたはOperation dispatchより前に`ResourceLimitExceeded`として拒否する。Hostがread-only responseを構築する途中で上限超過を検出した場合も、success responseの代わりに`ResourceLimitExceeded`を返してよい。 +各実装はこれらにboundedな上限を設定する。Request fieldだけで判定できる上限違反は、interaction固有のtarget resolutionまたはOperation dispatchより前に`ResourceLimitExceeded`として拒否する。Hostがread-only responseを構築する途中でresponse node数やbyte数等の上限超過を検出した場合も、success responseの代わりに`ResourceLimitExceeded`を返してよい。 `call_operation`では、dispatch後にresult size、encoding、backend budget等の問題を検出しても、effectがcommitされていないと保証できる場合だけ`ResourceLimitExceeded`または`Internal`を返す。未実行またはrollbackを保証できない場合は`OperationOutcomeUnknown`とする。Client側のresponse byte limit超過やresponse不達はProtocol failureへ変換せず、Transport failureとして扱う。現在のProtocolではlimit negotiationを定義しない。 @@ -662,7 +639,7 @@ HostとClientは、untrusted inputによるresource exhaustionを避けるため BatchはCore interactionではなくTransport Bindingのoptimizationである。 -Transport Bindingは、複数の`FetchRequest`、`FetchTreeRequest`、`FetchInterfaceRequest`を一つのphysical requestへまとめてよい。それぞれのlogical requestは独立して成功または失敗し、個別に実行した場合と同じ意味を持たなければならない。 +Transport Bindingは、複数の`ObserveRequest`と`FetchInterfaceRequest`を一つのphysical requestへまとめてよい。それぞれのlogical requestは独立して成功または失敗し、個別に実行した場合と同じ意味を持たなければならない。Subrequest間で先行resultを後続requestのfieldとして参照してはならない。 `call_operation`は副作用、順序、部分的成功の意味が不明確になるため、Coreの標準batch対象にしない。 diff --git a/4-client.md b/4-client.md index 233d637..e0ea528 100644 --- a/4-client.md +++ b/4-client.md @@ -14,8 +14,8 @@ Known SpaceとDiscoverable SpaceはClientが過去の観測から構築したcac 次のような経路で得られたエントリをKnown Spaceへ追加できる。 -- `fetch`または`fetch_tree`で取得したエントリ -- Operation結果の`entry`型pathを`fetch`して取得したエントリ +- `observe`で取得したエントリ +- Operation結果の`entry`型pathを`depth = 0`で`observe`して取得したエントリ Operationを通して発見されたpathは、必ずしもKnown Spaceへ追加する必要はない。Clientは現在の結果として一時的に扱うことも、取得後に必要なエントリだけを選択して保持することもできる。 @@ -42,7 +42,7 @@ struct CachedObject { struct CachedEntry { object: InternalObjectKey, - children: Vec, + children: Option>, } ``` @@ -50,7 +50,8 @@ struct CachedEntry { - 観測したObjectが`ref`を持ち、同じWorldspaceのObject storeに同じ`ref`が存在する場合、既存のCachedObjectを更新してEntryから参照する。 - `ref`がない場合、ClientはEntryごとにInternalObjectKeyを発行し、異なるpath間でObjectをdeduplicateしない。 -- Entry Treeはpathと親子関係を保持し、Object storeはObjectの現在状態を保持する。 +- Entry Treeはpathと親子関係を保持し、Object storeはObjectの現在状態を保持する。`CachedEntry.children = None`はchildren未観測、`Some([])`は観測済みでemptyであることを表す。 +- `children`が存在するresponse nodeをmergeするときは、そのentryで観測済みのdirect child edge一覧をresponseの完全な一覧で置き換える。`children`が省略されたnodeは構造について新しい情報を持たないため、既存の観測済み一覧を`None`へ戻したり、既存edgeを削除したりしない。 - 同じObjectを複数のEntryが参照しても、Object stateをEntryごとに複製しない。 Objectの`interfaces`はmembershipをsetとして扱い、同じ参照の重複を`InvalidResponse`として拒否する。ClientはHostの立項順をCachedObjectへ保持し、InterfaceやOperationの表示順に使用してよい。 @@ -82,17 +83,17 @@ ClientはObjectの`interfaces`とcacheを比較し、未知のInterfaceだけを ## Discoverable Space -Clientは、Hostから`fetch_tree`で取得したindexableなエントリツリーをDiscoverable Spaceとして保持する。Discoverable Spaceとして扱う間、Clientはそのtreeの構造を保持する必要がある。 +Clientは、Hostから`observe`で取得したindexableなエントリツリーをDiscoverable Spaceとして保持する。Discoverable Spaceとして扱う間、Clientはその観測済みtreeの構造を保持する必要がある。 Discoverable SpaceはKnown Spaceの部分集合であり、AI向け`discover`などの機械的探索に利用する。Worldspace rootまたはClientが選択した起点からindexable edgeで到達できる、materialize済みの範囲によって構成される。 -Clientが`fetch_tree`を再実行した結果、以前存在した親のindexable edgeが返されなくなった場合、その子エントリをDiscoverable Spaceから除外する。その結果、保持しているどの起点からも到達不能になったsubtreeは、その場で破棄できる。ただし、別の経路から到達できるエントリ、Clientがpinしたエントリ、実行中のOperationが参照しているエントリは引き続き保持してよい。 +Clientが`observe`結果をmergeし、`children`が存在するparent nodeから以前のindexable edgeが返されなくなった場合、その子エントリをDiscoverable Spaceから除外する。その結果、保持しているどの起点からも到達不能になったsubtreeは、その場で破棄できる。ただし、別の経路から到達できるエントリ、Clientがpinしたエントリ、実行中のOperationが参照しているエントリは引き続き保持してよい。`children`が省略されたnodeはedge削除の根拠にしない。 -Operationを通して発見されたpathは、それだけではDiscoverable Spaceへ追加しない。そのエントリを起点として`fetch_tree`を取得した場合に、そのindexableな範囲をDiscoverable Spaceへ追加できる。 +Operationを通して発見されたpathは、それだけではDiscoverable Spaceへ追加しない。そのエントリを起点として`depth > 0`で`observe`した場合に、そのindexableな範囲をDiscoverable Spaceへ追加できる。 ## 一時的な発見とpin -Clientは、Operation Resultの`entry`型として発見したpathを現在の結果として一時的に扱える。標準的なClientはOperationのreturn typeからentry pathを抽出して重複を除去し、Known Spaceと比較して必要なpathだけを取得する。複数の`fetch`はTransport Bindingが提供するbatchを利用してまとめてよい。 +Clientは、Operation Resultの`entry`型として発見したpathを現在の結果として一時的に扱える。標準的なClientはOperationのreturn typeからentry pathを抽出して重複を除去し、Known Spaceと比較して必要なpathだけを`depth = 0`で観測する。複数の`observe`はTransport Bindingが提供するbatchを利用してまとめてよい。 一時的に取得したエントリは、結果の利用が終わった時点で破棄してよい。 @@ -100,13 +101,11 @@ Clientは、Operation Resultの`entry`型として発見したpathを現在の 単純なClientは発見したエントリをすべて保持してもよいが、WIPはそれを必須としない。具体的な容量制限やeviction algorithmはClient実装に委ねる。 -## Tree取得 +## Objectとchildrenの観測 -Clientは、機械的にエントリを探索する必要がある場合、個別の`fetch`を多数発行するのではなく`fetch_tree`を利用する。 +Clientは`observe(path, depth)`を使い、対象Objectだけが必要なら`depth = 0`、indexableな配下も必要なら正のdepthを指定する。一つのinteractionでrequested depthまでを取得するため、Clientが各nodeについてdata-dependentな取得requestを逐次発行する必要はない。 -`fetch_tree`では起点path、探索深度`depth`、返却エントリ総数の上限`limit`を指定する。Hostはindex edgeを幅優先探索してTreeを返す。Tree nodeはpathを重複して持たず、Clientは起点pathと各Objectの`name`からchild pathを導出する。 - -レスポンスが`truncated`である場合、Clientは取得したTreeが完全ではないことを保持し、完全な空間として扱ってはならない。 +Response nodeの`children`が省略されている場合、そのnodeのchildrenは未観測であり、空であるとは扱わない。`children`が存在する場合、その一覧は完全であり、空arrayならindexable childが存在しない。Clientは起点pathと各Objectの`name`からchild pathを導出する。 件数の非常に多いCollectionの個々の要素は、通常indexableな子エントリとして露出しない。個別要素はCollection Objectの`query`や`list`等のOperationを通して発見することを想定する。 @@ -132,7 +131,7 @@ Operation responseが新しいObject validatorを返した場合、Clientは対 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として扱い、必要に応じて親Treeを再観測する。 +- `NotFound`では対象Entryをstaleとして扱い、必要に応じて親を再観測する。 - `InterfaceNotFound`では参照元Objectを再観測できる。 - `InterfaceMismatch`では対象Objectを再観測する。 - `InterfaceValidatorRequired`または`InterfaceValidatorMismatch`では対象Interfaceを再観測する。 @@ -141,7 +140,7 @@ ClientはHostが返すProtocol errorの`code`で回復actionを決定し、人 同じOperationを再試行するなら、先に新しい観測を取得しなければならない。 - `InvalidRequest`または`InvalidArguments`では同じrequestを変更せずに再送しない。 -- `ResourceLimitExceeded`ではrequest size、depth、limit等を削減できるが、Operationを自動再実行しない。 +- `ResourceLimitExceeded`ではrequest sizeやobservation depth等を削減できるが、Operationを自動再実行しない。 - `PermissionDenied`では公開済みOperationが実行拒否されたことを示し、Object自体が閲覧禁止で存在するとは推測しない。 `OperationOutcomeUnknown`では、Operationが未実行またはrollback済みであることが保証されない。ClientはOperationを自動再実行せず、対象Objectをstaleとして再観測するか、domain固有の照会手段を提示する。`Internal`、Transport timeout、connection lossの場合も、Effect annotationがない現在のProtocolではOperationを自動再実行しない。Response不達はProtocol errorへ変換せず、Transport failureとOperation outcomeが不明な状態をClient内部で保持する。 diff --git a/4.1-ai-tools-example.md b/4.1-ai-tools-example.md index f4060e6..2f28edb 100644 --- a/4.1-ai-tools-example.md +++ b/4.1-ai-tools-example.md @@ -10,7 +10,7 @@ AI用Toolsは、WIP ClientがAIへ提供する想定インターフェースで `discover(scope, query)` は、Clientが保持するDiscoverable Spaceから目的に関連するエントリを探す。 -検索対象は、Hostから`fetch_tree`によって取得されたindexableなエントリ公開情報に限定する。Operationによって新たに発見されたentry pathは、一時的な結果として扱うか、取得してKnown Spaceへ保持できるが、それだけでは`discover`の検索対象にはならない。 +検索対象は、Hostから`observe`によって取得されたindexableなエントリ公開情報に限定する。Operationによって新たに発見されたentry pathは、一時的な結果として扱うか、観測してKnown Spaceへ保持できるが、それだけでは`discover`の検索対象にはならない。 `discover`はドメインデータを検索する操作ではない。Issue本文やRAG corpusなどを検索する場合は、その能力を持つObjectのOperationを`invoke`する。 @@ -51,7 +51,7 @@ AIが新しいエントリを知る経路は複数ある。 - Known Space上の既知エントリを辿る。 - Operation Resultの`entry`型としてpathを受け取る。 -ClientはOperation Resultからentry pathを抽出し、必要なpathを`fetch`または`fetch_tree`する。新たに取得したエントリの保持、Treeへの統合、indexableな範囲の管理はClientの責務とし、このページではAI向けToolの意味論だけを扱う。 +ClientはOperation Resultからentry pathを抽出し、必要なdepthでそのpathを`observe`する。新たに取得したエントリの保持、Treeへの統合、indexableな範囲の管理はClientの責務とし、このページではAI向けToolの意味論だけを扱う。 ## ドメイン検索 diff --git a/draft/dynamic-worldspace-projection.md b/draft/dynamic-worldspace-projection.md index f0cdaec..8761bf8 100644 --- a/draft/dynamic-worldspace-projection.md +++ b/draft/dynamic-worldspace-projection.md @@ -35,7 +35,7 @@ Projectionは、少なくとも次を決定する。 - そのpathのObjectを現在の主体へ公開するか。 - 公開する`name`、optionalな`description`、`ref`、`validator`。 - Objectの`interfaces` fieldへ設定するInterface参照のordered set。 -- `fetch_tree`から列挙可能なindexable children。 +- `observe`から列挙可能なindexable children。 - Operation実行時に現在のProjected Objectへ作用するために、Host内部で何を再解決または確立する必要があるか。 ### Host Runtime @@ -57,34 +57,25 @@ HostがOperationを実装するために使用するRust struct、TypeScript obj ## 運用モデル -### `fetch` +### `observe` -`fetch(path)`では、Hostは概念的に次を行う。 +`observe(path, depth)`では、Hostは概念的に次を行う。 1. Requestの主体とpathをProjection Providerへ渡す。 2. Providerが現在のbackend stateから、そのpathで公開するProjected ObjectのProjection Resolutionを生成する。 3. 非公開または存在しない場合は`NotFound`とする。 4. 公開する場合は、現在のObject metadata、Interface参照のordered set、optionalな`ref`と`validator`を生成する。 -5. Protocol `Object`を返す。 +5. Nodeのdepthがrequested depthより小さい場合、その主体へ公開するdirect indexable childrenをclean exhaustionまで列挙し、各childについて同じ処理を再帰的に行う。 +6. Nodeがrequested depthに達した場合はchildrenを観測せず、responseの`children` fieldを省略する。 +7. Requested depthまで完全な`ObjectObservation`を返す。 -この処理のために、Hostが以前の`fetch`で生成したObject instanceを保持している必要はない。内部cacheを利用してもよいが、cacheの有無によってProtocol semanticsを変えてはならない。 +ProviderはWorldspace全体をmaterializeせず、現在処理しているparentのdirect childrenを遅延して発見できる必要がある。Childrenをstream、iterator、cursor等のHost内部表現で生成してよいが、一つのparentについて成功するには公開されたindexable childrenをすべて調べ終えなければならない。 -### `fetch_tree` +Backend failure、cancellation、またはresource budget超過をclean exhaustionとして扱わない。Requested depthまでの完全なresponseを構築できない場合、Host Runtimeは部分的なsuccess responseを返さず、対応するfailureを返す。 -`fetch_tree(path, depth, limit)`では、Host RuntimeがProjection Providerを通して起点Objectを解決し、indexable childrenをBreadth-First Searchで列挙する。 +各childについて現在のObject projectionを構築し、そのcanonical pathを後の`observe`または`call_operation`で現在のProjected Objectとして再解決できなければならない。以前観測したbackend entityやHost内部instanceを再現することは要求しない。 -ProviderはWorldspace全体をmaterializeせず、要求されたparentのdirect childrenだけを遅延して発見できる必要がある。Host RuntimeはProviderと協調し、Protocolの`depth`、`limit`、visibility、resource limitを適用する。 - -Providerがchildrenとして返す内部表現は未決定である。少なくとも、各childについて現在のObject projectionを構築し、そのcanonical pathを後の`fetch`または`call_operation`で現在のProjected Objectとして再解決できなければならない。以前観測したbackend entityやHost内部instanceを再現することは要求しない。 - -Lazyなchild discoveryは、認可filter後の公開childrenについて、少なくとも次を区別できなければならない。 - -- 要求範囲のchildrenをすべて調べ終えたclean exhaustion。 -- `depth`または`limit`によって一つ以上の公開されたindexable childを省略することになる状態。 -- Backend failure。 -- Cancellationまたはrequestのresource budget超過。 - -これによりHostは`truncated`を正確に設定する。`limit`件を返しただけでは追加childの存在を仮定せず、ちょうど全件を返した場合と省略が発生した場合を区別する。Depth境界でも、公開されたindexable childの有無をboundedに判定できる必要がある。Backend failure、cancellation、resource budget超過をclean exhaustionまたは`truncated`へ変換しない。Streaming、pagination、backpressureの具体形は決定しない。 +この処理のために、Hostが以前の`observe`で生成したObject instanceを保持している必要はない。内部cacheを利用してもよいが、cacheの有無によってProtocol semanticsを変えてはならない。 ### `fetch_interface` @@ -108,7 +99,7 @@ ProjectionがObjectへ割り当てた各Interface参照は、同じ主体から Step 3から8までの間にObject、Interface、Descriptor、Operation implementation、backend対象の対応が変化し得る実装は、この手順を満たさない。Projectionは、Host RuntimeとProviderがこのatomicityを実現するために必要なstable handle、transaction、conditional operation、lock等を使用できるようにしなければならない。 -過去の`fetch`で作成したHost内部Object instanceの存在を前提にしてはならない。Clientから届くprotocol-level Targetはpathとoptionalなvalidatorであり、Hostはcall時の現在状態からObject implementationを解決する。Validatorを省略したcallを現在のOperationが許可する場合は、過去に観測したObjectではなく、実行時にpathが指す現在のObjectへ無条件に実行する。 +過去の`observe`で作成したHost内部Object instanceの存在を前提にしてはならない。Clientから届くprotocol-level Targetはpathとoptionalなvalidatorであり、Hostはcall時の現在状態からObject implementationを解決する。Validatorを省略したcallを現在のOperationが許可する場合は、過去に観測したObjectではなく、実行時にpathが指す現在のObjectへ無条件に実行する。 Validatorを指定した場合は、Clientが観測したObject identityおよび保護対象状態と実行対象を照合する。Path、`ref`、以前のProjection Resolution、cacheされたHost内部instanceのいずれも、単独ではProtocol上の永続的なObject identityとして扱わない。 @@ -116,8 +107,8 @@ Validatorを指定した場合は、Clientが観測したObject identityおよ Filesystemを`/files`以下へ投影する場合、Hostが全file / directoryに対応するObject instanceを作成する必要はない。 -- `fetch("/files/a.txt")`では、pathをfilesystem entryへ解決し、stat等からObject projectionを構築する。 -- `fetch_tree("/files", ...)`では、directory listingから要求範囲のchildrenだけを列挙する。 +- `observe("/files/a.txt", depth = 0)`では、pathをfilesystem entryへ解決し、stat等からObject projectionを構築する。 +- `observe("/files", depth = 1)`では、directory listingから直接のindexable childrenをすべて列挙する。 - Regular file、directory、symlink等に応じてInterface参照の集合を選択できる。 - 主体の権限に応じてObjectを非公開にしたり、read-only、writable等のcapability Interfaceを集合へ追加または除外できる。 - File Operationでは、call時にpathを現在のfilesystem entryへ解決し、Rust struct、TypeScript object、file descriptor等を使ってOperationを実装できる。 @@ -131,7 +122,7 @@ Filesystemを`/files`以下へ投影する場合、Hostが全file / directoryに - Object集合を事前に列挙または常駐させなくてもよい。 - Backend dataからrequest時にObjectを生成できる。 - 大規模または無限に近いlogical spaceを、要求範囲だけ投影できる。 -- `fetch_tree`でindexableでないObjectも、既知のpathを`fetch`したときに直接解決できる。 +- Tree上でindexableでないObjectも、既知のpathを`depth = 0`で`observe`したときに直接解決できる。 - Operation resultの`Entry`等で新たに得たpathを、事前のObject登録なしに解決できる。 - 静的Objectも同じmodelで表現できる。 @@ -140,8 +131,8 @@ Filesystemを`/files`以下へ投影する場合、Hostが全file / directoryに - Rootと非rootに対する`name`規則を守る。 - 同じparentの公開childrenに重複する`name`を生成しない。 - Backend側の名前をそのままWIPのUnicode nameとして表現できない場合は、deterministicかつcanonicalで、同じparent内で衝突しないmappingを定義するか、そのentryを公開対象から除外する。 -- Mappingしたnameは、親全体の無制限列挙を前提にせず、direct `fetch`とOperation dispatchで同じchildへboundedに解決できなければならない。Encoding自体が可逆である必要はなく、boundedなbackend indexを利用してよい。 -- Name mappingはchild enumeration、direct `fetch`、`call_operation`で一貫させる。 +- Mappingしたnameは、親全体の無制限列挙を前提にせず、`depth = 0`の`observe`とOperation dispatchで同じchildへboundedに解決できなければならない。Encoding自体が可逆である必要はなく、boundedなbackend indexを利用してよい。 +- Name mappingはchild enumeration、`observe`、`call_operation`で一貫させる。 - Objectの`interfaces`を重複のないordered setとして生成し、各参照を取得可能で有効なInterface Descriptorへ解決する。 - ProviderやOperation implementationの出力を信頼せず、Host RuntimeがProtocol boundaryで検証できる。 - Invalidなbackend dataを、Protocol上有効に見える別のObjectへ暗黙に衝突させない。 @@ -164,15 +155,15 @@ Filesystemを`/files`以下へ投影する場合、Hostが全file / directoryに - Objectの`interfaces`に含まれる各Descriptorは、その主体から取得可能でなければならない。 - Interface参照からDescriptorを解決することと、そのInterfaceを実装するHost codeを区別する。 -### `fetch`、`fetch_tree`、`call_operation`で一貫すること +### `observe`と`call_operation`で一貫すること -- 同じ時点と主体について、単体取得とTree列挙が矛盾したObject metadataを生成しない。 +- 同じ時点と主体について、異なるdepthの観測が矛盾したObject metadataを生成しない。 - 同じ`ref`を持つObjectを複数pathへ投影する場合も、一つの共有された現在状態として扱い、path固有の`name`、`description`、Interface集合を同時に返さない。 - 同じ`ref`と同じvalidator valueを持つObject projectionは、validatorが存在する場合、`name`、`description`、`interfaces`を含む全representationを一致させる。 - 同じ`ref`でvalidatorが異なる場合は同一Objectの異なる観測状態であり、別Objectとして扱わない。 - Validatorが存在しないObjectでは同validatorによるrepresentation equality checkを行えないため、Clientが最後に成功した観測を現在状態として扱えるようにする。 - 同じ`ref`を持つObjectの公開representationが変化する場合は、validatorが存在するなら以前と同じvalidatorのまま異なるrepresentationを返さない。 -- `fetch_tree`で得たpathを`fetch`した場合に、backend stateが変化していなければ同じObjectとして解釈できる。 +- 深い`observe`で得たpathを`depth = 0`で再観測した場合に、backend stateが変化していなければ同じObjectとして解釈できる。 - Operation call時には、その時点でpathが指す現在のProjected ObjectとInterface集合を再解決し、Clientが指定した参照のmembershipとvalidatorを確認する。 - 非公開Object、非公開Operation、公開済みだが実行拒否されたOperationをProtocolで定めたerrorへ一貫して対応付ける。 @@ -207,14 +198,14 @@ Host APIは、backend transaction、lock、revision付きconditional update、fi ### 認可をrequest時に評価できること - Projectionは主体に基づいてObject visibilityと、Objectの`interfaces`へ含める参照の集合を決定できる。 -- 非公開ObjectとそのObjectだけを経由するsubtreeを`fetch_tree`から省略し、存在や省略数を示すmarkerを生成しない。 -- 非公開Objectの省略だけを理由に`fetch_tree.truncated`を`true`にせず、その主体へ公開されたindexable childrenについて判定する。 +- 非公開ObjectとそのObjectだけを経由するsubtreeを`observe` responseから省略し、存在や省略数を示すmarkerを生成しない。 +- Requested depthより浅いnodeでは、その主体へ公開されたindexable childrenを完全に返す。 - Operation implementationまたはその前段で、call時のauthorizationを再評価できる。 -- 以前の`fetch`時に許可されていたことだけを根拠にOperationを実行しない。 +- 以前の`observe`時に許可されていたことだけを根拠にOperationを実行しない。 - 非公開Objectの存在や非公開Operationを内部error、log、timing等から不用意に漏らさない実装が可能である。 - Operation resultへ`Entry` pathを含める場合もObject visibilityを迂回せず、result生成時点でその主体に認識させてよいpathだけを返す。この規則はRecord、List、Union等へnestedしたすべての`Entry`位置へ再帰的に適用する。 - `Entry` argumentや既知pathの所持をauthorizationの証明として扱わず、参照先へ作用するOperationは現在の主体と状態に基づいて認可する。 -- Result取得後のstateまたは権限変更により、その`Entry`への後続`fetch`が`NotFound`になることは許容する。 +- Result取得後のstateまたは権限変更により、その`Entry`への後続`observe`が`NotFound`になることは許容する。 ### Backend固有のidentityを強制しないこと @@ -229,12 +220,12 @@ Host APIは、backend transaction、lock、revision付きconditional update、fi ### Resource limitとcancellationを適用できること - Child enumeration、backend lookup、descriptor生成、Value変換へboundedなresource limitを適用できる。 -- `fetch_tree`の`depth`と`limit`をProvider側の無制限列挙へ変換しない。 +- `observe`のdepthをProvider側の無制限な再帰列挙へ変換せず、request全体へboundedなresource budgetを適用する。 - Client disconnect、timeout、Host shutdown等に応じてbackend処理へcancellationを伝播できる。 - `call_operation`をdispatchする前にresource limitへ達した場合は`ResourceLimitExceeded`として拒否し、Operationを実行しない。 - Dispatch後のcancellation、timeout、implementation failure、result encoding failureについて、Operationが未実行またはrollback済みであると保証できる場合だけ`Internal`または`ResourceLimitExceeded`を返す。保証できない場合は`OperationOutcomeUnknown`を返す。 - Side effectを持つOperationでは、cancellationやtimeoutを未実行またはrollback済みの証明として扱わず、Host RuntimeもClientも実行結果が不明なcallを自動retryしない。 -- Partial backend failureをProtocol上の成功Treeへ黙って変換しない。 +- Partial backend failureをProtocol上の成功したObject observationへ黙って変換しない。 ### RustとTypeScriptで同じsemanticsを表現できること @@ -301,7 +292,7 @@ Composition後も、同じ主体へ公開されたWorldspace全体で`ref`とInt 7. 固定pathの静的service endpointを、動的modelの特殊ケースとして公開する。 8. 複数Providerを一つのWorldspaceへ合成し、Provider-localなidentityの衝突を防ぐ。 9. Backend entityを持たないvirtual Objectと、複数entityを集約するObjectへOperation implementationを適用する。 -10. `fetch_tree`で結果がちょうど`limit`件の場合、追加childの有無とbackend failureを区別して`truncated`を決める。 +10. 深い`observe`がresource budgetを超える場合、部分的なresponseを返さず`ResourceLimitExceeded`にする。 11. Operation resultのnestedな`Entry`から、現在の主体へ非公開のObject pathが漏れないようにする。 ## 未決定事項 @@ -311,7 +302,7 @@ Composition後も、同じ主体へ公開されたWorldspace全体で`ref`とInt - Path resolutionとchild discoveryの具体的な戻り値。 - Projected Objectがzero / one / multiple backend entityから導出される場合のHost内部Object implementation表現。 - Child discoveryがObject projectionを返すか、遅延解決用の内部keyを返すか。 -- Clean exhaustion、additional child、failure、cancellationをHostへ伝え、`truncated`を正確に決める内部contract。 +- Clean exhaustion、failure、cancellationを区別し、requested depthまで完全な観測だけをsuccessとして返せる内部contract。 - Rust structやTypeScript objectを、Interface DeclarationおよびOperation implementationへ接続する言語別API。 - DynamicなProjected Object implementationをProviderから返すときのgeneric、type erasure、runtime representation。 - Interface DeclarationとOperation implementationを同じAPIにするか分離するか。 diff --git a/draft/rust-api-model.md b/draft/rust-api-model.md index 50b8098..07342df 100644 --- a/draft/rust-api-model.md +++ b/draft/rust-api-model.md @@ -17,7 +17,7 @@ Rust APIでは、次のmodelを自然に表現できるようにする。 3. 同じstructが、必要に応じて公開する0個以上のInterface traitを実装する。 4. Objectを返す時点で、公開するInterfaceのordered setを明示的に選択する。 5. Trait declarationからInterface Descriptor、Value codec、validation、Operation dispatchに必要なcodeを生成する。 -6. Struct instanceをWorldspace全体について常駐させず、`fetch`、`fetch_tree`、`call_operation`の解決時にdata-drivenに生成できる。 +6. Struct instanceをWorldspace全体について常駐させず、`observe`と`call_operation`の解決時にdata-drivenに生成できる。 このmodelでは、Protocol上のObjectとInterfaceの関連付けは`Object.interfaces`だけで表す。Operation implementationへ到達するためのRust内部codeはSDK / Host Runtimeの実装詳細であり、新しいProtocol conceptを導入しない。 @@ -181,7 +181,7 @@ Object { `selected_interface_references`は、Hostが各generated Interface Definitionを登録または公開するときに割り当てるopaque参照を、publication APIへの追加順で並べたものである。同じ参照の重複は拒否する。Macroが特定のwire参照文字列をcompile timeに固定することは要求しない。 -`fetch`と`fetch_tree`はDescriptor自体をObjectへ埋め込まず、このInterface参照のordered setだけを返す。Clientが各参照を`fetch_interface`したとき、Host Runtimeはtrait declarationから生成されたDescriptorと、存在する場合はInterface validatorを返す。同じ参照とvalidatorの組のDescriptorはHost上で共有およびcacheできるため、Object instanceごとにDescriptorを再生成または再送する必要はない。 +`observe`はDescriptor自体をObjectへ埋め込まず、このInterface参照のordered setだけを返す。Clientが各参照を`fetch_interface`したとき、Host Runtimeはtrait declarationから生成されたDescriptorと、存在する場合はInterface validatorを返す。同じ参照とvalidatorの組のDescriptorはHost上で共有およびcacheできるため、Object instanceごとにDescriptorを再生成または再送する必要はない。 ## Macroが生成する責務 @@ -235,7 +235,7 @@ Rust SDKは、integerのProtocol相互運用範囲、finite number、unknown fie ## Dynamic Worldspaceでのlifecycle -### `fetch` +### `observe` Projection implementationはrequest時にbackend dataを解決し、struct instanceを生成する。 @@ -257,9 +257,7 @@ async fn resolve_file(path: &WipPath) -> Result { Host Runtimeは`PublishedObject`からProtocol Objectを返す。Response生成後にこの`File` instanceを破棄してよく、Worldspace内の全fileに対応するinstanceを保持しない。 -### `fetch_tree` - -Directory listingで発見した各entryについて、その時点のstruct instanceを生成して公開できる。ただし、Providerがdirectory全体を先に収集してから`Vec`として返すことを要求しない。Host Runtimeの`depth`、`limit`、resource budgetに従って、direct childrenをlazyかつboundedに発見できなければならない。 +Requested depthが正の場合、Directory listingで発見した各entryについて、その時点のstruct instanceを生成して公開できる。Providerがdirectory全体を先に収集してから`Vec`として返すことは要求しないが、一つのparentのobservationを成功させるには公開されたindexable childrenをclean exhaustionまで列挙しなければならない。 ```rust let mut entries = filesystem.discover_children(path, budget).await?; @@ -272,28 +270,19 @@ while let Some(entry) = entries.next().await? { continue; }; - traversal.accept(child)?; - - if traversal.has_enough_evidence_to_finish() { - break; - } + observation.push_child(child)?; } - -let completion = entries.completion(); ``` -`discover_children`、`budget`、`traversal`、`completion`はconceptualであり、具体APIではない。必要なsemanticsは次である。 +`discover_children`、`budget`、`observation`はconceptualであり、具体APIではない。必要なsemanticsは次である。 - 各childを現在の主体についてprojectし、非公開Objectとそのsubtreeを返さない。 -- 非公開childをtraversal count、`limit`、`truncated`判定へ含めない。 -- Clean exhaustionと、追加の公開childが存在する状態を区別する。 -- 結果がちょうど`limit`件の場合も、追加childの有無を根拠なく仮定しない。 -- Depth境界で公開されたindexable childが省略されるか判定できる。 -- Backend failure、cancellation、resource budget超過をclean exhaustionとして扱わない。 -- Host RuntimeがProtocolの`truncated`を正確に設定できる情報を提供する。 +- 公開されたindexable childrenをすべて列挙し、clean exhaustionで終了する。 +- Backend failure、cancellation、resource budget超過をclean exhaustionとして扱わず、部分的なsuccess responseを返さない。 +- Requested depthに達したnodeではchild discoveryを行わず、`children`を未観測として省略する。 - 異なるconcrete published typeを、Providerから共通のreturn typeとして扱える。 -具体的なreturn type、streaming、pagination、backpressure、type erasure、error propagationは未決定である。 +具体的なreturn type、internal streaming、backpressure、type erasure、error propagationは未決定である。 ### `call_operation` @@ -312,7 +301,7 @@ runtime.call_current( `resolve_current_projection`と`runtime.call_current`というAPIを採用することは決定しない。ResolverはRuntimeが開始したexecution boundary内で呼ばれ、返す値はそのboundary中にObject identityとbackend対象を安定して保持するhandleまたはtransaction contextを含む必要がある。このexampleが示す要件は次である。 -- 過去の`fetch`で作成したstruct instanceを保持していなくてもOperationを実行できる。 +- 過去の`observe`で作成したstruct instanceを保持していなくてもOperationを実行できる。 - Call時の現在の主体、Object visibility、Object metadata、Interface集合を同じProjection pathで再解決し、Objectが非公開なら`NotFound`を返す。 - Requestの`interface.reference`が現在の`Object.interfaces`に含まれることを確認し、含まれなければ`InterfaceMismatch`を返す。 - 現在のInterfaceにOperationが宣言されていなければ`OperationNotFound`、Operationを公開しつつ実行だけを拒否する場合は`PermissionDenied`を返す。 @@ -420,7 +409,7 @@ Operation implementationは、Object instance以外にrequest contextを必要 これらをmethod parameter、receiver wrapper、generated context、task-local stateのどれで渡すかは未決定である。Protocol parameterとして宣言された値と、Hostが注入するcontextを明確に区別しなければならない。 -Object publication時のInterface集合の選択と、Operation call時のmembership、Interface validator、authorizationの再評価を実装できる必要がある。以前の`fetch`で公開されたInterface集合だけを根拠に、現在のOperation実行を許可してはならない。 +Object publication時のInterface集合の選択と、Operation call時のmembership、Interface validator、authorizationの再評価を実装できる必要がある。以前の`observe`で公開されたInterface集合だけを根拠に、現在のOperation実行を許可してはならない。 Operation resultのRecord、List、Union等へnestedしたすべての`Entry`位置について、Hostは現在の主体にそのpathを認識させてよいことを再帰的に確認できなければならない。通常のstructural Value validationだけではこのvisibility checkを満たさない。Macro-generated code、Projection、Host Runtimeのどこで確認するかは未決定である。 @@ -449,8 +438,8 @@ Rust API modelは少なくとも次を満たす。 - Objectのpath、children、Interface集合をstructへ恒久的に固定しない。 - Struct instanceをrequest scopeで生成および破棄できる。 - 全Object instanceの事前登録を要求しない。 -- Direct childrenを現在の主体についてprojectし、非公開Objectをcountせず、lazyかつboundedに発見する。 -- Clean exhaustion、additional visible child、failure、cancellationを区別して`truncated`を正確に決定できる。 +- Direct childrenを現在の主体についてprojectし、非公開Objectとそのsubtreeを除外しつつlazyに発見し、success responseではclean exhaustionまで列挙する。 +- Backend failure、cancellation、resource budget超過をclean exhaustionとして扱わず、部分的なobservationをsuccess responseとして返さない。 - 同じstructへ複数のInterfaceを同時に追加でき、追加順を保持し、重複を拒否できる。 - 異なるInterfaceの同名Operationを、Interface参照とOperation名の組でdispatchできる。 - Protocol boundaryでarguments、result、Object、Descriptorを検証する。 diff --git a/draft/typescript-api-model.md b/draft/typescript-api-model.md index 45c2ca2..7b4fc92 100644 --- a/draft/typescript-api-model.md +++ b/draft/typescript-api-model.md @@ -17,7 +17,7 @@ TypeScript APIでは、次のmodelを自然に表現できるようにする。 3. Definition objectからOperation implementationのTypeScript型を推論する。 4. Classまたはplain objectが、Protocol Objectとして公開するmetadataと、必要に応じて0個以上のInterfaceのOperation implementationを提供する。 5. Objectを返す時点で、公開するInterfaceのordered setを明示的に選択する。 -6. Object instanceをWorldspace全体について常駐させず、`fetch`、`fetch_tree`、`call_operation`の解決時にdata-drivenに生成できる。 +6. Object instanceをWorldspace全体について常駐させず、`observe`と`call_operation`の解決時にdata-drivenに生成できる。 7. Custom transpiler、TypeScript compiler plugin、decorator metadataをcore APIの前提にしない。 このmodelでは、Protocol上のObjectとInterfaceの関連付けは`Object.interfaces`だけで表す。Operation implementationへ到達するためのTypeScript / JavaScript内部codeはSDK / Host Runtimeの実装詳細であり、新しいProtocol conceptを導入しない。 @@ -305,7 +305,7 @@ Optional propertyの`undefined`はwireへ出力せず、field省略として扱 `selectedInterfaceReferences`は、Hostが各runtime Interface definitionを登録または公開するときに割り当てるopaque参照を、publication APIへの追加順で並べたものである。同じ参照の重複は拒否する。Variable名やJavaScript object identityをportableなProtocol参照としてそのまま使用することは要求しない。 -`fetch`と`fetch_tree`はDescriptor自体をObjectへ埋め込まず、このInterface参照のordered setだけを返す。Clientが各参照を`fetch_interface`したとき、Host Runtimeはruntime definition objectから構築したDescriptorと、存在する場合はInterface validatorを返す。同じ参照とvalidatorの組のDescriptorはHost上で共有およびcacheできるため、Object instanceごとにDescriptorを再生成または再送する必要はない。 +`observe`はDescriptor自体をObjectへ埋め込まず、このInterface参照のordered setだけを返す。Clientが各参照を`fetch_interface`したとき、Host Runtimeはruntime definition objectから構築したDescriptorと、存在する場合はInterface validatorを返す。同じ参照とvalidatorの組のDescriptorはHost上で共有およびcacheできるため、Object instanceごとにDescriptorを再生成または再送する必要はない。 ## Runtime definitionの責務 @@ -364,7 +364,7 @@ Protocol `Unit`は、例えば`wip.unitValue`のような専用singleton / senti ## Dynamic Worldspaceでのlifecycle -### `fetch` +### `observe` Projection implementationはrequest時にbackend dataを解決し、classまたはplain object instanceを生成する。 @@ -401,11 +401,7 @@ async function resolveFile( Host Runtimeは`PublishedObject`からProtocol Objectを返す。Response生成後にこの`File` instanceを破棄してよく、Worldspace内の全fileに対応するinstanceを保持しない。 -### `fetch_tree` - -Providerがdirectory全体を先に収集してArrayとして返すことを要求しない。Host Runtimeの`depth`、`limit`、resource budgetに従って、direct childrenをlazyかつboundedに発見できなければならない。 - -ConceptualにはAsync Iterable、pull-based cursor、paged source等を利用できる。 +Requested depthが正の場合、Providerはdirect childrenをlazyに発見できる。Directory全体を先に収集してArrayとして返すことは要求しないが、一つのparentのobservationを成功させるには公開されたindexable childrenをclean exhaustionまで列挙しなければならない。ConceptualにはAsync Iterable等を利用できる。 ```ts const entries = filesystem.discoverChildren(path, budget); @@ -420,28 +416,19 @@ for await (const entry of entries) { continue; } - traversal.accept(child); - - if (traversal.hasEnoughEvidenceToFinish()) { - break; - } + observation.pushChild(child); } - -const completion = entries.completion(); ``` -`discoverChildren`、`budget`、`traversal`、`completion`はconceptualであり、具体APIではない。必要なsemanticsは次である。 +`discoverChildren`、`budget`、`observation`はconceptualであり、具体APIではない。必要なsemanticsは次である。 - 各childを現在の主体についてprojectし、非公開Objectとそのsubtreeを返さない。 -- 非公開childをtraversal count、`limit`、`truncated`判定へ含めない。 -- Clean exhaustionと、追加の公開childが存在する状態を区別する。 -- 結果がちょうど`limit`件の場合も、追加childの有無を根拠なく仮定しない。 -- Depth境界で公開されたindexable childが省略されるか判定できる。 -- Backend failure、cancellation、resource budget超過をclean exhaustionとして扱わない。 -- Host RuntimeがProtocolの`truncated`を正確に設定できる情報を提供する。 +- 公開されたindexable childrenをすべて列挙し、clean exhaustionで終了する。 +- Backend failure、cancellation、resource budget超過をclean exhaustionとして扱わず、部分的なsuccess responseを返さない。 +- Requested depthに達したnodeではchild discoveryを行わず、`children`を未観測として省略する。 - 異なるclassやplain objectを共通のpublished return typeとして扱える。 -具体的なAsync Iterator contract、streaming、pagination、backpressure、error propagationは未決定である。 +具体的なAsync Iterator contract、internal streaming、backpressure、error propagationは未決定である。 ### `call_operation` @@ -460,7 +447,7 @@ await runtime.callCurrent( `resolveCurrentProjection`と`runtime.callCurrent`というAPIを採用することは決定しない。ResolverはRuntimeが開始したexecution boundary内で呼ばれ、返す値はそのboundary中にObject identityとbackend対象を安定して保持するhandleまたはtransaction contextを含む必要がある。このexampleが示す要件は次である。 -- 過去の`fetch`で作成したobject instanceを保持していなくてもOperationを実行できる。 +- 過去の`observe`で作成したobject instanceを保持していなくてもOperationを実行できる。 - Call時の現在の主体、Object visibility、Object metadata、Interface集合を同じProjection pathで再解決し、Objectが非公開なら`NotFound`を返す。 - Requestの`interface.reference`が現在の`Object.interfaces`に含まれることを確認し、含まれなければ`InterfaceMismatch`を返す。 - 現在のInterfaceにOperationが宣言されていなければ`OperationNotFound`、Operationを公開しつつ実行だけを拒否する場合は`PermissionDenied`を返す。 @@ -582,7 +569,7 @@ Operation implementationは、Object instance以外にrequest contextを必要 これらをmethod parameter、wrapper object、AsyncLocalStorage、closure等のどれで渡すかは未決定である。Protocol parameterとして宣言された値と、Hostが注入するcontextを明確に区別しなければならない。 -Object publication時のInterface集合の選択と、Operation call時のmembership、Interface validator、authorizationの再評価を実装できる必要がある。以前の`fetch`で公開されたInterface集合だけを根拠に、現在のOperation実行を許可してはならない。 +Object publication時のInterface集合の選択と、Operation call時のmembership、Interface validator、authorizationの再評価を実装できる必要がある。以前の`observe`で公開されたInterface集合だけを根拠に、現在のOperation実行を許可してはならない。 Operation resultのRecord、List、Union等へnestedしたすべての`Entry`位置について、Hostは現在の主体にそのpathを認識させてよいことを再帰的に確認できなければならない。通常のstructural Value validationだけではこのvisibility checkを満たさない。Runtime definition、Projection、Host Runtimeのどこで確認するかは未決定である。 @@ -648,8 +635,8 @@ TypeScript API modelは少なくとも次を満たす。 - Objectのpath、children、Interface集合をclassへ恒久的に固定しない。 - Classまたはplain object instanceをrequest scopeで生成および破棄できる。 - 全Object instanceの事前登録を要求しない。 -- Direct childrenを現在の主体についてprojectし、非公開Objectをcountせず、lazyかつboundedに発見する。 -- Clean exhaustion、additional visible child、failure、cancellationを区別して`truncated`を正確に決定できる。 +- Direct childrenを現在の主体についてprojectし、非公開Objectとそのsubtreeを除外しつつlazyに発見し、success responseではclean exhaustionまで列挙する。 +- Backend failure、cancellation、resource budget超過をclean exhaustionとして扱わず、部分的なobservationをsuccess responseとして返さない。 - 同じclassまたはplain objectへ複数のInterface-specific implementationを同時にbindでき、追加順を保持し、重複を拒否できる。 - 異なるInterfaceの同名Operationを、Interface参照とOperation名の組およびInterface-specific bindingでdispatchできる。 - Operation result内のnestedな`Entry`へ、現在の主体についてvisibility checkを適用できる。 diff --git a/draft/unresolved-issues.md b/draft/unresolved-issues.md index 923ae88..b825404 100644 --- a/draft/unresolved-issues.md +++ b/draft/unresolved-issues.md @@ -32,7 +32,7 @@ ### Interaction / Error -- `fetch_tree`のdepthとlimitへ相互運用上の共通上限を定義するか。 +- `observe`のdepthへ相互運用上の共通上限を定義するか。 - ProtocolErrorへstructured detailを追加するか。 - Resource limitを固定値またはcapability negotiationのどちらで定義するか。 diff --git a/draft/wip-over-https.md b/draft/wip-over-https.md index a120e38..863f7ec 100644 --- a/draft/wip-over-https.md +++ b/draft/wip-over-https.md @@ -18,8 +18,7 @@ OperationがWebSocket等のendpointを通常のApplication dataとして返す 少なくとも、Protocolの以下のinteractionをHTTP request / responseへ対応付ける。 -- `fetch` -- `fetch_tree` +- `observe` - `fetch_interface` - `call_operation` @@ -35,8 +34,7 @@ Endpoint URLはqueryとfragmentを持たず、pathが`/`で終わるcanonical fo | Interaction | HTTP method | Relative path | | --- | --- | --- | -| `fetch` | `POST` | `v1/fetch` | -| `fetch_tree` | `POST` | `v1/fetch_tree` | +| `observe` | `POST` | `v1/observe` | | `fetch_interface` | `POST` | `v1/fetch_interface` | | `call_operation` | `POST` | `v1/call_operation` | | batch | `POST` | `v1/batch` | @@ -49,10 +47,10 @@ Endpoint URLはqueryとfragmentを持たず、pathが`/`で終わるcanonical fo https://gateway.example/tenants/acme/proxies/filesystem/wip/ ``` -`fetch` routeは次になる。 +`observe` routeは次になる。 ```text -https://gateway.example/tenants/acme/proxies/filesystem/wip/v1/fetch +https://gateway.example/tenants/acme/proxies/filesystem/wip/v1/observe ``` Endpointのpath prefixはHTTP deployment上のroutingであり、Worldspace内のpathではない。Worldspace pathは常に各WIP requestのlogical fieldとして渡す。Hostまたはreverse proxyは異なるbase pathに複数のWorldspaceやproxy surfaceをmountできるが、一つのendpointに属するinteractionはすべて同じbase URL配下へ公開する。 @@ -79,7 +77,7 @@ WIP over HTTPSは特定のauthentication schemeを要求せず、HTTP authentica Credentialが欠落または無効でWIP interactionを開始できない場合、HTTP layerは`401 Unauthorized`と、使用するschemeに応じた`WWW-Authenticate`を返してよい。HTTP layerは、特定のWIP endpointが表すWorldspace access surface全体へのaccessを認めない場合に、そのendpointへのrequestを`403 Forbidden`等で拒否してよい。ClientはこれらをProtocol failureへ変換せず、Transport authentication / authorization failureとして扱う。 -HTTP layerによるWorldspace全体のaccess controlを通過してWIP interactionを開始した後は、個別Objectへのaccess拒否を「Objectは存在するが閲覧禁止」という状態として公開しない。その主体へ公開しないObjectはClient-facing Worldspaceに存在しないものとして扱い、`fetch`、`fetch_tree`、`call_operation`では`NotFound`を返す。個別Objectの存在を示唆する`PermissionDenied`や、Protocol error envelopeを持たない`403 Forbidden`へ置き換えない。 +HTTP layerによるWorldspace全体のaccess controlを通過してWIP interactionを開始した後は、個別Objectへのaccess拒否を「Objectは存在するが閲覧禁止」という状態として公開しない。その主体へ公開しないObjectはClient-facing Worldspaceに存在しないものとして扱い、`observe`と`call_operation`では`NotFound`を返す。個別Objectの存在を示唆する`PermissionDenied`や、Protocol error envelopeを持たない`403 Forbidden`へ置き換えない。 Authentication後に確立された主体に対するInterface / Operation visibilityとOperation authorizationもWIP Protocol semanticsに従う。現在公開されていないInterfaceには`InterfaceNotFound`、現在のInterfaceに宣言されていないOperationには`OperationNotFound`を返す。`PermissionDenied`は、現在公開されているOperationの存在を示したうえで、その主体による実行だけを拒否する場合に使用する。 @@ -103,85 +101,49 @@ Protocol structの`String`はJSON string、`Vec`はRFC 4648 Section 4のbase 未知のJSON fieldを許可する箇所はProtocol側で明示する。Object、Interface Descriptor、request / response、Protocol errorの未宣言fieldは既定で拒否する。 -## Objectの取得 +## Objectとchildrenの観測 -`fetch` requestはpathとして解釈されるstringを`path`に渡し、Objectを直接受け取る。 - -概念的なrequest bodyは次の形になる。 - -```json -{ - "path": "/items/123" -} -``` - -Responseは次の形になる。 - -```json -{ - "name": "123", - "description": "First item", - "interfaces": [ - "item-interface-v1", - "item-marker-interface-v1" - ], - "ref": "item:123", - "validator": "b3BhcXVlLXZhbGlkYXRvcg==" -} -``` - -`interfaces`は0個以上のInterface参照を含み、membershipはsetとして扱う。同じ参照の重複はinvalidであり、array順序はUI等の表示順として保持してよいがOperation解決には影響しない。 - -`ref`、`description`、`validator`はoptional fieldであり、存在しない場合はfield自体を省略する。JSON `null`を代わりに使用しない。 - -Request pathはresponseへ重複して含めない。HTTP batchを使用する場合も、subrequestの`id`によってrequest pathとObject responseを対応付ける。 - -## Treeの取得 - -`fetch_tree` requestは起点path、depth、limitを渡す。 +`observe` requestは起点pathとdepthを渡す。 ```json { "path": "/items", - "depth": 1, - "limit": 100 + "depth": 1 } ``` -Responseは各nodeのObjectとchildrenを含む。各Objectのpathはrequest pathとObjectの`name`から導出し、validatorはObjectのfieldとしてencodeする。 +Responseはrootの`ObjectObservation`を直接返す。各nodeは`object`とoptionalな`children`を持ち、各Objectのpathはrequest pathとchildrenの`name`から導出する。ValidatorはObjectのfieldとしてencodeする。 ```json { - "root": { - "object": { - "name": "items", - "description": "Item collection", - "interfaces": [ - "sha256:item-collection-interface" - ], - "validator": "cm9vdC12YWxpZGF0b3I=" - }, - "children": [ - { - "object": { - "name": "123", - "description": "First item", - "interfaces": [ - "item-interface-v1", - "item-marker-interface-v1" - ], - "ref": "item:123", - "validator": "aXRlbS12YWxpZGF0b3I=" - }, - "children": [] - } - ] + "object": { + "name": "items", + "description": "Item collection", + "interfaces": [ + "sha256:item-collection-interface" + ], + "validator": "cm9vdC12YWxpZGF0b3I=" }, - "truncated": false + "children": [ + { + "object": { + "name": "123", + "description": "First item", + "interfaces": [ + "item-interface-v1", + "item-marker-interface-v1" + ], + "ref": "item:123", + "validator": "aXRlbS12YWxpZGF0b3I=" + } + } + ] } ``` -`depth`または`limit`によって存在するindexable childを省略した場合、`truncated`を`true`にする。 +`depth = 0`ではroot nodeの`children`を省略する。Nodeのdepthがrequestの`depth`より小さい場合は`children`を必ずencodeし、観測済みでemptyなら空arrayを使用する。Nodeがrequested depthに達した場合は`children` fieldを省略する。Optional fieldの省略をJSON `null`で置き換えない。 + +Success responseはrequested depthまで完全であり、部分的なsuccess responseは返さない。完全なresponseをresource budget内で構築できない場合、Hostは`resource_limit_exceeded`を返す。 ## Interfaceの取得 @@ -216,7 +178,7 @@ Interface DescriptorはJSON-compatibleなlogical structとしてProtocolで定 `validator`はInterface参照と組み合わせて解釈するoptionalなopaque bytesである。同じ参照とvalidatorの組は同じDescriptorを表す。Descriptorを変更可能にするHostはvalidatorを返して変更時に更新し、validatorを返さない参照は有効期間中immutableにする。 -ClientはObjectの各Interface参照をcacheと比較し、未知の参照だけを`fetch_interface`する。Validatorが存在する観測は`(interface, validator)`の組でcacheし、Interface validator mismatch等で更新が必要になった参照は再取得する。Validatorを返さない参照は、その参照の有効期間中Descriptorをimmutableとしてcacheできる。HostはClientのcache状態を推測せず、`fetch`や`fetch_tree`のresponseへDescriptorを先行同梱しない。複数のInterface取得はHTTP batchingでまとめられる。 +ClientはObjectの各Interface参照をcacheと比較し、未知の参照だけを`fetch_interface`する。Validatorが存在する観測は`(interface, validator)`の組でcacheし、Interface validator mismatch等で更新が必要になった参照は再取得する。Validatorを返さない参照は、その参照の有効期間中Descriptorをimmutableとしてcacheできる。HostはClientのcache状態を推測せず、`observe` responseへDescriptorを先行同梱しない。複数のInterface取得はHTTP batchingでまとめられる。 ## Operation valueのJSON encoding @@ -344,7 +306,7 @@ Protocol failureは、非2xx HTTP responseのJSON bodyへ次のenvelopeでencode | `internal` | `500 Internal Server Error` | | `operation_outcome_unknown` | `500 Internal Server Error` | -`resource_limit_exceeded`がrequestまたはresponse representationのbyte size超過を表す場合は`413 Content Too Large`、depth、limit、nesting、collection件数等のlogical limit超過を表す場合は`422 Unprocessable Content`を使用する。Rate limitまたはconcurrency limitによる`429 Too Many Requests`はTransport / deployment concernであり、Core interactionの`resource_limit_exceeded`へ自動変換しない。 +`resource_limit_exceeded`がrequestまたはresponse representationのbyte size超過を表す場合は`413 Content Too Large`、observation depth、nesting、collection件数等のlogical limit超過を表す場合は`422 Unprocessable Content`を使用する。Rate limitまたはconcurrency limitによる`429 Too Many Requests`はTransport / deployment concernであり、Core interactionの`resource_limit_exceeded`へ自動変換しない。 HTTP statusはProtocol error codeを置き換えない。複数のcodeが同じstatusを使用し、同じcodeがresource limitの種類に応じて異なるstatusを使用できる。Hostは上記mappingに従わなければならないが、Clientが非2xx responseからvalidなProtocol error envelopeを取得できた場合、statusがmappingと一致しなくても回復actionは`code`に従い、statusから別のcodeを推測しない。Clientはstatus mismatchをTransport Binding違反として診断してよい。2xx responseのerror envelope、または非2xx responseのsuccess bodyは`InvalidResponse`として扱う。 @@ -369,9 +331,10 @@ Batchは上記の`POST v1/batch` routeを使用し、bodyに一意な`id`を持 "requests": [ { "id": "entry-123", - "method": "fetch", + "method": "observe", "arguments": { - "path": "/items/123" + "path": "/items/123", + "depth": 0 } }, { @@ -393,14 +356,16 @@ Hostは各subrequestを、単独で受け取った場合と同じ規則で処理 { "id": "entry-123", "result": { - "name": "123", - "description": "First item", - "interfaces": [ - "item-interface-v1", - "item-marker-interface-v1" - ], - "ref": "item:123", - "validator": "b3BhcXVlLXZhbGlkYXRvcg==" + "object": { + "name": "123", + "description": "First item", + "interfaces": [ + "item-interface-v1", + "item-marker-interface-v1" + ], + "ref": "item:123", + "validator": "b3BhcXVlLXZhbGlkYXRvcg==" + } } }, { @@ -432,7 +397,7 @@ Batchには次の規則を適用する。 - HostはClientが要求していないsubresponseを追加してはならない。 - 各subresponseは`result`または`error`の一方だけを持つ。 -初期のbatch形式に格納できるのは`fetch`、`fetch_tree`、`fetch_interface`とし、`call_operation`は含めない。将来Effect annotationを採用する場合に、副作用を持たないと明示されたOperationをbatch対象へ加えるかを改めて検討する。 +初期のbatch形式に格納できるのは`observe`と`fetch_interface`とし、`call_operation`は含めない。将来Effect annotationを採用する場合に、副作用を持たないと明示されたOperationをbatch対象へ加えるかを改めて検討する。 Batch envelopeがvalidである場合、Hostは一部または全部のsubrequestがProtocol failureでも`200 OK`を返す。各subresponseの`error`は対応するinteractionで許可されたProtocol errorの`code`と`message`を直接含み、itemごとのHTTP statusは持たない。