|
|
|
@@ -52,21 +52,47 @@ The interface descriptor uses WIP `Json` for compatibility input and includes th
|
|
|
|
|
|
|
|
|
|
## Native projection extension and collisions
|
|
|
|
|
|
|
|
|
|
`worker::wip::WipMountRegistry` is the Host-owned mount allocator. A Feature can independently construct a `WipProjection` with an async `WipOperationHandler`, then pass its aggregate registry through `install_wip_mode_with_mounts` before compatibility finalization. A Feature first requests a Host-owned `/features/<feature>` namespace with `allocate_feature_route`; checked direct-child joins prevent a Feature from claiming an ambient global route.
|
|
|
|
|
`worker::wip::WipMountRegistry` is the Host-owned namespace, Object, and operation registry. A provider requests a root namespace with `allocate_namespace(owner, namespace)`; the owner is retained as Host metadata and is not inserted into the public path. It then mounts the collection Object directly at `/<namespace>` and may install a bounded direct-child resolver. Features do not appear as intermediate Objects.
|
|
|
|
|
|
|
|
|
|
- Routes must be canonical absolute WIP paths.
|
|
|
|
|
Object resolution and operations are separate contracts. One mounted `WipProjection` owns a static Object route and its initial operations. Another Feature may add operations with `contribute_operations` without replacing that Object. Dynamic families likewise keep one `WipDynamicItemResolver`, while `contribute_dynamic_operations` supplies disjoint handlers for every resolved item without a second resolver. The Host merges only contributions with the same interface format, documentation, and type declarations; duplicate operation names, inconsistent interfaces/validators, missing targets, duplicate namespace owners, and unrelated route claims fail deterministically at registration. The merged interface validator changes with the effective operation set, so stale Known Space cannot authorize a newly contributed operation.
|
|
|
|
|
|
|
|
|
|
- Routes must be canonical absolute WIP paths, and allocated namespaces are one lowercase root segment.
|
|
|
|
|
- Object names must match the final route segment.
|
|
|
|
|
- A projected object exposes exactly its declared interface.
|
|
|
|
|
- Unrelated duplicate routes and conflicting interface descriptors or validators fail startup.
|
|
|
|
|
- Object existence and resolution have one owner; operation contributors cannot remount or substitute the Object.
|
|
|
|
|
- Multiple Features may contribute disjoint operations to the same Object interface.
|
|
|
|
|
- Unrelated duplicate routes, duplicate operation names, and conflicting interface shapes fail startup.
|
|
|
|
|
- A bounded dynamic mount may resolve exactly one item segment below an already mounted native collection; deeper paths never fall through to the resolver.
|
|
|
|
|
- A native projection replaces a compatibility projection either by the original same-route semantic capability or by an explicit registry capability claim owned by a mounted native route.
|
|
|
|
|
- Conflicting native claims fail startup. When native is selected, the claimed compatibility tool is hidden rather than exposed through a second entry. Normal Tool mode is unaffected because it does not install the WIP registry.
|
|
|
|
|
|
|
|
|
|
`WipInspect` renders the complete descriptor, including descriptor-local named declarations and recursive record, list, enum, and union shapes with required flags and declaration documentation. The unit samples `mount_collision_and_native_replacement_are_explicit` and `native_projection_preserves_descriptor_and_decodes_typed_arguments_end_to_end` demonstrate independent native registration, deterministic replacement, collision rejection, complete descriptor inspection, and a descriptor-typed native invocation.
|
|
|
|
|
`WipInspect` renders the complete effective descriptor, including contributed operations, descriptor-local named declarations, and recursive record, list, enum, and union shapes with required flags and declaration documentation. The tests `host_namespace_object_resolution_and_operation_contributions_are_independent`, `operation_contributions_reject_interface_and_target_conflicts`, and `native_projection_preserves_descriptor_and_decodes_typed_arguments_end_to_end` demonstrate root allocation, unique resolution, contribution merging, collision rejection, current call-time authorization, complete descriptor inspection, and descriptor-typed invocation.
|
|
|
|
|
|
|
|
|
|
The built-in native route migration is:
|
|
|
|
|
|
|
|
|
|
| Historical route | Canonical route |
|
|
|
|
|
| --- | --- |
|
|
|
|
|
| `/features/ticket/tickets[/<reference>]` | `/tickets[/<reference>]` |
|
|
|
|
|
| `/features/objective/objectives[/<reference>]` | `/objectives[/<reference>]` |
|
|
|
|
|
| `/features/merge-request/merge-requests[/<reference>]` | `/merge-requests[/<reference>]` |
|
|
|
|
|
|
|
|
|
|
`/repositories` and `/workdirs` can be allocated by a later provider using the same registration contract; this layer does not implement or pre-allocate those domains. `/checkouts` content projection is likewise outside this contract.
|
|
|
|
|
|
|
|
|
|
### Registering a subsequent provider
|
|
|
|
|
|
|
|
|
|
1. Allocate `allocate_namespace("repository", "repositories")`. The returned `WipNamespaceRoute::root()` is `/repositories`; the owner is independent of any Feature registration name.
|
|
|
|
|
2. Mount a native collection `WipProjection` at that root with capability `repository:collection`, matching Object name and one declared interface. Static Objects underneath the root use the same capability owner prefix. A mounted collection retains its own identity, interfaces, and validator even when it has static children.
|
|
|
|
|
3. For dynamic items, register one `WipDynamicMount` on the collection with capability `repository:item`. A foreign capability owner is rejected. Its `WipDynamicItemResolver` owns reference acceptance, Object identity, and current Object validator. It returns only a bounded direct child; it must not reinterpret a reference as another namespace or grant permission from existence.
|
|
|
|
|
4. The reference provider supplies its read operations and handlers independently of management Feature enablement. An Object-only provider may use an empty operation descriptor. Enabled management Features register `WipOperationContribution` for static Objects or `WipDynamicOperationContribution` for a dynamic family; they do not allocate the namespace again or replace its resolver.
|
|
|
|
|
5. Contributions use the existing interface reference and identical format, documentation, and type declarations, supplying only their new operations. Interface references are global: extending a descriptor that is also mounted elsewhere must not create different descriptors/validators under the same reference (registration fails). Use separate references for collection and item contracts. Failed contributions leave the registry unchanged.
|
|
|
|
|
6. Handlers are responsible for checking current target capability and current subject authorization before dispatch. Registration/discovery is metadata, not a grant. A resolver/handler must retain the original permission identity and domain audit/failure contracts. Revocation after discovery must fail before provider dispatch. Compatibility mounts are restricted to `/tools/<tool-name>` and cannot bypass namespace ownership or republish legacy routes.
|
|
|
|
|
|
|
|
|
|
Tests `management_enablement_is_independent_of_read_and_operation_permissions` and `contributed_interface_invalidates_observations_and_restore_requires_discovery` cover all eight enablement/read/manage combinations, direct-call rejection, effective descriptor changes, fresh runtime isolation under the same Worker identity, reset, and post-observation revocation.
|
|
|
|
|
|
|
|
|
|
## Authority and execution
|
|
|
|
|
|
|
|
|
|
Discovery is not authority. The Worldspace contains only the tools already registered from enabled Features and the Worker's current execution context. Calling a compatibility operation:
|
|
|
|
|
Discovery is not authority. Object publication, operation implementation, target capability, and subject permission are independent checks. An Object may remain discoverable through an enabled read provider when a management Feature contributes no operations; conversely, publishing an operation never bypasses the target's current capability or the subject's current permission. Every handler re-evaluates permission at call time, so revocation after discovery is rejected before provider dispatch. Feature enablement selects implementations and does not itself grant read or mutation authority.
|
|
|
|
|
|
|
|
|
|
The Worldspace contains only the operations registered from enabled Features and the Worker's current execution context. Calling a compatibility operation:
|
|
|
|
|
|
|
|
|
|
1. resolves the exact mounted route;
|
|
|
|
|
2. verifies object and interface membership and validators;
|
|
|
|
@@ -85,6 +111,8 @@ The stateful `wip-client::Client` is owned by one Worker WIP runtime. Sessions a
|
|
|
|
|
|
|
|
|
|
Known Space and interface observations are therefore not shared across Workers, endpoints, or security contexts. A restored Worker creates a new runtime/client and must explore again. `WipDiscover(reset = true)` drops all observations before reconnect/authority-change exploration; `refresh = true` explicitly supersedes one cached observation. A normal compaction keeps the live runtime but the three gateway schemas are supplied again on every LLM request, including the instruction to begin discovery at `/`; the compacted transcript is not treated as cache authority.
|
|
|
|
|
|
|
|
|
|
Saved Session/history entries remain append-only evidence and are never rewritten or replayed as calls. In particular, historical `/features/<feature>/...` text stays displayable but is not a current route alias. Passing such a legacy path to discovery or call returns `NotFound` with guidance to rediscover from `/`; the Host does not translate it, resolve it under another namespace, or expose old and new routes in parallel.
|
|
|
|
|
|
|
|
|
|
## Errors, cancellation, and retries
|
|
|
|
|
|
|
|
|
|
The adapter keeps these outcomes distinct:
|
|
|
|
@@ -96,6 +124,8 @@ The adapter keeps these outcomes distinct:
|
|
|
|
|
- **disconnected/timeout after dispatch**: `wip-client` records an unknown outcome;
|
|
|
|
|
- **operation outcome unknown**: an executing provider fails without a rollback/non-execution guarantee, a response cannot be completed after dispatch, or the call future is force-closed.
|
|
|
|
|
|
|
|
|
|
Cooperative cancellation is scoped to the active execution's selected operation and exact resolved handler instance. Static/dynamic dispatchers forward `cancel_operation` only to that operation's provider, once per cancellation request, never to unrelated contributors or every alias backed by a shared handler. The runtime pins the dispatcher used for execution rather than resolving the Object again on cancellation, since dynamic resolvers may return stateful instances. Providers may implement `cancel_operation` for operation-specific control or the shared `cancel` default. Terminal completion or a dropped execution future releases the active binding; unknown/finished execution IDs do not invoke any provider. A cancellation request is not itself terminal confirmation.
|
|
|
|
|
|
|
|
|
|
An unknown mutating outcome must never be retried automatically. The model must inspect external state or ask for operator guidance. Retrieval failures may be explicitly refreshed.
|
|
|
|
|
|
|
|
|
|
## Measurement
|
|
|
|
|