From 28dbf4c8d682ce1d83814af56f433a42876d462f Mon Sep 17 00:00:00 2001 From: Hare Date: Wed, 7 Oct 2026 16:04:06 +0900 Subject: [PATCH] docs: integrate scoped interface references into core specification --- 2-core-model.md | 2 +- 2.1-object-tree-schema.md | 22 +- ...ation.md => 2.2-operation-and-interface.md | 25 ++- 3-protocol.md | 83 ++++++- 4-client.md | 6 +- 4.1-ai-tools.md | 2 + 4.2-text-view.md | 52 ++++- 5.1-wip-over-http.md | 50 +++-- draft/dynamic-worldspace-projection.md | 6 +- draft/interface-scope.md | 206 ------------------ draft/rust-api-model.md | 14 +- draft/typescript-api-model.md | 14 +- draft/unresolved-issues.md | 16 +- 13 files changed, 234 insertions(+), 264 deletions(-) rename 2.2-operation.md => 2.2-operation-and-interface.md (84%) delete mode 100644 draft/interface-scope.md diff --git a/2-core-model.md b/2-core-model.md index 74324cc..1eee544 100644 --- a/2-core-model.md +++ b/2-core-model.md @@ -56,7 +56,7 @@ ObjectはOperation定義を直接持たず、0個以上のInterface参照をorde Interface集合のmembershipはset semanticsを持ち、同じ参照を重複して含めない。列挙順はOperation解決には影響しないが、HostがInterfaceを公開した順序としてUI表示に使用できる。 -InterfaceとOperationの意味論は[2.2. Interface / Operation](2.2-operation.md)、Descriptorのlogical structは[3. Protocol](3-protocol.md)、AI向け操作は[4.1. AI Tools](4.1-ai-tools.md)、人間とAIへのsignature表記は[4.2. Text View](4.2-text-view.md)で扱う。 +InterfaceとOperationの意味論は[2.2. Operation and Interface](2.2-operation-and-interface.md)、Descriptorのlogical structは[3. Protocol](3-protocol.md)、AI向け操作は[4.1. AI Tools](4.1-ai-tools.md)、人間とAIへのsignature表記は[4.2. Text View](4.2-text-view.md)で扱う。 ## Core interaction diff --git a/2.1-object-tree-schema.md b/2.1-object-tree-schema.md index 9029e95..c35b7f0 100644 --- a/2.1-object-tree-schema.md +++ b/2.1-object-tree-schema.md @@ -35,7 +35,7 @@ Objectの本文、状態、domain metadata等のApplication dataを、共通のp Objectは0個以上のInterfaceを参照する。各Interface Descriptorは、Objectに対して実行可能なOperationの一つのcapability namespaceを宣言する。 -Operation名は一つのInterface Descriptor内で一意であればよく、異なるInterface間で同じOperation名を使用できる。Operation callはInterface参照を明示するため、Protocol上の解決は曖昧にならない。UIやAI Tool表示では、必要に応じて`.`の形でqualifyする。この表示形式はProtocol fieldへ再parseする識別子ではなく、Interface参照とOperation名の組を人間へ示す表記である。 +Operation名は一つのInterface Descriptor内で一意であればよく、異なるInterface間で同じOperation名を使用できる。Operation callはscopeとlocal nameからなるInterface参照を明示するため、Protocol上の解決は曖昧にならない。人間・AI向けのqualified表記は[Text Viewの参照表記](4.2-text-view.md#参照表記)に従う。 Interfaceは次を定義する。 @@ -49,6 +49,18 @@ Interface実装者は実装コード上でInterfaceを宣言し、Libraryはそ 同じInterfaceを持つObjectは同じDescriptor参照を共有できる。 +## Interface scope + +Objectをpath `P`で公開するとき、そのInterface参照のscopeは`P`に至る祖先chain上になければならない。祖先は直近のparentだけでなくrootからparentまでの各pathを含む。Path segmentの完全一致で判定し、単純な文字列prefixで判定しない。 + +例えば`/github/my-rep/issues`は、scope `/`、`/github`、`/github/my-rep`のInterfaceを公開できる。`/gitlab`、`/github/other-rep`、`/github/my-rep/issues/123`のscopeは使用できない。`/github`は`/github-extra`の祖先ではない。 + +この制約は配置pathに基づき、indexableかどうかには依存しない。非indexableなObjectを直接観測した場合も同じ規則を適用する。Scopeの祖先Objectを先に観測することも、そのObject自身が同じInterfaceを公開することも要求しない。 + +Scopeの適合と`Object.interfaces`への明示的なmembershipは別の条件である。祖先scopeのInterfaceを自動継承せず、scopeをauthorizationの証明として扱わない。 + +Object自身のpathをscopeにできるか(self-scope)、特にroot ObjectでのInterface公開は未確定である。本節で確定する祖先関係はstrict ancestorとし、self-scopeを必要とする公開の扱いは[未解決事項](draft/unresolved-issues.md)に残す。 + ## Object / エントリ / path WIPでは、Objectとエントリを別のdomain entityとして定義しない。ObjectをTree上の位置として扱うとき、そのObjectをエントリと呼ぶ。 @@ -137,7 +149,7 @@ Hostは、主体に認識させるObjectだけでClient-facing Worldspaceを構 - 省略されたObjectやchild数を示すredaction markerは返さない。 - 非公開pathを起点とする`observe`には、Host内部での存在理由にかかわらず`NotFound`を返す。Object観測に対する`PermissionDenied`は使用しない。 -Objectを公開しながら、特定Interfaceを集合から除外すること、公開したInterfaceから一部のOperationを除外すること、公開されたOperationの実行を認可時に拒否することはできる。Operationの可視性と`PermissionDenied`の使い分けは[2.2. Interface / Operation](2.2-operation.md)で定義する。 +Objectを公開しながら、特定Interfaceを集合から除外すること、公開したInterfaceから一部のOperationを除外すること、公開されたOperationの実行を認可時に拒否することはできる。Operationの可視性と`PermissionDenied`の使い分けは[2.2. Operation and Interface](2.2-operation-and-interface.md)で定義する。 Objectの`description`には、その主体へ公開できる説明だけを含める。安全な説明を公開できない場合はoptionalな`description`を省略できるが、Protocolはfield-level redaction markerを定義しない。Objectの本文やdomain dataの部分的な開示は、各Operationのresult schemaとdomain semanticsで表現する。 @@ -169,12 +181,12 @@ Tree上のchildrenとして自然に列挙できるのは、**indexableなObject 全件列挙が高コストまたは不自然な集合は、Treeへ直接展開しない。対象の集合を扱うObjectのOperationを使って検索、filter、paginationを行い、resultとして関連する`entry`を返す。 -例えば、大規模なIssue collectionは次のように公開できる。 +例えば、大規模なIssue collectionは次のように公開できる。参照はscope `/`を含む短縮表記で示す。 ```text /issues - interfaces: [IssueCollection] - operation: IssueCollection.query(filter, cursor, limit) -> IssueQueryResult + interfaces: ["/::IssueCollection"] + operation: /::IssueCollection#query(filter, cursor, limit) -> IssueQueryResult ``` ```text diff --git a/2.2-operation.md b/2.2-operation-and-interface.md similarity index 84% rename from 2.2-operation.md rename to 2.2-operation-and-interface.md index e9974fa..0bbb3e5 100644 --- a/2.2-operation.md +++ b/2.2-operation-and-interface.md @@ -1,4 +1,4 @@ -# 2.2. Interface / Operation +# 2.2. Operation and Interface ## Interface @@ -12,7 +12,24 @@ Interface実装者は、RustのtraitやTypeScriptのdefinition API等を使っ Interface Descriptorは人間が手書きするschema fileではない。Hostが`fetch_interface`で公開し、Clientが参照単位でcacheするprotocol dataである。 -Interface参照へWorldspaceのpath scopeを導入する変更案は、[Scoped Interface References(草案)](draft/interface-scope.md)で扱う。現行Protocolのopaque参照を置き換えるための草案であり、本章の確定仕様へはまだ適用しない。 +## Interfaceの識別とscope + +Interface参照は、Worldspace上の絶対pathである`scope`と、そのscope内のlocal nameである`name`を別fieldとして持つ構造化データである。同じClient-facing Worldspace内の同じ有効な`(scope, name)`は同じInterfaceを表す。 + +```text +{ scope: "/github", name: "issue.read" } +{ scope: "/gitlab", name: "issue.read" } +``` + +この二つは同じlocal nameを持つが、異なるInterface参照である。Local nameの`.`等に階層やOperationとの区切りの意味を持たせない。同じscope内の異なるInterfaceへ同じnameを割り当てない。複数Providerを同じscopeへ登録する場合も、Hostが名前の衝突を検出・解消する。 + +ScopeはClientに対してHostが公開するWorldspaceのrootを基準とする。Backendのpath、filesystem root、HTTP endpointのprefixではなく、相対pathは認めない。異なるWorldspace間で同じ`(scope, name)`を同一Interfaceとして扱わない。 + +Objectが利用できるscopeは、そのObjectの配置pathとの[祖先関係](2.1-object-tree-schema.md#interface-scope)に従う。この制約はInterfaceの自動継承ではない。Objectは使用するInterfaceを明示的に公開し、scopeだけを根拠にOperationを追加したり、実行を認可したりしない。 + +構造とvalidationは[3. Protocol](3-protocol.md#interface-reference)、`/github::issue.read#read`等の人間・AI向け短縮表記は[4.2. Text View](4.2-text-view.md#参照表記)で定義する。Interface参照とOperation名を連結した表示文字列をProtocolの参照fieldへ格納しない。 + +Hostによるproxy・Worldspace合成では、Hostがscopeを公開先の配置へ変換する。Path、typed `entry`、identity、validatorとの一貫性は[Worldspace composition](3-protocol.md#worldspace-composition)に従う。 ## Interface Descriptor @@ -58,7 +75,7 @@ Return typeにはDescriptorで定義される任意のvalue typeを使用でき Operationの用途は短いdocumentationで説明する。長文documentationや大量のApplication dataをInterface Descriptorへ埋め込まない。 -Operation名は一つのInterface Descriptor内で一意とする。異なるInterface間では同じOperation名を使用でき、`call_operation`はInterface参照とOperation名の組で解決する。UIやAI Toolでは必要に応じて`.`と表示する。このqualified表記は表示用であり、一つのProtocol fieldへencodeまたは再parseしない。 +Operation名は一つのInterface Descriptor内で一意とする。異なるInterface間では同じOperation名を使用でき、`call_operation`は構造化Interface参照とOperation名の組で解決する。表示用のqualified表記は[Text Viewの参照表記](4.2-text-view.md#参照表記)に従い、Protocolでは参照とOperation名を別fieldとして扱う。 ## `fetch_interface` @@ -119,7 +136,7 @@ HostはOperationを実行する前に、次を検証する。 1. `target.path`が存在する。 2. `target.validator`が指定されている場合、現在のObject validatorと一致する。 -3. `interface.reference`がObjectの現在の`interfaces`に含まれる。 +3. `interface.reference`が`(scope, name)`の完全一致でObjectの現在の`interfaces`に含まれ、対象pathに対するscopeの祖先制約を満たす。 4. MutableなInterfaceでは`interface.validator`が指定され、現在のInterface validatorと一致する。 5. 選択したInterfaceにOperationが宣言されている。 6. Argumentsがparameter declarationに従っている。 diff --git a/3-protocol.md b/3-protocol.md index 6a65201..2d53077 100644 --- a/3-protocol.md +++ b/3-protocol.md @@ -77,6 +77,29 @@ Pathとして宣言されたfieldのvalueは、同じWorldspace内のObjectを Nameに`/`を許可しないため、Protocolはpath segment escapeを定義しない。Transport BindingによるURL encodingはWIP Pathの構成とは別に扱う。 +## Interface Reference + +Interface参照は、scopeとlocal nameからなるrecordとして表す。新しいfirst-class resourceやnamed scalarではなく、Objectやinteractionが使用する参照のstructである。 + +```rust +struct InterfaceReference { + scope: String, + name: String, +} +``` + +- `scope`はClient-facing Worldspaceのrootに基づくcanonical absolute path。上記Pathの規則を適用し、relative path、`.` / `..`、空scopeを認めない。Root scopeは`/`とする。 +- `name`はそのscope内のInterfaceを識別する空でないUnicode string。`.`、`::`、`#`等を含んでもfield内の文字として扱い、pathやOperation名へ分解しない。 +- 同じWorldspace context内で`scope`と`name`のUnicode code point sequenceがそれぞれ完全一致する場合だけ、同じ参照とする。Normalization、case変換、URL decodeは行わない。 +- `Object.interfaces`の重複判定、membership、request / responseの参照一致、Interface cacheのkeyにはこの組を使う。Object member順や短縮表記の引用・escapeの違いは参照の同一性へ影響しない。 +- Interface Descriptorはscopeやnameを自身のfieldとして持たない。同じ構造のDescriptorであることから参照の同一性を推測しない。 + +`Object.interfaces`の各要素、`FetchInterfaceRequest.interface`、`FetchInterfaceResponse.interface`、`InterfaceTarget.reference`はすべてこのstructを使用する。Opaque stringや`scope::name`という連結stringを代替として受理しない。Operation名は`CallOperationRequest.operation`に独立して保持する。 + +人間・AI向けの短縮表記は[4.2. Text View](4.2-text-view.md#参照表記)に従う。Scope省略形を入力として受けるadapterも、明示されたcontextから絶対scopeを確定してからProtocol requestを構築する。 + +不正な参照shape、relative scope、空name等はCore request validationで`InvalidRequest`とする。Responseに不正な参照がある場合はClient-localな`InvalidResponse`とする。Validな参照に対応するInterfaceが主体へ公開されているか、対象Objectで使えるかはinteractionごとに検証する。 + ## Documentation Interface、Operation、type、field、parameter、caseに付与するdocumentationを次のlogical structで表す。 @@ -100,7 +123,7 @@ DocumentationはHostが提供するplain text dataであり、Clientのsystem in struct Object { name: String, description: Option, - interfaces: Vec, + interfaces: Vec, r#ref: Option, validator: Option>, } @@ -126,7 +149,7 @@ Objectで利用できるOperationを定義するInterface Descriptorへの参照 - Clientは列挙順をInterfaceおよびOperationのUI表示順として使用してよい。 - Operation callは集合から一つのInterface参照を明示する。 -異なるInterfaceでは同じOperation名を宣言できる。UIやAI Toolは必要に応じて`.`と表示してよい。このqualified表記は表示上の組であり、一つのProtocol stringへencodeまたはparseする規則を定義しない。 +異なるInterfaceでは同じOperation名を宣言できる。Protocolでは構造化参照とOperation名を別fieldとして扱い、表示用の短縮表記は[4.2. Text View](4.2-text-view.md#参照表記)に従う。 Hostはvalidatorを発行することで、同じInterface参照のDescriptorを時間とともに変更できる。Validatorを発行しない参照のDescriptorは、その参照が有効な間は変更しない。Clientは`fetch_interface`でDescriptorとvalidatorを一つの観測として取得する。 @@ -299,7 +322,7 @@ struct ReturnDeclaration { 一つのDescriptor内でOperation名は一意でなければならない。一つのOperation内でparameter名は一意でなければならない。 -Interface Descriptorの生成と意味論は[2.2. Interface / Operation](2.2-operation.md)、人間とAIへのInterface signatureは[4.2. Text View](4.2-text-view.md)で扱う。 +Interface Descriptorの生成と意味論は[2.2. Operation and Interface](2.2-operation-and-interface.md)、人間とAIへのInterface signatureは[4.2. Text View](4.2-text-view.md)で扱う。 ## Value @@ -418,13 +441,15 @@ Success responseはrequested depthまで完全である。Node数によるpartia 各nodeのObjectがvalidatorを持つ場合、Clientはrequest pathとchildrenの`name`から導出したpathに対応付けてcacheし、条件付きOperationの`target`を構築できる。 +HostとClientは各nodeの配置pathに対して[Interface scopeの祖先制約](2.1-object-tree-schema.md#interface-scope)を検証する。祖先制約に違反する参照を含むObject responseは`InvalidResponse`であり、そのObjectを操作へ使用しない。Self-scopeとroot Objectへの適用は同節の未確定事項に従う。 + ## `fetch_interface` Interface参照に対応する現在のInterface Descriptorを取得する。 ### Interface参照とvalidator -`Object.interfaces`の各要素、`FetchInterfaceRequest.interface`、`FetchInterfaceResponse.interface`、`InterfaceTarget.reference`は、Hostが公開するInterfaceへのopaqueな参照である。同じ有効なInterface参照は同じInterfaceを表すが、Hostはvalidatorを使用してDescriptorを時間とともに変更できる。 +`Object.interfaces`の各要素、`FetchInterfaceRequest.interface`、`FetchInterfaceResponse.interface`、`InterfaceTarget.reference`は`InterfaceReference`である。同じWorldspace context内の同じ有効な`(scope, name)`は同じInterfaceを表すが、Hostはvalidatorを使用してDescriptorを時間とともに変更できる。 `FetchInterfaceResponse.validator`は、HostがそのInterface Descriptorの現在状態へ付与するoptionalなopaque bytesである。Clientは内容を解釈せず、観測したDescriptorに基づいてOperationを実行するときに、Interface参照とともに`InterfaceTarget`へコピーする。 @@ -445,11 +470,11 @@ Interface validatorはAIやユーザーへ公開するApplication dataではな ```rust struct FetchInterfaceRequest { - interface: String, + interface: InterfaceReference, } struct FetchInterfaceResponse { - interface: String, + interface: InterfaceReference, descriptor: InterfaceDescriptor, validator: Option>, } @@ -475,6 +500,8 @@ Clientはvalidatorが存在するInterface observationを、`(interface, validat Hostは、主体へ公開したObjectの`interfaces`に含まれる各参照について、現在のDescriptorをその主体の`fetch_interface`で取得可能にしなければならない。現在公開されていないInterface参照には`InterfaceNotFound`を返し、Descriptor取得の認可失敗として`PermissionDenied`は使用しない。 +`fetch_interface`は完全な`(scope, name)`を受け取るため、祖先Objectを順に取得するlookupを要求しない。Scopeだけの存在確認や、近い祖先の同名Interfaceへのfallbackも行わない。Requestに対象Objectのpathはなく、特定Objectで利用できるかの祖先制約は`observe`と`call_operation`で検証する。Scope外のObjectで使えないことと、Interface単独の取得可否は同一視しない。 + ## `call_operation` 指定pathにあるObjectへOperationを実行する。 @@ -486,7 +513,7 @@ struct Target { } struct InterfaceTarget { - reference: String, + reference: InterfaceReference, validator: Option>, } @@ -513,7 +540,7 @@ Hostは、現在その主体へ公開しているObjectとInterfaceに基づい 1. `target.path`のObjectが公開されていない場合は`NotFound`。 2. 指定された`target.validator`が現在のObject validatorと一致しない場合は`ValidatorMismatch`。 -3. `interface.reference`が、現在そのObjectで公開されている`Object.interfaces`に含まれない場合は`InterfaceMismatch`。 +3. `interface.reference`が、現在そのObjectで公開されている`Object.interfaces`に`(scope, name)`の完全一致で含まれない、または対象pathへのInterface scopeの祖先制約に違反する場合は`InterfaceMismatch`。 4. 現在のInterfaceがvalidatorを持つにもかかわらず`interface.validator`が省略されている場合は`InterfaceValidatorRequired`。 5. 指定された`interface.validator`が現在のInterface validatorと一致しない場合は`InterfaceValidatorMismatch`。現在のInterfaceがvalidatorを持たない場合にvalidatorが指定されたときも一致しないものとする。 6. `operation`が現在のInterface Descriptorに宣言されていない場合は`OperationNotFound`。 @@ -537,6 +564,46 @@ Clientはresultを、requestの`interface`が指定し、Hostがpreconditionを Host Runtimeがimplementation resultのencodeまたはvalidation failureを送信前に検出し、Operationのeffectがcommitされていないと保証できる場合は`Internal`を返す。Operationが未実行またはrollback済みであることを保証できず、validなsuccess responseも返せない場合は`OperationOutcomeUnknown`を返す。 +## Worldspace composition + +Clientが扱う絶対pathとInterface scopeは、常に接続先Hostが公開するClient-facing Worldspaceのrootに基づく。Proxyや合成によってUpstream Worldspaceの公開位置が変わる場合、Hostが公開先とUpstreamの座標を対応付ける。Upstreamのrootやmount構成をClientに追跡・補完させない。 + +Upstreamのrootを`/github`へ配置する例: + +| 項目 | Upstream | 公開先 | +| --- | --- | --- | +| Root | `/` | `/github` | +| Object path | `/my-rep/issues` | `/github/my-rep/issues` | +| Interface参照 | `{ scope: "/", name: "issue.read" }` | `{ scope: "/github", name: "issue.read" }` | +| Repository scope | `/my-rep` | `/github/my-rep` | +| `entry` | `/my-rep/issues/123` | `/github/my-rep/issues/123` | + +別のUpstreamを`/gitlab`へ配置した場合、その`{ scope: "/", name: "issue.read" }`は`{ scope: "/gitlab", name: "issue.read" }`となる。同じlocal nameでもscopeによって区別される。さらに全体を`/services`へ配置するHostは、`/github`を`/services/github`へ変換する。Worldspaceの配置を変えないHTTP proxyはscopeを変更する必要がない。HTTP endpointのpath prefixとWorldspace pathを混同しない。 + +### 座標の変換 + +合成Hostは次の対応を一貫させる。 + +- `observe`のrequest pathをUpstreamへ変換する。ResponseのObjectの`name`とchildrenは公開先pathの規則を満たすようにする。特にUpstream rootの空の`name`を、非rootのmount先へそのまま公開しない。 +- `Object.interfaces`の各構造化参照のscopeを公開先へ変換し、公開先での祖先制約と名前の一意性を保つ。 +- `fetch_interface`を適切なUpstreamと構造化参照へ対応付ける。Responseの`interface`はClientが要求した公開先の参照にする。 +- `call_operation`のtarget pathとInterface参照をUpstreamへ対応付ける。Local name単独で転送先を選ばない。 +- Descriptorで`entry`と宣言されたargumentsをUpstreamへ、resultを公開先へ変換する。Named type、record、list、unionの内部にある`entry`も同じ規則で扱う。 + +通常の`string`、opaqueな`json`、documentation内のpathらしい文字列を推測して書き換えない。Application固有の別の座標系はApplication adapterの責務とする。 + +公開subtree外のscopeや`entry`に対応付けがない場合、Upstream pathをそのまま公開したり、scopeを削除・rootへ付け替えたりしてはならない。部分合成の対応付け方針と詳細な拒否条件は未確定だが、失敗時も既存のProtocol failure契約を守る。特にUpstreamでeffectがcommit済みのOperationのresultを変換できない場合、未実行を保証するerrorへ置き換えない。Validなsuccessを返せず、未実行またはrollbackを保証できない場合は`OperationOutcomeUnknown`として扱う。 + +### 同一性と観測整合性 + +- 公開先の同じ有効な`(scope, name)`とvalidatorを、異なるDescriptorへ対応付けない。Validatorのない参照のDescriptorは、その参照が有効な間immutableとする。 +- 異なるUpstreamのObjectへ同じ有効な公開`ref`を割り当てない。 +- Routingやmountの変更後に、古いObject validatorで別の対象へOperationを実行できないようにする。 +- Upstream validatorをそのまま使用するか、Host側で対応付け・wrapするかは、これらの保証を満たす範囲でHostが決める。 +- Scopeが変わればProtocol上は別のInterface参照である。Clientに移動前後の同一性を推測させない。 + +同じUpstream Objectを複数のscope配下へ配置すると、公開するInterface集合が配置ごとに変わり得る。異なる公開representationへ同じ`ref`とvalidatorを無条件に引き継げない。共通祖先scopeでの共有やprojectionごとのidentity割当等の選択、scopeのrename・再登録・mount変更時のlifecycleは[未解決事項](draft/unresolved-issues.md)に残す。未決事項は既存の同一性・validator・実行中callの一貫性を弱める許可ではない。 + ## Protocol responseとfailure Core interactionは、成功responseまたはProtocol failureを返す。 diff --git a/4-client.md b/4-client.md index 26d627d..fcec0b0 100644 --- a/4-client.md +++ b/4-client.md @@ -48,6 +48,10 @@ EntryのpathとchildrenはWorldspace上の配置contextであり、Object identi ## 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 @@ -63,7 +67,7 @@ Clientはvalidatorが存在する観測を`(interface, validator)`の組で識 ClientはDescriptorが必要なInterface参照とcacheを比較し、未知のInterfaceだけを取得する。Objectの`interfaces`からDescriptor interestを先行して導出しても、Operationを選択した時点で必要な参照だけを取得してもよい。Interface validator mismatch等で更新が必要になった参照は再取得する。複数の`fetch_interface`が必要な場合、それぞれを個別のrequestとして並行実行できる。 -異なるInterfaceで同じOperation名が存在しても、ClientはInterface参照とOperation名の組で識別する。UIやAI Toolでは必要に応じて`.`と表示する。Operation callでは表示文字列をparseせず、Interface参照とOperation名を別fieldとして送る。 +異なる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を早期に破棄しない。 diff --git a/4.1-ai-tools.md b/4.1-ai-tools.md index af5456f..07cb8cb 100644 --- a/4.1-ai-tools.md +++ b/4.1-ai-tools.md @@ -68,6 +68,8 @@ Signatureの配置や、詳細表示・表示対象を選択する具体的なTo Interfaceを明示するのは、同じObjectの複数Interfaceに同名Operationがあり得るためである。Interfaceの選択をAIへ示すことと、Descriptorの取得手順をAIに管理させることは別である。 +選択するInterfaceは絶対scopeとlocal nameの組で識別する。Adapterが[Text Viewの短縮表記](4.2-text-view.md#参照表記)を入力として受ける場合も、入力境界で構造化参照へ変換し、Operation名は独立して保持する。Scope省略には明示contextが必要であり、対象pathからの推測や相対scopeの解決はしない。Protocolへ短縮表記のstringをそのまま送らない。 + ClientはObjectとDescriptorの観測を保持し、引数を検証し、path、Object validator、Interface参照とvalidatorをProtocol requestへ設定する。AIにvalidatorの取得・コピー・更新をさせない。同一性管理やvalidatorはsignatureに含めない。 Pathを知っていることやInterfaceが表示されたことは、実行権限を意味しない。Hostは呼出時の公開状態、権限、capability、実行条件を引き続き検証する。ClientはresultをDescriptorに従って検証してから提示する。 diff --git a/4.2-text-view.md b/4.2-text-view.md index 6757ee4..8857a6f 100644 --- a/4.2-text-view.md +++ b/4.2-text-view.md @@ -26,13 +26,55 @@ Interface signatureは、Interface参照と、それに対応する検証済み Object tree全体の描画、Operation arguments / resultのvalue表示、Protocol errorや診断metadataの表示は本章の対象に含めない。 +## 参照表記 + +Interface参照のscopeとlocal nameの境界は`::`、InterfaceとOperationの境界は`#`で表す。 + +| 対象 | 短縮表記 | +| --- | --- | +| 完全なOperation指定 | `/github::issue.read#read` | +| 完全なInterface参照 | `/github::issue.read` | +| Scope省略のOperation指定 | `issue.read#read` | +| Root scopeのOperation指定 | `/::issue.read#read` | + +`/github::issue.read#read`は`scope = "/github"`、`name = "issue.read"`、`operation = "read"`の組を示す。対象Objectのpath、arguments、validatorを含まず、request全体の代わりにはならない。Protocolでは構造化Interface参照とOperation名を別fieldに保持し、この連結stringをwireやcache keyに使用しない。 + +### 成分の引用 + +- Scopeはcanonical absolute pathであり、文字列全体が`[A-Za-z0-9_./-]+`に一致する場合は引用せず表示できる。 +- Interface名とOperation名は、文字列全体が`[A-Za-z0-9_.-]+`に一致する場合は引用せず表示できる。 +- それ以外は成分全体を二重引用符で囲み、JSON stringのescape規則を使用する。単純な成分も引用してよい。 +- `::`と`#`は引用符の外側でだけ境界となる。区切りの前後に空白を出力しない。 + +```text +"/github::archive"::issue.read#read +/github::"issue#read"#read +/github::issue.read#"read#raw" +"/開発"::"課題.read"#read +"/github"::"issue.read"#"read" +``` + +最後の例は`/github::issue.read#read`と同じ成分を表す。引用やescapeは元の値を変えず、ProtocolへASCII制限や禁止文字を追加しない。Unicode normalization、case変換、URL encodingをしない。制御文字等には[名前と文字列](#名前と文字列)の安全なescape規則も適用する。境界を読む場合は引用とescapeを考慮し、単純な文字列splitを使用しない。 + +### Scope省略とcontext + +Scopeの相対pathは、Protocol dataにも短縮表記にも認めない。`github::issue.read`や`../github::issue.read`を相対scopeとして解決しない。Scopeを明示するなら、引用の有無にかかわらずcanonical absolute pathを使う。 + +`issue.read#read`やInterfaceだけの`issue.read`は、scopeが別途明示されたcontextでのみ使える省略形である。Scopeの省略はroot scope `/`の指定とは異なる。Contextがなければ解決できず、rootへのdefault、対象Objectのpathからの推測、祖先の同名Interfaceの探索は行わない。Scopeが確定してもmembership、祖先制約、authorizationは検証する。 + +短縮表記を入力として受けるかはToolやUIが決める。受ける場合は専用の入力境界で成分を検証し、構造化参照とOperation名へ変換する。Signature全体を再parseして呼出先を決めることとは区別し、`invoke`を単一string引数の操作へ変更しない。 + +### Signature内の参照 + +Object signatureとInterface signatureでは、公開先の絶対scopeを含む完全な短縮表記を生成し、その全体をJSON stringとして引用表示する。外側の引用はsignatureの文字列表記であり、成分の引用とは別の層である。例えばscope `/github`、name `issue#read`の参照は`"/github::\"issue#read\""`と表示する。Scopeを省略したり、Upstreamの参照へ戻したりしない。 + ## Object signature ```text object at "/issues/123" { name: "123"; description: "Issue 123の公開操作。本文はOperationで取得する。"; - interfaces: ["issue.read", "issue.lifecycle"]; + interfaces: ["/::issue.read", "/::issue.lifecycle"]; } ``` @@ -46,7 +88,7 @@ Block内は次の順に表示する。 Descriptionがない場合はそのpropertyを省略し、存在する空文字列は`description: "";`と表示する。説明の欠落からObjectの用途を補完しない。 -Rootは`object at "/"`かつ`name: "";`となる。Interface参照は元の値を引用表示し、略称や別の識別子へ置き換えない。例中の`issue.read`等はopaque参照の例であり、参照の命名規則を定めない。 +Rootは`object at "/"`かつ`name: "";`となる。Interface参照は[参照表記](#参照表記)に従い絶対scopeを含め、別の参照やlocal nameだけへ置き換えない。Root ObjectのInterface公開とself-scopeの扱いは[未解決事項](draft/unresolved-issues.md)に残る。 `ref`とvalidatorはObject signatureへ含めない。同一性管理と条件付き実行はClient runtimeの責務のままである。Objectの本文やdomain metadataを推測してpropertyとして追加しない。 @@ -56,7 +98,7 @@ ChildrenもObject signatureに含めない。表示にchildrenがないことは ```text /// "Issueの内容と関連項目を読む。" -interface "issue.read" { +interface "/::issue.read" { type Relation = enum { parent, sibling, related }; type RelatedItems = { @@ -76,7 +118,7 @@ interface "issue.read" { } ``` -Interfaceは`interface "" { ... }`と表示する。Interface参照は元の値を引用表示する。 +Interfaceは`interface "" { ... }`と表示する。``は構造化参照から生成した完全な短縮表記であり、前述の規則で全体を引用表示する。 Block内では、Descriptorの全`types`を宣言順に、続いて全`operations`を宣言順に表示する。Record field、parameter、enum / union caseもすべて元の順序で表示する。この順序はsignature内部の表示規則であり、Protocol上の名前解決やvalidationを変更しない。 @@ -142,7 +184,7 @@ Type名、Operation名、parameter名、field名、case名は次のように表 - 表示keywordは`object`、`at`、`name`、`description`、`interfaces`、`interface`、`type`、`operation`、`enum`、`union`、および`unit`、`boolean`、`integer`、`number`、`string`、`bytes`、`json`、`entry`とする。 ```text -interface "example" { +interface "/::example" { type `string` = { `表示名`: string }; operation `find-item`(`search term`: string) -> `string`; } diff --git a/5.1-wip-over-http.md b/5.1-wip-over-http.md index 32459e7..0acb54e 100644 --- a/5.1-wip-over-http.md +++ b/5.1-wip-over-http.md @@ -127,19 +127,39 @@ JSON encodingには次の規則を適用する。 `Vec`はRFC 4648 Section 4のstandard base64 alphabetを使用し、必要な`=` paddingを含むcanonical base64 stringとしてencodeする。Whitespace、URL-safe alphabet、padding省略、同じoctet列に対する別表現を受理しない。 -Path、Interface参照、Object identity、名前、validatorの意味はJSON scalar自体ではなくfieldの位置によって決まる。 +Path、Interface参照、Object identity、名前、validatorの意味はfieldの位置とProtocolの型によって決まる。 | Logical field | JSON encoding | | --- | --- | | Path / `entry` | canonical absolute Worldspace pathのstring | | Object、Operation、Type、Field、Parameter、Case名 | string | -| Interface参照 | string | +| Interface参照 | `InterfaceReference` object | | `ref` | string | | `format` | string | | Object / Interface validator | canonical base64 string | JSON serializationのwhitespace、escapeの選択、object member順をcanonical化しない。同じlogical valueがbyte-for-byte同一のJSONになることを要求しない。 +## Interface Reference + +`InterfaceReference`は次のexactなJSON objectとしてencodeする。 + +| Field | JSON type | Presence | +| --- | --- | --- | +| `scope` | canonical absolute Worldspace pathのstring | required | +| `name` | 空でないUnicode string | required | + +```json +{ + "scope": "/github", + "name": "issue.read" +} +``` + +`Object.interfaces`の各要素、`FetchInterfaceRequest.interface`、`FetchInterfaceResponse.interface`、`InterfaceTarget.reference`のすべてでこの形を使用する。Scopeの省略、relative scope、`null`、空name、追加member、旧形式のopaque string、`"/github::issue.read"`等の短縮表記stringは認めない。Requestでの違反は`400 Bad Request`と`invalid_request`、responseでの違反はClient-localな`InvalidResponse`とする。 + +参照の比較はJSON decode後の`scope`と`name`の完全一致であり、object member順やJSON escapeの違いは同一性に影響しない。ScopeへURL encoding / decodingを追加せず、name内の`::`や`#`も通常の文字として保持する。ScopeはWorldspace上のpathであり、HTTP endpointのprefixを加えたりscope用のHTTP routeを生成したりしない。合成によるscope変換は[ProtocolのWorldspace composition](3-protocol.md#worldspace-composition)に従う。 + ## ObjectとObjectObservation `Object`は次のJSON objectとしてencodeする。 @@ -148,7 +168,7 @@ JSON serializationのwhitespace、escapeの選択、object member順をcanonical | --- | --- | --- | | `name` | string | required | | `description` | string | optional | -| `interfaces` | stringのarray | required | +| `interfaces` | `InterfaceReference` objectのarray | required | | `ref` | string | optional | | `validator` | canonical base64 string | optional | @@ -159,15 +179,15 @@ JSON serializationのwhitespace、escapeの選択、object member順をcanonical "name": "123", "description": "First item", "interfaces": [ - "item-interface-v1", - "item-marker-interface-v1" + { "scope": "/", "name": "item-interface-v1" }, + { "scope": "/", "name": "item-marker-interface-v1" } ], "ref": "item:123", "validator": "aXRlbS12YWxpZGF0b3I=" } ``` -`interfaces`のarray順はHostの立項順を保持し、重複を含まない。 +`interfaces`のarray順はHostの立項順を保持し、`(scope, name)`の完全一致による重複を含まない。各参照のscopeは観測pathに対してProtocolの祖先制約を満たす。 `ObjectObservation`は次のJSON objectとしてencodeする。 @@ -436,7 +456,7 @@ Success bodyはrootの`ObjectObservation`を直接encodeする。 "object": { "name": "items", "description": "Item collection", - "interfaces": ["item-collection-interface-v1"], + "interfaces": [{ "scope": "/", "name": "item-collection-interface-v1" }], "validator": "cm9vdC12YWxpZGF0b3I=" }, "children": [ @@ -444,7 +464,7 @@ Success bodyはrootの`ObjectObservation`を直接encodeする。 "object": { "name": "123", "description": "First item", - "interfaces": ["item-interface-v1"], + "interfaces": [{ "scope": "/", "name": "item-interface-v1" }], "ref": "item:123", "validator": "aXRlbS12YWxpZGF0b3I=" } @@ -463,11 +483,11 @@ Responseのpath、name、depth、children completenessはrequestと[3. Protocol] | Field | JSON type | Presence | | --- | --- | --- | -| `interface` | Interface参照のstring | required | +| `interface` | `InterfaceReference` object | required | ```json { - "interface": "item-interface-v1" + "interface": { "scope": "/", "name": "item-interface-v1" } } ``` @@ -475,13 +495,13 @@ Responseのpath、name、depth、children completenessはrequestと[3. Protocol] | Field | JSON type | Presence | | --- | --- | --- | -| `interface` | Interface参照のstring | required | +| `interface` | `InterfaceReference` object | required | | `descriptor` | Interface Descriptor object | required | | `validator` | canonical base64 string | optional | ```json { - "interface": "item-interface-v1", + "interface": { "scope": "/", "name": "item-interface-v1" }, "descriptor": { "format": "wip-interface/1", "types": [], @@ -517,7 +537,7 @@ Responseの`interface`はrequestと完全一致しなければならない。Des | Field | JSON type | Presence | | --- | --- | --- | -| `reference` | Interface参照のstring | required | +| `reference` | `InterfaceReference` object | required | | `validator` | canonical base64 string | optional | ```json @@ -527,7 +547,7 @@ Responseの`interface`はrequestと完全一致しなければならない。Des "validator": "b2JqZWN0LXZhbGlkYXRvcg==" }, "interface": { - "reference": "item-interface-v1", + "reference": { "scope": "/", "name": "item-interface-v1" }, "validator": "aW50ZXJmYWNlLXZhbGlkYXRvcg==" }, "operation": "get_related_item", @@ -537,7 +557,7 @@ Responseの`interface`はrequestと完全一致しなければならない。Des } ``` -`interface.reference`と`operation`は別fieldである。表示用の`.`を一つのfieldへencodeしない。 +`interface.reference`と`operation`は別fieldである。表示用の`/::item-interface-v1#get_related_item`を一つのfieldへencodeしない。 HostはDescriptorに依存しない`target`、`interface`、`operation`のshapeを検証し、Protocolのerror precedenceに従って現在のObjectとInterface observationを固定した後、そのDescriptorに従って`arguments`をdecodeする。 diff --git a/draft/dynamic-worldspace-projection.md b/draft/dynamic-worldspace-projection.md index 4b6f7fd..67f3d54 100644 --- a/draft/dynamic-worldspace-projection.md +++ b/draft/dynamic-worldspace-projection.md @@ -6,7 +6,7 @@ 具体的なtrait、class、function、decorator、macro、builderのsyntaxは定義しない。この文書で使用する`Projection Provider`、`Projection Resolution`、`Projected Object`等の名称もworking terminologyであり、canonicalなProtocol typeではない。 -Protocol上の確定事項は[Core Model](../2-core-model.md)、[Object tree / Schema](../2.1-object-tree-schema.md)、[Interface / Operation](../2.2-operation.md)、[Protocol](../3-protocol.md)を参照する。言語別のconceptual API modelは[Rust API Model](rust-api-model.md)と[TypeScript API Model](typescript-api-model.md)で扱う。 +Protocol上の確定事項は[Core Model](../2-core-model.md)、[Object tree / Schema](../2.1-object-tree-schema.md)、[Operation and Interface](../2.2-operation-and-interface.md)、[Protocol](../3-protocol.md)を参照する。言語別のconceptual API modelは[Rust API Model](rust-api-model.md)と[TypeScript API Model](typescript-api-model.md)で扱う。 ## 目的 @@ -81,7 +81,7 @@ Backend failure、cancellation、またはresource budget超過をclean exhausti ProjectionがObjectへ割り当てた各Interface参照は、同じ主体から取得可能なDescriptorへ解決されなければならない。 -複数のObjectは同じInterface参照を共有でき、一つのObjectも複数のInterfaceを組み合わせられる。Validatorを返すInterface参照ではDescriptorを変更でき、同じ参照とvalidatorの組が一つのDescriptor observationを表す。Validatorを返さない参照のDescriptorは、その参照が有効な間immutableである。Interface参照のscope、発行、生成時期、deduplication、cache方法は別途決定する。 +複数のObjectは同じInterface参照を共有でき、一つのObjectも複数のInterfaceを組み合わせられる。Validatorを返すInterface参照ではDescriptorを変更でき、同じ参照とvalidatorの組が一つのDescriptor observationを表す。Validatorを返さない参照のDescriptorは、その参照が有効な間immutableである。Interface参照のscopeは[2.2. Operation and Interface](../2.2-operation-and-interface.md#interfaceの識別とscope)に従う。登録API、生成時期、deduplication、cacheの具体実装は別途決定する。 ### `call_operation` @@ -262,7 +262,7 @@ Composition後も、同じ主体へ公開されたWorldspace全体で`ref`とInt - 同じ有効なInterface参照とvalidatorの組を異なるDescriptorへ対応付けない。 - Validator比較がProvider routingの変更によって別Objectへ適用されない。 -Interface参照のnamespace案は[Scoped Interface References(草案)](interface-scope.md)で扱う。Worldspaceの絶対pathをscopeとし、Objectの祖先制約と、合成後の公開位置に合わせたHostの参照変換を検討する。Objectの`ref`の具体的な発行方式は引き続き未決定とする。 +Interface参照は[2.2. Operation and Interface](../2.2-operation-and-interface.md#interfaceの識別とscope)の構造化参照を使用する。Objectの祖先制約と、合成後のscope・path・typed `entry`の変換は[ProtocolのWorldspace composition](../3-protocol.md#worldspace-composition)に従う。Objectの`ref`の具体的な発行方式は引き続き未決定とする。 ただし、mount API、path routing、Provider間のparent / child関係、同名entry conflict、cross-provider Operation、transaction boundaryは未決定である。ProtocolはHost内部のcomposition方式を公開しないため、Host APIでこれらをどこまで標準化するかを別途検討する。 diff --git a/draft/interface-scope.md b/draft/interface-scope.md deleted file mode 100644 index ddd35bb..0000000 --- a/draft/interface-scope.md +++ /dev/null @@ -1,206 +0,0 @@ -# Scoped Interface References(草案) - -## 位置付け - -Interface参照にWorldspace上のpathをscopeとして持たせ、独立したProviderやWorldspaceが定義したInterfaceを、Hostによる合成後も衝突なく公開するためのProtocol変更案である。 - -この草案では、次を設計方針とする。 - -- Interface参照は、絶対pathのscopeと、そのscope内のlocal nameから構成する。 -- Objectが公開できるInterfaceは、Objectの配置pathの祖先をscopeに持つものに制限する。 -- 絶対pathは、Clientに対してHostが公開するWorldspaceのrootを基準とする。 -- ProxyやWorldspace合成によって公開位置が変わる場合、Clientへ見せるpathとInterface参照を移動後の配置へ変換するのはHostの責務とする。 - -現行の[3. Protocol](../3-protocol.md)ではInterface参照全体をopaque stringとして扱っている。本案はその一部に構造と意味を与えるものであり、単なる表示上の修飾ではない。Canonical文書へ採用するまでは草案として扱い、未確定の構文や境界条件を末尾にまとめる。 - -## Interface参照のデータ構造 - -Interface参照は`scope`とlocal nameを別々に持つ構造化データとする。Operationの指定は、その参照とOperation名を組み合わせる。以下はlogicalな構成の例であり、request全体のwire schemaではない。 - -```text -interface = { - scope = "/" - name = "issue.read" -} -operation = "read" -``` - -`scope`、Interfaceの`name`、`operation`はClient内部でも別々に保持する。後述の短縮表記をProtocol上の正本やcache keyとして扱わない。現行Protocolのopaque stringから、この構造化参照への移行は別途行う。 - -- `scope`はHostが公開するWorldspace内のcanonical absolute path。 -- `name`はそのscope内でInterfaceを識別するlocal name。例の`issue.read`に含まれる`.`はObjectの階層やOperation名との区切りを意味しない。 -- Interfaceはscopeとlocal nameの組で識別する。同じscope内の異なるInterfaceへ同じlocal nameを割り当てない。 -- 同じlocal nameでもscopeが異なれば別の参照である。Descriptorの内容が似ていても同一性を推測しない。 -- 同じscopeに複数のProviderを登録する場合、そのscope内の名前の衝突はHostが検出・解消する。Scopeを付けるだけで同一scope内の重複が自動的に解消されるわけではない。 - -Scopeはbackendのpath、OSのfilesystem root、URL origin、HTTP endpointのprefixではない。例えばHTTP endpointが`https://example.test/wip`でも、Worldspaceのscopeは`/github`であり、`/wip/github`へ自動的に変わるわけではない。 - -Scope pathの比較にはProtocolのpath規則を用いる。Unicode normalization、case変換、URL decode、文字列prefixだけによる祖先判定は行わない。`/github`は`/github-extra`の祖先ではない。 - -## 人間・AI向けの短縮表記 - -ScopeとInterfaceの境界には`::`、InterfaceとOperationの境界には`#`を使う。境界ごとに異なる記号を用いることで、scopeまたはOperationを省略した表記も区別できる。 - -| 対象 | 表記 | 含まれる成分 | -| --- | --- | --- | -| 完全なOperation指定 | `/github::issue.read#read` | scope、Interface名、Operation名 | -| 完全なInterface参照 | `/github::issue.read` | scope、Interface名 | -| Scope省略のOperation指定 | `issue.read#read` | Interface名、Operation名 | -| Root scopeのOperation指定 | `/::issue.read#read` | scope `/`、Interface名、Operation名 | - -`/github::issue.read#read`は`scope = "/github"`、`name = "issue.read"`、`operation = "read"`に対応する。`#read`はInterface名の一部ではない。短縮表記には呼び出し対象Objectのpath、arguments、validatorは含まれず、これだけでOperation request全体を表すものではない。 - -### 成分の引用 - -各成分は次の規則で表示する。 - -- Scopeはcanonical pathであり、文字列全体が`[A-Za-z0-9_./-]+`に一致する場合は引用せずに表示できる。 -- Interface名とOperation名は、文字列全体が`[A-Za-z0-9_.-]+`に一致する場合は引用せずに表示できる。 -- それ以外は成分全体を二重引用符で囲み、JSON stringのescape規則を使う。単純な成分も引用してよい。 -- `::`と`#`は引用符の外側にある場合だけ境界となる。区切りの前後に空白は出力しない。 - -この規則は表示のためのものであり、pathや名前の文字種をASCIIへ制限しない。引用を外した元の値には、それぞれのProtocol validationを適用する。Unicode normalization、case変換、percent encodingは行わない。制御文字等の安全な表示には[4.2. Text Viewの文字列規則](../4.2-text-view.md#名前と文字列)を適用する。 - -```text -"/github::archive"::issue.read#read -/github::"issue#read"#read -/github::issue.read#"read#raw" -"/開発"::"課題.read"#read -"/github"::"issue.read"#"read" -``` - -最後の例と`/github::issue.read#read`は同じ成分を表す。`::`や`#`がpath segmentに含まれていても引用によって区別できるため、既存のpath規則へ禁止文字を追加しない。引用とescapeを考慮して境界を判定し、文字列を単純に`::`や`#`でsplitしてはならない。 - -### Scope省略と解決context - -`issue.read#read`は、scopeが別途明示されたcontextで使う相対的な表記である。Scopeの省略とroot scope `/`の指定は異なる。 - -- 表示・入力を扱う側が明示的に保持するscope contextがある場合、そのscopeとInterface名を組み合わせる。 -- Contextがなければ完全な参照へ解決できない。Rootへのdefault、対象Objectのpathからの推測、祖先の同名Interfaceの探索は行わない。 -- Contextでscopeが確定しても、対象ObjectのInterface membership、祖先制約、authorizationの検証は省略しない。 - -短縮表記を入力として受け付けるかはToolやUIが決める。受け付ける場合はその入力境界で成分を取り出して検証し、構造化された参照とOperation名へ変換する。Object / Interface signature等の表示text全体を再parseして呼出先を決めることとは区別する。本案は`invoke`の引数を短縮表記の単一stringへ変更するものではない。 - -## Objectとscopeの関係 - -Objectをpath `P`で公開するとき、`Object.interfaces`の各参照のscope `S`は、`P`へ至る祖先chain上にある必要がある。「祖先」は直近のparentだけでなく、rootからparentまでの各pathを含む。兄弟や別subtreeのscopeは使用できない。 - -`/github/my-rep/issues`の場合は次のようになる。 - -| Interface参照 | このObjectでの利用 | 理由 | -| --- | --- | --- | -| `/::common.read` | 可 | `/`は祖先 | -| `/github::issue.read` | 可 | `/github`は祖先 | -| `/github/my-rep::issue.admin` | 可 | `/github/my-rep`はparent | -| `/gitlab::issue.read` | 不可 | 別subtree | -| `/github/other-rep::issue.read` | 不可 | 祖先ではない | -| `/github/my-rep/issues/123::issue.read` | 不可 | 子孫であって祖先ではない | - -Object自身のpathをscopeとして認めるかは、root ObjectのInterfaceも含めて未確定とする。この草案の通常例はstrict ancestorを使用し、self-scopeを暗黙に導入しない。 - -この制約はInterfaceの自動継承ではない。祖先scopeで宣言されたInterfaceが、配下のすべてのObjectへ自動的に追加されるわけではない。Objectが明示的に公開した`interfaces`のmembershipと、scopeの祖先制約の両方を満たす必要がある。 - -Scopeが祖先であることもauthorizationの証明ではない。現在の主体への公開可視性、Operationの実行権限、validatorによるpreconditionは従来どおり検証する。 - -## Clientによる解決 - -ClientはObjectを観測したpathと、そこに公開された完全なInterface参照を使用する。 - -1. `observe`のrequest pathと各Objectの`name`から配置pathを得る。 -2. `Object.interfaces`の各参照についてscopeがその配置pathの祖先であることを検証する。 -3. 条件を満たす構造化参照を、scopeとlocal nameを保持したまま`fetch_interface`へ渡す。 -4. Operation callでは同じ構造化参照をInterface targetへ設定し、Operation名は従来どおり別fieldへ設定する。現行の`InterfaceTarget.reference`等の具体的な型変更はProtocol採用時に反映する。 - -Hostは祖先制約に違反する参照をObjectへ公開してはならない。ClientはそのようなObject responseをProtocol違反として扱い、その参照を対象ObjectのInterfaceとして解決・使用しない。既存の分類に合わせ、Client-localな`InvalidResponse`として拒否する案とする。 - -Local nameだけによる検索、近い祖先から順に同名Interfaceを探すlookup、shadowingは導入しない。Scope省略の短縮表記は前節の明示的なcontextで解決してから、この手順へ渡す。`/::issue.read`と`/github::issue.read`の両方が公開されている場合も、完全な構造化参照で明示的に区別する。 - -`fetch_interface`は完全な参照を受け取るため、祖先Objectを順に取得する必要はない。現行requestには対象Objectのpathがないので、「どのObjectから利用するか」の祖先検証はObject観測時とOperation call時に行う。Interface単独の取得可否はHostの公開可視性によって決まり、scope外のObjectから使えないこととDescriptor自体を取得できないことは同一視しない。 - -Hostも`call_operation`で、対象Objectに対するmembershipとscopeの適合を検証する。Clientの検証だけを信頼しない。Scope不適合を含むrequestのerror mappingと検証順は、既存の`InvalidRequest` / `InterfaceMismatch`等との整合を含めて確定する。 - -Operation名とNamed typeのnamespaceは引き続きInterface Descriptor内に閉じる。本案はexternal type importやInterface間の型参照を追加しない。 - -## HostによるproxyとWorldspace合成 - -Clientが扱う絶対pathは、常に接続先HostのClient-facing Worldspaceのrootに基づく。Upstreamのrootや内部mount構成をClientに追跡・補完させない。 - -Upstream Worldspaceのrootを`/github`へ配置する例を示す。表中のInterface参照は構造化されたscopeとlocal nameの短縮表記であり、連結stringをwireへ送る意味ではない。 - -| 項目 | Upstreamでの値 | Clientへ公開する値 | -| --- | --- | --- | -| Root | `/` | `/github` | -| Objectの配置path | `/my-rep/issues` | `/github/my-rep/issues` | -| Interface参照 | `/::issue.read` | `/github::issue.read` | -| Repository scopeの参照 | `/my-rep::issue.admin` | `/github/my-rep::issue.admin` | -| `entry`型のpath | `/my-rep/issues/123` | `/github/my-rep/issues/123` | - -別のUpstreamを`/gitlab`へ配置すれば、その`/::issue.read`は`/gitlab::issue.read`となり、GitHub側と衝突しない。 - -さらにこの合成Worldspace全体を`/services`へ配置するHostは、次のように再変換する。 - -```text -/github/my-rep/issues -> /services/github/my-rep/issues -/github::issue.read -> /services/github::issue.read -/gitlab::issue.read -> /services/gitlab::issue.read -``` - -各Hostは自分がClientへ公開する座標系について責任を持つ。単にHTTP requestを中継してWorldspaceの配置を変えないproxyは、scopeを変更する必要がない。 - -### 変換する箇所 - -合成Hostは、表示だけでなくProtocol上の対応を一貫させる。 - -- `observe`のrequest pathをUpstream側へ変換し、返されるObjectの配置・`name`・childrenが公開先のpath規則を満たすようにする。特にUpstream rootの空の`name`を非rootのmount先へそのまま公開しない。 -- `Object.interfaces`のscopeを公開先へ変換する。 -- Clientの`fetch_interface`参照を適切なUpstreamとその参照へ対応付け、responseの`interface`はClientが要求した公開先の参照にする。 -- `call_operation`のtarget pathとInterface参照をUpstream側へ対応付ける。転送先はlocal name単独ではなく完全な参照とtargetの対応で決める。 -- Descriptorで`entry`と宣言されたargumentsをUpstream側へ、resultを公開先へ変換する。Record、list、union、Named typeを辿った内部の`entry`も対象にする。 - -通常の`string`、opaqueな`json`、documentation内のpathらしい文字列を推測して書き換えない。Application固有のdataに別の座標系がある場合は、そのApplication adapterの責務として扱う。 - -型として正しいUpstream pathであっても、公開先へ対応付けられないpathをそのまま返してはならない。公開subtreeの外への`entry`やscopeへの参照をどう扱うかは、明示的な対応付けまたは公開・実行の拒否を含め、Hostの合成方針として定める。Scopeを単に削除したりrootへ付け替えたりして制約を回避しない。 - -### 名前・同一性・validator - -公開先の参照は、移動後のscopeとlocal nameの組に対して衝突なく登録する。配置変更後に同じlocal nameを維持しても、scopeが変わればProtocol上は別の参照である。古い参照と新しい参照の同一性をClientへ推測させない。 - -Scopeの変換だけでObjectの`ref`やvalidatorの安全性が保証されるわけではない。合成Hostは既存の同一性・観測整合性の規則も満たす必要がある。 - -- 異なるUpstreamのObjectへ同じ有効な公開`ref`を割り当てない。 -- 同じ公開Interface参照とvalidatorの組を、異なるDescriptorへ対応付けない。 -- Routingやmountの変更後に、古いObject validatorで別の対象へOperationを実行できないようにする。 -- Upstream validatorをそのまま利用するかHost側で対応付け・wrapするかは、これらの保証を満たす範囲でHostが決める。 - -同じUpstream Objectを複数のscope配下へ配置すると、公開するInterface参照が配置ごとに変わり得る。現行Protocolは同じ有効な`ref`とvalidatorのObject representationが一致することを要求するため、異なるInterface集合を持つprojectionへ同じ公開identityを無条件に引き継げない。この場合の共通祖先scopeでの共有、projectionごとのidentity割当等は、採用前に整理する。 - -## Cacheと表示 - -Interface cacheはClient-facing Worldspaceの接続先・主体等のcontextで分離した上で、構造化参照の`(scope, name)`とoptionalなvalidatorに基づいて扱う。引用やescapeの違いは別参照を作らない。異なるWorldspaceに同じ`/github::issue.read`があっても、同一Interfaceとはみなさない。ScopeはグローバルなURL namespaceではない。 - -本案を[4.2. Text View](../4.2-text-view.md)へ適用するときは、公開先の構造化参照からscopeを含む短縮表記を生成し、参照の表示位置へ引用表示する。そこでの外側の引用はText Viewの文字列表記であり、短縮表記の成分を引用する規則とは別の層である。表示側でscopeを省略したり、Upstreamの参照へ戻したりしない。 - -```text -object at "/github/my-rep/issues" { - name: "issues"; - description: "RepositoryのIssue collection。"; - interfaces: ["/github::issue.read"]; -} - -interface "/github::issue.read" { - operation list() -> { items: [entry] }; -} -``` - -Text Viewがscopeを定義するのではなく、採用後のProtocol参照を表示する。現在のText Viewのopaque参照例は、Protocol側の採用時に更新する。 - -## 採用前に詰める点 - -- **Self-scopeとroot Object**:Object自身のpathをscopeとして許すか。Strict ancestorだけではroot Objectに利用可能なscopeがないため、rootの扱いを含めて決める。 -- **Protocolへの移行**:既存opaque参照から構造化された`scope` / `name`への移行、request / response fieldへの配置、Transport Bindingのencoding。`::` / `#`と成分の引用は短縮表記として定義済みであり、wire上の単一string encodingにはしない。 -- **Scopeの公開単位**:scope登録とそのpathのObjectの公開・削除の関係。祖先Object自身が同じInterfaceを公開することは要求しないが、registryのlifecycleを定める必要がある。 -- **有効期間と移動**:scopeのrename、mountの付け替え、同じpathへの再登録、進行中callおよび古いcacheの扱い。 -- **複数配置と部分合成**:同じObjectを複数scopeへ投影する場合の`ref`、切り出したsubtreeの外にあるscope・`entry`への対応付け。 -- **Failure semantics**:不正な参照構文、scope不適合、未公開scope / Interface、変換不能な`entry`に対するerrorと、既存の検証順・非公開情報の秘匿との整合。 - -本案はInterface参照のscopeとHostの公開座標変換を定義するためのものであり、Host内部のmount API、Provider登録API、合成設定の共通data structureを同時に規定しない。 diff --git a/draft/rust-api-model.md b/draft/rust-api-model.md index 07342df..b3cfe6d 100644 --- a/draft/rust-api-model.md +++ b/draft/rust-api-model.md @@ -6,7 +6,7 @@ このdraftで示すtrait名、attribute、derive、generated type名、method signatureは説明用であり、具体的なRust API syntaxとして確定しない。Ownership、lifetime、async runtime、error type、macro crate構成も未決定である。 -Protocol上の確定事項は[Core Model](../2-core-model.md)、[Object tree / Schema](../2.1-object-tree-schema.md)、[Interface / Operation](../2.2-operation.md)、[Protocol](../3-protocol.md)を参照する。動的なObject projectionの運用要件は[Dynamic Worldspace Projection](dynamic-worldspace-projection.md)、対応するTypeScript modelは[TypeScript API Model](typescript-api-model.md)を参照する。 +Protocol上の確定事項は[Core Model](../2-core-model.md)、[Object tree / Schema](../2.1-object-tree-schema.md)、[Operation and Interface](../2.2-operation-and-interface.md)、[Protocol](../3-protocol.md)を参照する。動的なObject projectionの運用要件は[Dynamic Worldspace Projection](dynamic-worldspace-projection.md)、対応するTypeScript modelは[TypeScript API Model](typescript-api-model.md)を参照する。 ## 目的 @@ -52,7 +52,7 @@ trait FileInterface { Trait declarationは、次のlogical declarationに対応する。 - 一つのtrait declarationを、一つのInterface Descriptorを生成するRust側definitionとして扱う。 -- Trait名はgenerated Rust itemやlocal registrationを識別するために使用できるが、Protocol `InterfaceDescriptor`のfieldやopaqueなInterface参照としてそのまま公開しない。 +- Trait名はgenerated Rust itemやlocal registrationを識別するために使用できるが、Protocol `InterfaceDescriptor`のfieldや構造化されたInterface参照としてそのまま公開しない。 - Trait methodをOperation Declarationとして扱う。 - ReceiverはProtocol parameterに含めない。 - Method parameterを名前付きOperation parameterとして扱う。 @@ -179,7 +179,7 @@ Object { } ``` -`selected_interface_references`は、Hostが各generated Interface Definitionを登録または公開するときに割り当てるopaque参照を、publication APIへの追加順で並べたものである。同じ参照の重複は拒否する。Macroが特定のwire参照文字列をcompile timeに固定することは要求しない。 +`selected_interface_references`は、Hostが各generated Interface Definitionを登録または公開するときに割り当てる構造化参照`{ scope, name }`を、publication APIへの追加順で並べたものである。同じ`(scope, name)`の重複は拒否し、Objectの配置pathに対する祖先制約も検証する。Macroが参照をcompile timeに固定することは要求しない。 `observe`はDescriptor自体をObjectへ埋め込まず、このInterface参照のordered setだけを返す。Clientが各参照を`fetch_interface`したとき、Host Runtimeはtrait declarationから生成されたDescriptorと、存在する場合はInterface validatorを返す。同じ参照とvalidatorの組のDescriptorはHost上で共有およびcacheできるため、Object instanceごとにDescriptorを再生成または再送する必要はない。 @@ -350,7 +350,7 @@ object Protocol Objectの`interfaces`は追加順を保持するordered setである。同じInterface参照の重複は拒否する。各Interface Descriptorは独立したOperation集合を宣言し、複数trait implementationを一つのDescriptorへ暗黙にmergeしない。 -異なるInterfaceは同じOperation名を宣言できる。Dispatchはrequestの`InterfaceTarget.reference`とOperation名の組で一意に決まり、表示上の曖昧さがある場合は`.`でqualifyできる。この表示文字列をProtocol request fieldへparseし直さない。 +異なるInterfaceは同じOperation名を宣言できる。Dispatchはrequestの`InterfaceTarget.reference`とOperation名の組で一意に決まり、表示上のqualified表記は[Text Viewの参照表記](../4.2-text-view.md#参照表記)に従う。Signature全体をProtocol request fieldへparseし直さない。 Rust traitのsupertrait、trait alias、複数traitの組み合わせをDescriptor生成へどう対応付けるかは未決定であり、Protocol上のInterface inheritanceを暗黙に導入しない。 @@ -373,7 +373,9 @@ Sugarを使用する場合も、対象typeが指定されたすべてのInterfac ## HostへのInterface登録 -Generated Interface DefinitionをHostへ登録し、opaqueなInterface参照を割り当てる必要がある。 +Generated Interface DefinitionをHostへ登録し、構造化されたInterface参照を割り当てる必要がある。 + +参照の絶対scopeとlocal name、および配置pathへの祖先制約は[2.2. Operation and Interface](../2.2-operation-and-interface.md#interfaceの識別とscope)に従う。以下のconceptual API例はscope / nameを渡す具体構文を省略しており、暗黙のroot scopeを定めるものではない。登録時のcontextと引数、self-scope、scope lifecycleは引き続き未決定である。 Conceptualには、eager registrationとlazy registrationの両方が考えられる。 @@ -474,7 +476,7 @@ Rust API modelは少なくとも次を満たす。 - Object metadata取得をsyncまたはasyncのどちらにするか。 - Publication APIがObject instanceをown、borrow、`Arc`化するか。 - Generated Interface Definitionの具体的なRust表現。 -- Interface登録とopaque参照発行のlifecycle。 +- Interface登録とscope / local name割当のlifecycle。 - Trait、Operation、parameter名のrename規則。 - Rust doc commentとProtocol Documentationの対応。 - Supported Rust typeと`TypeExpr`の対応。 diff --git a/draft/typescript-api-model.md b/draft/typescript-api-model.md index 7b4fc92..fb8eaa8 100644 --- a/draft/typescript-api-model.md +++ b/draft/typescript-api-model.md @@ -6,7 +6,7 @@ このdraftで示すfunction、object shape、generic type、class、method signatureは説明用であり、具体的なTypeScript API syntaxとして確定しない。Package構成、schema builderの最終名称、ownership、async context、error type、bundler integrationも未決定である。 -Protocol上の確定事項は[Core Model](../2-core-model.md)、[Object tree / Schema](../2.1-object-tree-schema.md)、[Interface / Operation](../2.2-operation.md)、[Protocol](../3-protocol.md)を参照する。動的なObject projectionの運用要件は[Dynamic Worldspace Projection](dynamic-worldspace-projection.md)、対応するRust modelは[Rust API Model](rust-api-model.md)を参照する。 +Protocol上の確定事項は[Core Model](../2-core-model.md)、[Object tree / Schema](../2.1-object-tree-schema.md)、[Operation and Interface](../2.2-operation-and-interface.md)、[Protocol](../3-protocol.md)を参照する。動的なObject projectionの運用要件は[Dynamic Worldspace Projection](dynamic-worldspace-projection.md)、対応するRust modelは[Rust API Model](rust-api-model.md)を参照する。 ## 目的 @@ -130,7 +130,7 @@ const FileInterface = wip.interface({ Interface definitionは、次のlogical declarationに対応する。 - 一つのruntime definition objectを、一つのInterface Descriptorを構築するTypeScript側definitionとして扱う。 -- JavaScript variable名`FileInterface`はlocal code上の識別子であり、Protocol `InterfaceDescriptor`のfieldやopaqueなInterface参照としてそのまま公開しない。 +- JavaScript variable名`FileInterface`はlocal code上の識別子であり、Protocol `InterfaceDescriptor`のfieldや構造化されたInterface参照としてそのまま公開しない。 - 各Operation definitionが保持するstableなstringをOperation Declarationの`name`として扱う。 - `parameters`で宣言されたstableなstringを名前付きOperation parameterとして扱う。 - `returns`をOperation return typeとして扱う。 @@ -303,7 +303,7 @@ const protocolObject = { Optional propertyの`undefined`はwireへ出力せず、field省略として扱う。`null`へ自動変換しない。 -`selectedInterfaceReferences`は、Hostが各runtime Interface definitionを登録または公開するときに割り当てるopaque参照を、publication APIへの追加順で並べたものである。同じ参照の重複は拒否する。Variable名やJavaScript object identityをportableなProtocol参照としてそのまま使用することは要求しない。 +`selectedInterfaceReferences`は、Hostが各runtime Interface definitionを登録または公開するときに割り当てる構造化参照`{ scope, name }`を、publication APIへの追加順で並べたものである。同じ`(scope, name)`の重複は拒否し、Objectの配置pathに対する祖先制約も検証する。Variable名やJavaScript object identityをportableなProtocol参照としてそのまま使用することは要求しない。 `observe`はDescriptor自体をObjectへ埋め込まず、このInterface参照のordered setだけを返す。Clientが各参照を`fetch_interface`したとき、Host Runtimeはruntime definition objectから構築したDescriptorと、存在する場合はInterface validatorを返す。同じ参照とvalidatorの組のDescriptorはHost上で共有およびcacheできるため、Object instanceごとにDescriptorを再生成または再送する必要はない。 @@ -519,13 +519,15 @@ const object = wip.publish(file) }); ``` -表示上の曖昧さがある場合は`.`でqualifyできる。この表示文字列をProtocol request fieldへparseし直さない。 +表示上のqualified表記は[Text Viewの参照表記](../4.2-text-view.md#参照表記)に従う。Signature全体をProtocol request fieldへparseし直さない。 Intersection type、interface extension、mixin等をDescriptorのcompositionへ自動変換しない。Protocol上のInterface inheritanceを暗黙に導入しない。 ## HostへのInterface登録 -Runtime Interface definitionをHostへ登録し、opaqueなInterface参照を割り当てる必要がある。 +Runtime Interface definitionをHostへ登録し、構造化されたInterface参照を割り当てる必要がある。 + +参照の絶対scopeとlocal name、および配置pathへの祖先制約は[2.2. Operation and Interface](../2.2-operation-and-interface.md#interfaceの識別とscope)に従う。以下のconceptual API例はscope / nameを渡す具体構文を省略しており、暗黙のroot scopeを定めるものではない。登録時のcontextと引数、self-scope、scope lifecycleは引き続き未決定である。 Conceptualには、eager registrationとlazy registrationの両方が考えられる。 @@ -674,7 +676,7 @@ TypeScript API modelは少なくとも次を満たす。 - `wip.interface`、`wip.operation`、type builderの最終syntax。 - `wip.Infer`と`wip.Implementation`の具体的なgeneric type。 - `strictFunctionTypes`を含むminimum TypeScript compiler settings。 -- Interface登録とopaque参照発行のlifecycle。 +- Interface登録とscope / local name割当のlifecycle。 - 登録時にruntime definitionをdeep freezeするか、immutableなDescriptor / dispatch snapshotへ変換するか。 - Operation、parameter、type、field、caseのrename規則。 - Documentationのauthoring syntax。 diff --git a/draft/unresolved-issues.md b/draft/unresolved-issues.md index 3459faa..bb43802 100644 --- a/draft/unresolved-issues.md +++ b/draft/unresolved-issues.md @@ -2,9 +2,9 @@ 主要な未解決事項を、canonicalなCore文書へのindexとしてまとめる。 -## 2.2. Interface / Operation +## 2.2. Operation and Interface -対象: [2.2. Interface / Operation](../2.2-operation.md) +対象: [2.2. Operation and Interface](../2.2-operation-and-interface.md) - RustとTypeScriptの動的Worldspace Projection Host API。[運用と要件のdraft](dynamic-worldspace-projection.md) - RustとTypeScriptのcode-level Interface Declaration / Object publication API。[Rust API model](rust-api-model.md) / [TypeScript API model](typescript-api-model.md)のdraft @@ -17,9 +17,17 @@ 対象: [3. Protocol](../3-protocol.md) -### Field semantics +### Interface scopeとcomposition -- `Object.interfaces`、`fetch_interface`、`InterfaceTarget.reference`の参照scopeと有効期間。[Scoped Interface References(草案)](interface-scope.md)で、絶対pathによるscope、Objectの祖先制約、proxy / Worldspace合成時のHostによる座標変換を検討する。 +構造化参照と絶対scopeは[2.2. Operation and Interface](../2.2-operation-and-interface.md#interfaceの識別とscope)、fieldとHost変換は[3. Protocol](../3-protocol.md#worldspace-composition)、短縮表記は[4.2. Text View](../4.2-text-view.md#参照表記)、JSON encodingは[5.1. WIP over HTTP](../5.1-wip-over-http.md#interface-reference)へ統合済み。残る論点は次のとおり。 + +- **Self-scopeとroot Object**:Object自身のpathをscopeにできるか。確定済みのstrict ancestor規則だけではroot Objectに利用可能なscopeがないため、rootへの適用を含めて決める。 +- **Scopeの公開単位**:scope登録と、そのpathのObjectの公開・削除の関係。Scopeの祖先Objectが同じInterfaceを公開することは要求しないが、registryのlifecycleは未確定。 +- **有効期間と移動**:scopeのrename、mount変更、同じpathへの再登録、進行中callと古いcacheの扱い。Scopeが変われば別参照であることと、既存のvalidator保証は維持する。 +- **複数配置とidentity**:同じUpstream Objectを複数scopeへ投影する場合の共通祖先scopeでの共有やprojectionごとの`ref`・validator。同じ`ref`とvalidatorで異なるrepresentationを返せるようにはしない。 +- **部分合成と拒否条件**:公開subtree外のscope・typed `entry`への対応付け、対応不能時の公開・実行拒否とerror mapping。非公開情報の秘匿と既存のerror precedenceを維持し、effectがcommit済みか不明なcallを未実行保証のerrorへ置き換えない。 + +Host内部のmount API、Provider登録API、合成設定の共通data structureは引き続きHost API draftで検討する。 ### Type / Value