task: add plugin service boundary
This commit is contained in:
parent
d7e416982f
commit
0f2ec7c263
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
## 1. Summary recommendation
|
## 1. Summary recommendation
|
||||||
|
|
||||||
Introduce a `pod::feature` public API as the single Pod-side registration layer for built-in features and future external plugins. A feature module should declare its identity, requested capabilities, and contributions, then install those contributions only through typed host registrars for existing Pod/Worker surfaces: `ToolRegistry`, the hardened safe `pod::hook` surface, host-managed background tasks, and host-owned notification/history/alert/diagnostic paths.
|
Introduce a `pod::feature` public API as the single Pod-side registration layer for built-in features and future external plugins. A feature module should declare its identity, requested capabilities, service dependencies, service exports, and contributions, then install those capabilities only through typed host registrars for existing Pod/Worker surfaces: `ToolRegistry`, the hardened safe `pod::hook` surface, host-managed background tasks, host-mediated service registry, and host-owned notification/history/alert/diagnostic paths.
|
||||||
|
|
||||||
The registry should not become a second runtime, a plugin dispatcher tool, or a generic `Pod` mutation escape hatch. Feature state remains inside the feature module; the Pod owns only install metadata, diagnostics, granted host handles, and normal durable session/runtime surfaces.
|
The registry should not become a second runtime, a plugin dispatcher tool, or a generic `Pod` mutation escape hatch. Feature state remains inside the feature module; the Pod owns only install metadata, diagnostics, granted host handles, and normal durable session/runtime surfaces.
|
||||||
|
|
||||||
|
|
@ -65,6 +65,7 @@ pub mod feature {
|
||||||
pub mod hook;
|
pub mod hook;
|
||||||
pub mod notify;
|
pub mod notify;
|
||||||
pub mod registry;
|
pub mod registry;
|
||||||
|
pub mod service;
|
||||||
pub mod tool;
|
pub mod tool;
|
||||||
|
|
||||||
pub use background::{BackgroundTaskContribution, BackgroundTaskRegistrar};
|
pub use background::{BackgroundTaskContribution, BackgroundTaskRegistrar};
|
||||||
|
|
@ -72,6 +73,7 @@ pub mod feature {
|
||||||
pub use diagnostic::{FeatureDiagnostic, FeatureInstallReport};
|
pub use diagnostic::{FeatureDiagnostic, FeatureInstallReport};
|
||||||
pub use notify::{FeatureAlertSink, FeatureNotifySink};
|
pub use notify::{FeatureAlertSink, FeatureNotifySink};
|
||||||
pub use registry::{FeatureDescriptor, FeatureId, FeatureInstallContext, FeatureModule, FeatureRuntimeKind};
|
pub use registry::{FeatureDescriptor, FeatureId, FeatureInstallContext, FeatureModule, FeatureRuntimeKind};
|
||||||
|
pub use service::{FeatureServiceProvider, FeatureServiceRegistrar, ServiceDeclaration, ServiceRequirement, YoiService};
|
||||||
pub use tool::ToolContribution;
|
pub use tool::ToolContribution;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -91,6 +93,8 @@ pub struct FeatureDescriptor {
|
||||||
pub version: Option<String>,
|
pub version: Option<String>,
|
||||||
pub runtime: FeatureRuntimeKind, // Builtin, ExternalProcess, McpBridge, WasmPlaceholder, DeclarativePlaceholder
|
pub runtime: FeatureRuntimeKind, // Builtin, ExternalProcess, McpBridge, WasmPlaceholder, DeclarativePlaceholder
|
||||||
pub requested_capabilities: Vec<CapabilityRequest>,
|
pub requested_capabilities: Vec<CapabilityRequest>,
|
||||||
|
pub provides_services: Vec<ServiceDeclaration>,
|
||||||
|
pub requires_services: Vec<ServiceRequirement>,
|
||||||
pub declared_tools: Vec<ToolDeclaration>,
|
pub declared_tools: Vec<ToolDeclaration>,
|
||||||
pub declared_hooks: Vec<HookDeclaration>,
|
pub declared_hooks: Vec<HookDeclaration>,
|
||||||
pub declared_background_tasks: Vec<BackgroundTaskDeclaration>,
|
pub declared_background_tasks: Vec<BackgroundTaskDeclaration>,
|
||||||
|
|
@ -110,11 +114,12 @@ pub struct FeatureInstallContext<'a> {
|
||||||
pub grants: &'a CapabilityGrantSet,
|
pub grants: &'a CapabilityGrantSet,
|
||||||
pub tools: ToolRegistrar<'a>,
|
pub tools: ToolRegistrar<'a>,
|
||||||
pub hooks: PublicHookRegistrar<'a>,
|
pub hooks: PublicHookRegistrar<'a>,
|
||||||
|
pub services: FeatureServiceProvider<'a>,
|
||||||
|
pub service_exports: FeatureServiceRegistrar<'a>,
|
||||||
pub background_tasks: BackgroundTaskRegistrar<'a>,
|
pub background_tasks: BackgroundTaskRegistrar<'a>,
|
||||||
pub notify: FeatureNotifySink<'a>,
|
pub notify: FeatureNotifySink<'a>,
|
||||||
pub alerts: FeatureAlertSink<'a>,
|
pub alerts: FeatureAlertSink<'a>,
|
||||||
pub diagnostics: FeatureDiagnosticSink<'a>,
|
pub diagnostics: FeatureDiagnosticSink<'a>,
|
||||||
pub services: FeatureServiceProvider<'a>,
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -123,7 +128,8 @@ Important details:
|
||||||
- `FeatureDescriptor` is declarative and serializable. It is safe to show in diagnostics, profile previews, and `ListFeatures`-style future tooling.
|
- `FeatureDescriptor` is declarative and serializable. It is safe to show in diagnostics, profile previews, and `ListFeatures`-style future tooling.
|
||||||
- `FeatureModule::install` is runtime code that wires stateful tool/hook implementations into host registrars.
|
- `FeatureModule::install` is runtime code that wires stateful tool/hook implementations into host registrars.
|
||||||
- `FeatureInstallContext` must not expose `Pod`, `Worker`, raw `ToolServerHandle`, raw `Interceptor`, raw `NotifyBuffer`, raw `LogWriter`, raw `event_tx`, or direct history mutation.
|
- `FeatureInstallContext` must not expose `Pod`, `Worker`, raw `ToolServerHandle`, raw `Interceptor`, raw `NotifyBuffer`, raw `LogWriter`, raw `event_tx`, or direct history mutation.
|
||||||
- `FeatureServiceProvider` returns only host services backed by granted capabilities, for example scoped filesystem access, WorkItem store access, memory access, Pod orchestration handles, web provider handles, or secret references. It should return `Denied`/`Unavailable` diagnostics instead of exposing partial internals.
|
- `FeatureServiceProvider` returns only host-mediated services backed by granted capabilities and resolved service dependencies, for example scoped filesystem access, WorkItem store access, memory access, Pod orchestration handles, web provider handles, secret references, or another feature's declared public service. It should return `Denied`/`Unavailable` diagnostics instead of exposing partial internals.
|
||||||
|
- `FeatureServiceRegistrar` lets a feature expose a narrow public service API to other features. This is an extension boundary for future plugin-to-plugin APIs, not a requirement to move already-implemented core behavior out of the host.
|
||||||
|
|
||||||
### Example registration snippet
|
### Example registration snippet
|
||||||
|
|
||||||
|
|
@ -297,6 +303,54 @@ Rules:
|
||||||
- The host records task lifecycle/status in install/runtime diagnostics. Do not expose arbitrary feature-defined event channels for task progress.
|
- The host records task lifecycle/status in install/runtime diagnostics. Do not expose arbitrary feature-defined event channels for task progress.
|
||||||
- Initial activation can be conservative (`PodLifetime` and/or `OnDemand`); restart policy may start with `Never`, but the API should make shutdown/cancellation behavior explicit from the beginning.
|
- Initial activation can be conservative (`PodLifetime` and/or `OnDemand`); restart policy may start with `Never`, but the API should make shutdown/cancellation behavior explicit from the beginning.
|
||||||
|
|
||||||
|
### Service contribution and dependency
|
||||||
|
|
||||||
|
Add a host-mediated service registry so a feature/plugin can publish a narrow API and another feature/plugin can depend on that API without importing the provider's concrete implementation or bypassing capability policy.
|
||||||
|
|
||||||
|
This is not a plan to move existing implemented core features out of the host immediately. Core-backed APIs may remain core-backed. The service form exists so future detachable features can depend on stable public interfaces rather than private Pod internals or another plugin's concrete state.
|
||||||
|
|
||||||
|
Initial shape:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub trait YoiService: Send + Sync + 'static {
|
||||||
|
fn service_id(&self) -> ServiceId;
|
||||||
|
fn service_version(&self) -> ServiceVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ServiceDeclaration {
|
||||||
|
pub id: ServiceId, // e.g. yoi.memory.v1
|
||||||
|
pub version: ServiceVersion,
|
||||||
|
pub description: String,
|
||||||
|
pub operations: Vec<ServiceOperationDeclaration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ServiceRequirement {
|
||||||
|
pub id: ServiceId,
|
||||||
|
pub version: ServiceVersionReq,
|
||||||
|
pub optional: bool,
|
||||||
|
pub reason: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FeatureServiceRegistrar<'a> { /* host-owned */ }
|
||||||
|
pub struct FeatureServiceProvider<'a> { /* host-owned */ }
|
||||||
|
```
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
- A feature may provide a service through `FeatureServiceRegistrar`, and consumers may obtain the service only through `FeatureServiceProvider` after host dependency resolution and capability grant checks.
|
||||||
|
- Features must not directly hold another feature's concrete module/state unless that handle was returned by the host service registry.
|
||||||
|
- Service identity is source-independent interface identity (`yoi.memory.v1`, `yoi.pod-management.v1`, `project.issue-tracker.v1`), while provider identity remains a `FeatureId`.
|
||||||
|
- Service dependencies are resolved during feature registry preflight. Required missing services skip the consumer feature with diagnostics; optional missing services install the consumer in a degraded mode if its installer supports that.
|
||||||
|
- Service dependency cycles are rejected initially. Late-bound/cyclic service handles are out of scope until a real need appears.
|
||||||
|
- In-process built-in services may use Rust trait objects internally. External plugin/WASM/MCP services should be represented by host-side proxies that implement the same service interface boundary; do not expose raw foreign runtime handles.
|
||||||
|
- Service handles should be capability-bound. Prefer narrowed interfaces such as read-only vs write-capable services, or enforce caller/grant checks through a host-provided service call context.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- `builtin:memory` may provide `yoi.memory.v1` and contribute memory tools. A WorkItem intake feature may require `yoi.memory.v1` optionally for contextual lookup.
|
||||||
|
- `builtin:pod-orchestration` may provide `yoi.pod-management.v1` and contribute Pod management tools. The actual Pod lifecycle/scope authority remains host-owned; the service is a controlled façade.
|
||||||
|
- A future issue-tracker plugin may provide `project.issue-tracker.v1`, while WorkItem tooling consumes that service without knowing the concrete plugin package.
|
||||||
|
|
||||||
### Capability request/grant/diagnostics
|
### Capability request/grant/diagnostics
|
||||||
|
|
||||||
Capabilities are requested by descriptors and granted by the host. A feature may request a capability, but it must not assume the capability exists.
|
Capabilities are requested by descriptors and granted by the host. A feature may request a capability, but it must not assume the capability exists.
|
||||||
|
|
@ -308,6 +362,8 @@ pub enum HostCapability {
|
||||||
ContributeTool { name: ToolName },
|
ContributeTool { name: ToolName },
|
||||||
ContributeHook { point: pod::hook::HookPoint },
|
ContributeHook { point: pod::hook::HookPoint },
|
||||||
RunBackgroundTask,
|
RunBackgroundTask,
|
||||||
|
ProvideService { id: ServiceId },
|
||||||
|
UseService { id: ServiceId, access: ServiceAccess },
|
||||||
EmitModelNotification,
|
EmitModelNotification,
|
||||||
EmitAlert,
|
EmitAlert,
|
||||||
ScopedFs { read: bool, write: bool, execute: bool },
|
ScopedFs { read: bool, write: bool, execute: bool },
|
||||||
|
|
@ -336,6 +392,8 @@ pub struct FeatureInstallReport {
|
||||||
pub installed_tools: Vec<ToolName>,
|
pub installed_tools: Vec<ToolName>,
|
||||||
pub installed_hooks: Vec<String>,
|
pub installed_hooks: Vec<String>,
|
||||||
pub installed_background_tasks: Vec<FeatureTaskId>,
|
pub installed_background_tasks: Vec<FeatureTaskId>,
|
||||||
|
pub provided_services: Vec<ServiceId>,
|
||||||
|
pub resolved_services: Vec<ServiceResolutionReport>,
|
||||||
pub skipped_contributions: Vec<SkippedContribution>,
|
pub skipped_contributions: Vec<SkippedContribution>,
|
||||||
pub diagnostics: Vec<FeatureDiagnostic>,
|
pub diagnostics: Vec<FeatureDiagnostic>,
|
||||||
}
|
}
|
||||||
|
|
@ -347,8 +405,8 @@ Diagnostics must avoid secrets and must be safe for session logs, TUI display, a
|
||||||
|
|
||||||
Feature state belongs to the feature module.
|
Feature state belongs to the feature module.
|
||||||
|
|
||||||
- A feature may own `Arc<State>` and clone it into contributed tools, hooks, and background tasks.
|
- A feature may own `Arc<State>` and clone it into contributed tools, hooks, background tasks, and service implementations.
|
||||||
- The Pod registry stores descriptors, install reports, enabled/disabled status, and host-owned handles. It does not store feature business state.
|
- The Pod registry stores descriptors, service resolution records, install reports, enabled/disabled status, and host-owned handles. It does not store feature business state.
|
||||||
- Durable feature data must live in a feature-owned or host-granted store with an explicit API: WorkItem files through a WorkItem service, memory records through memory APIs, plugin config/state through a future plugin-state service, etc.
|
- Durable feature data must live in a feature-owned or host-granted store with an explicit API: WorkItem files through a WorkItem service, memory records through memory APIs, plugin config/state through a future plugin-state service, etc.
|
||||||
- Session history is not feature storage. It is an audit/replay record of model-visible interactions and committed system items.
|
- Session history is not feature storage. It is an audit/replay record of model-visible interactions and committed system items.
|
||||||
- A feature that needs restoration after process restart should reconstruct itself from its own durable store/config plus normal Pod metadata, not from private data hidden in Worker context.
|
- A feature that needs restoration after process restart should reconstruct itself from its own durable store/config plus normal Pod metadata, not from private data hidden in Worker context.
|
||||||
|
|
@ -370,6 +428,7 @@ Public features/plugins must not be able to perform these operations:
|
||||||
- Grant themselves capabilities or infer grants from successful construction.
|
- Grant themselves capabilities or infer grants from successful construction.
|
||||||
- Mutate manifest/profile/scope state directly.
|
- Mutate manifest/profile/scope state directly.
|
||||||
- Perform filesystem/process/network/secret access outside granted host services.
|
- Perform filesystem/process/network/secret access outside granted host services.
|
||||||
|
- Depend on another feature/plugin by concrete implementation, private state, raw process handle, or direct module pointer instead of a host-resolved service interface.
|
||||||
- Emit unbounded tool outputs, diagnostics, alerts, task-status reports, or notification bodies.
|
- Emit unbounded tool outputs, diagnostics, alerts, task-status reports, or notification bodies.
|
||||||
- Emit arbitrary plugin-defined UI payloads, dialogs, or event-channel messages.
|
- Emit arbitrary plugin-defined UI payloads, dialogs, or event-channel messages.
|
||||||
- Put secrets into diagnostics, session logs, model context, TUI output, or feature install reports.
|
- Put secrets into diagnostics, session logs, model context, TUI output, or feature install reports.
|
||||||
|
|
@ -387,6 +446,7 @@ Recommended placement:
|
||||||
- install reports/diagnostics
|
- install reports/diagnostics
|
||||||
- capability request/grant model
|
- capability request/grant model
|
||||||
- typed registrars/sinks
|
- typed registrars/sinks
|
||||||
|
- service registry, service declarations, and dependency resolution reports
|
||||||
|
|
||||||
- `crates/pod/src/hook.rs`
|
- `crates/pod/src/hook.rs`
|
||||||
- remains the public hook module after hardening
|
- remains the public hook module after hardening
|
||||||
|
|
@ -410,9 +470,10 @@ Install location in Pod startup:
|
||||||
1. Resolve manifest/profile and host capability policy.
|
1. Resolve manifest/profile and host capability policy.
|
||||||
2. Construct `Pod` and internal safety surfaces.
|
2. Construct `Pod` and internal safety surfaces.
|
||||||
3. Install host/internal hooks such as manifest permission enforcement.
|
3. Install host/internal hooks such as manifest permission enforcement.
|
||||||
4. Build and install enabled feature modules through `FeatureRegistryBuilder`.
|
4. Build enabled feature descriptors, collect declared service providers/requirements, resolve the service dependency DAG, and compute capability grants.
|
||||||
5. Flush/register tools through the existing Worker tool registry.
|
5. Install enabled feature modules through `FeatureRegistryBuilder`, including service exports, tools, hooks, and background task declarations.
|
||||||
6. Freeze/install the Pod interceptor and start normal run/attach behavior.
|
6. Flush/register tools through the existing Worker tool registry.
|
||||||
|
7. Freeze/install the Pod interceptor, start host-managed background tasks at their activation point, and start normal run/attach behavior.
|
||||||
|
|
||||||
The exact sequencing can be adjusted to match current construction, but the invariant should hold: public feature hooks cannot precede host safety hooks, and feature tools must exist before the model receives the final tool schema for a run.
|
The exact sequencing can be adjusted to match current construction, but the invariant should hold: public feature hooks cannot precede host safety hooks, and feature tools must exist before the model receives the final tool schema for a run.
|
||||||
|
|
||||||
|
|
@ -425,30 +486,35 @@ Recommended migration is incremental and behavior-preserving:
|
||||||
- Define which hook decisions are safe for external contributors.
|
- Define which hook decisions are safe for external contributors.
|
||||||
|
|
||||||
2. Add `pod::feature` with no behavior change.
|
2. Add `pod::feature` with no behavior change.
|
||||||
- Implement descriptors, capability grants, install reports, and registrars.
|
- Implement descriptors, service declarations/requirements, capability grants, install reports, and registrars.
|
||||||
- Initially register no external plugins.
|
- Initially register no external plugins.
|
||||||
|
|
||||||
3. Wrap current built-in tool registration as built-in feature modules.
|
3. Add the service registry as a host-mediated boundary.
|
||||||
|
- Start with core-backed services or a trivial built-in service provider to validate provider/consumer resolution.
|
||||||
|
- Do not move existing Memory or Pod management implementation solely for this ticket.
|
||||||
|
- Use diagnostics for missing required services, optional degraded service dependencies, and service cycles.
|
||||||
|
|
||||||
|
4. Wrap current built-in tool registration as built-in feature modules.
|
||||||
- Start with a small built-in feature whose state/services are already cleanly bounded.
|
- Start with a small built-in feature whose state/services are already cleanly bounded.
|
||||||
- Preserve existing tool names, schemas, and permission behavior.
|
- Preserve existing tool names, schemas, and permission behavior.
|
||||||
- Convert duplicate-name failures into registry diagnostics before flushing tools.
|
- Convert duplicate-name failures into registry diagnostics before flushing tools.
|
||||||
|
|
||||||
4. Move larger built-in groups behind feature modules.
|
5. Move larger built-in groups behind feature modules.
|
||||||
- Filesystem/process tools from `crates/tools`.
|
- Filesystem/process tools from `crates/tools`.
|
||||||
- Memory tools.
|
- Memory tools.
|
||||||
- Pod orchestration tools.
|
- Pod orchestration tools.
|
||||||
- Task/WorkItem tools once their stores and hooks have explicit capabilities.
|
- Task/WorkItem tools once their stores and hooks have explicit capabilities.
|
||||||
- Web tools as configured provider-backed features.
|
- Web tools as configured provider-backed features.
|
||||||
|
|
||||||
5. Move built-in hook contributions only after safe hook semantics are stable.
|
6. Move built-in hook contributions only after safe hook semantics are stable.
|
||||||
- Keep manifest permission enforcement as an internal host hook, not a feature hook.
|
- Keep manifest permission enforcement as an internal host hook, not a feature hook.
|
||||||
- Keep accounting/usage hooks internal unless they become genuine feature behavior.
|
- Keep accounting/usage hooks internal unless they become genuine feature behavior.
|
||||||
|
|
||||||
6. Treat workflow/user-input expansion separately.
|
7. Treat workflow/user-input expansion separately.
|
||||||
- Workflow invocation already uses a durable system-item attachment pattern.
|
- Workflow invocation already uses a durable system-item attachment pattern.
|
||||||
- Do not expose arbitrary workflow-like context injection to plugins until there is a safe typed command/input-contribution API with durable append semantics.
|
- Do not expose arbitrary workflow-like context injection to plugins until there is a safe typed command/input-contribution API with durable append semantics.
|
||||||
|
|
||||||
7. Add profile/manifest enablement after built-ins work through the same registry.
|
8. Add profile/manifest enablement after built-ins work through the same registry.
|
||||||
- Built-ins and external plugins should share descriptor/capability/install-report mechanics.
|
- Built-ins and external plugins should share descriptor/capability/install-report mechanics.
|
||||||
- Host policy may grant built-ins by default, but built-ins should still declare what they use.
|
- Host policy may grant built-ins by default, but built-ins should still declare what they use.
|
||||||
|
|
||||||
|
|
@ -460,6 +526,13 @@ WorkItem / intake routing:
|
||||||
- It should request `WorkItemStore`, `RunBackgroundTask`, and notification/alert capabilities instead of reaching into ticket files ad hoc.
|
- It should request `WorkItemStore`, `RunBackgroundTask`, and notification/alert capabilities instead of reaching into ticket files ad hoc.
|
||||||
- Model-visible routing hints or intake results must be committed through notification/history append paths.
|
- Model-visible routing hints or intake results must be committed through notification/history append paths.
|
||||||
- This registry gives the WorkItem feature a clean way to install without making WorkItem a special Pod runtime mode.
|
- This registry gives the WorkItem feature a clean way to install without making WorkItem a special Pod runtime mode.
|
||||||
|
- If WorkItem, Memory, or Pod orchestration are split into smaller feature modules later, they should communicate through declared services such as `yoi.work-item-store.v1`, `yoi.memory.v1`, or `yoi.pod-management.v1` rather than private module references.
|
||||||
|
|
||||||
|
Feature-to-feature service APIs:
|
||||||
|
|
||||||
|
- The service registry lets plugins expose stable APIs without requiring the host to make every domain capability a permanent core API.
|
||||||
|
- This does not force existing Memory or Pod management implementations to be extracted immediately. They may stay core-backed while still being representable as service façades for consumers.
|
||||||
|
- External plugins should consume service proxies provided by the host, not another plugin's raw process/WASM/MCP handle.
|
||||||
|
|
||||||
MCP:
|
MCP:
|
||||||
|
|
||||||
|
|
@ -500,5 +573,9 @@ Plugin distribution:
|
||||||
7. Background tasks need lifecycle policy.
|
7. Background tasks need lifecycle policy.
|
||||||
- If external plugins can spawn tasks, the host must define shutdown, cancellation, panic handling, diagnostic routing, and whether task output may become model-visible.
|
- If external plugins can spawn tasks, the host must define shutdown, cancellation, panic handling, diagnostic routing, and whether task output may become model-visible.
|
||||||
|
|
||||||
8. Existing workflow/input expansion is close to the forbidden boundary.
|
8. Service API design needs an in-process vs external-plugin boundary.
|
||||||
|
- Built-in services can use Rust traits or typed handles, but external plugins need host-side proxies and operation schemas. The first implementation should avoid baking in Rust trait-object assumptions as the only service representation.
|
||||||
|
- Service handles must be capability-bound, or one broad service handle can accidentally become an authority escalation path.
|
||||||
|
|
||||||
|
9. Existing workflow/input expansion is close to the forbidden boundary.
|
||||||
- It is safe only because it commits system items before model visibility. Any future plugin command/input contribution must preserve that durable replay property.
|
- It is safe only because it commits system items before model visibility. Any future plugin command/input contribution must preserve that durable replay property.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Decision: add host-mediated Feature services
|
||||||
|
|
||||||
|
Add Service provider/consumer support to the Plugin/Feature base Pod API.
|
||||||
|
|
||||||
|
This is not a decision to extract currently implemented core features such as Memory or Pod management immediately. Existing implementations may remain core-backed. The new service form exists so future built-in features and plugins can expose stable APIs to other features without direct concrete dependencies or ad hoc Pod internals access.
|
||||||
|
|
||||||
|
Revised contribution/dependency model:
|
||||||
|
|
||||||
|
- Contributions:
|
||||||
|
- ToolContribution
|
||||||
|
- HookContribution
|
||||||
|
- BackgroundTaskContribution
|
||||||
|
- ServiceProvider / ServiceDeclaration
|
||||||
|
- Dependencies:
|
||||||
|
- ServiceRequirement, resolved by the host registry before feature installation
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
- A feature/plugin may provide a public service through a host-owned service registry.
|
||||||
|
- Another feature/plugin may acquire that service only through the host, after dependency resolution and capability grant checks.
|
||||||
|
- Consumers do not import provider concrete types, private state, raw process handles, raw WASM/MCP handles, or plugin-specific modules.
|
||||||
|
- Required missing services skip the consuming feature with diagnostics; optional missing services allow degraded installation when supported.
|
||||||
|
- Service cycles are rejected initially.
|
||||||
|
- In-process built-ins may use Rust trait-object handles internally, but the public design must leave room for external plugin service proxies.
|
||||||
|
- Service handles must be capability-bound so acquiring a broad service does not become an authority escalation path.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- `builtin:memory` may provide `yoi.memory.v1`; other features can optionally consume read-only memory lookup without depending on Memory internals.
|
||||||
|
- `builtin:pod-orchestration` may provide `yoi.pod-management.v1` as a controlled façade while the actual Pod lifecycle/scope authority remains host-owned.
|
||||||
|
- Future issue-tracker plugins may provide `project.issue-tracker.v1` for WorkItem integration.
|
||||||
|
|
@ -7,7 +7,7 @@ kind: feature
|
||||||
priority: P1
|
priority: P1
|
||||||
labels: [plugin, registry, tools, hooks, orchestration]
|
labels: [plugin, registry, tools, hooks, orchestration]
|
||||||
created_at: 2026-06-03T12:23:17Z
|
created_at: 2026-06-03T12:23:17Z
|
||||||
updated_at: 2026-06-04T20:23:15Z
|
updated_at: 2026-06-04T20:48:19Z
|
||||||
assignee: null
|
assignee: null
|
||||||
legacy_ticket: null
|
legacy_ticket: null
|
||||||
---
|
---
|
||||||
|
|
@ -16,7 +16,7 @@ legacy_ticket: null
|
||||||
|
|
||||||
Yoi already has many capability surfaces: built-in tools, memory tools, Pod management tools, manifest permission hooks, workflow assets, notifications, and planned WorkItem / MCP / plugin features. If new features keep registering themselves through ad hoc Pod/Worker code paths, Plugin system work will not produce a single management boundary and later features such as WorkItem intake will be hard to detach.
|
Yoi already has many capability surfaces: built-in tools, memory tools, Pod management tools, manifest permission hooks, workflow assets, notifications, and planned WorkItem / MCP / plugin features. If new features keep registering themselves through ad hoc Pod/Worker code paths, Plugin system work will not produce a single management boundary and later features such as WorkItem intake will be hard to detach.
|
||||||
|
|
||||||
The immediate need is not package distribution or WASM execution. The immediate need is a runtime feature contribution registry that lets built-in features and future external plugins contribute through the same existing host surfaces: Tools, Hooks, host-managed BackgroundTasks, and durable notification/history plus alert/diagnostic paths.
|
The immediate need is not package distribution or WASM execution. The immediate need is a runtime feature contribution registry that lets built-in features and future external plugins contribute through the same existing host surfaces: Tools, Hooks, host-managed BackgroundTasks, host-mediated Services, and durable notification/history plus alert/diagnostic paths.
|
||||||
|
|
||||||
## Direction
|
## Direction
|
||||||
|
|
||||||
|
|
@ -27,6 +27,7 @@ Introduce a feature registry boundary for Pod runtime capability installation.
|
||||||
- Tool contributions registered into the normal ToolRegistry / permission / history path.
|
- Tool contributions registered into the normal ToolRegistry / permission / history path.
|
||||||
- Hook contributions registered through the public Pod Hook boundary.
|
- Hook contributions registered through the public Pod Hook boundary.
|
||||||
- BackgroundTask contributions are host-managed for async feature work; feature modules must not create untracked runtime loops.
|
- BackgroundTask contributions are host-managed for async feature work; feature modules must not create untracked runtime loops.
|
||||||
|
- Service provider/consumer contributions allow a feature/plugin to expose a narrow public API and another feature/plugin to acquire it through host dependency resolution and capability grants.
|
||||||
- Model-visible notifications use the existing durable Notify / SystemItem / Event::SystemItem path rather than invisible context injection.
|
- Model-visible notifications use the existing durable Notify / SystemItem / Event::SystemItem path rather than invisible context injection.
|
||||||
- Transient human-facing alerts and diagnostics are separate host-defined outputs, not arbitrary plugin UI channels.
|
- Transient human-facing alerts and diagnostics are separate host-defined outputs, not arbitrary plugin UI channels.
|
||||||
- The registry is responsible for discovery/enablement diagnostics and installation into existing surfaces; it must not create a parallel execution path.
|
- The registry is responsible for discovery/enablement diagnostics and installation into existing surfaces; it must not create a parallel execution path.
|
||||||
|
|
@ -47,6 +48,7 @@ Pure descriptor types may later move to a separate `plugin` / `extension` crate
|
||||||
- Tools
|
- Tools
|
||||||
- Hooks
|
- Hooks
|
||||||
- BackgroundTasks
|
- BackgroundTasks
|
||||||
|
- Service providers and service requirements
|
||||||
- Model-visible notification, transient alert, and diagnostic capabilities where needed
|
- Model-visible notification, transient alert, and diagnostic capabilities where needed
|
||||||
- Define capability request / host grant data structures suitable for policy diagnostics.
|
- Define capability request / host grant data structures suitable for policy diagnostics.
|
||||||
- Add a registry/builder/install context that can install enabled feature contributions into existing Pod/Worker surfaces.
|
- Add a registry/builder/install context that can install enabled feature contributions into existing Pod/Worker surfaces.
|
||||||
|
|
@ -86,7 +88,7 @@ Pure descriptor types may later move to a separate `plugin` / `extension` crate
|
||||||
|
|
||||||
- The codebase has a first-class feature contribution registry boundary for Pod runtime installation.
|
- The codebase has a first-class feature contribution registry boundary for Pod runtime installation.
|
||||||
- At least one built-in capability group is registered through the new registry without changing behavior.
|
- At least one built-in capability group is registered through the new registry without changing behavior.
|
||||||
- The registry can describe Tool, Hook, and BackgroundTask contributions and records source/runtime/capability diagnostics.
|
- The registry can describe Tool, Hook, BackgroundTask, and Service provider/requirement contributions and records source/runtime/capability diagnostics.
|
||||||
- Feature installation uses existing ToolRegistry, HookRegistry, host-managed BackgroundTask lifecycle, and notification/history paths; no parallel Pod context injection path or arbitrary plugin UI channel is introduced.
|
- Feature installation uses existing ToolRegistry, HookRegistry, host-managed BackgroundTask lifecycle, host-mediated Service resolution, and notification/history paths; no parallel Pod context injection path or arbitrary plugin UI channel is introduced.
|
||||||
- WorkItem and MCP follow-up tickets can target this registry instead of adding ad hoc registration code.
|
- WorkItem and MCP follow-up tickets can target this registry instead of adding ad hoc registration code.
|
||||||
- Focused tests cover the migrated built-in registration and capability/diagnostic behavior.
|
- Focused tests cover the migrated built-in registration and capability/diagnostic behavior.
|
||||||
|
|
|
||||||
|
|
@ -609,4 +609,43 @@ Revised boundary:
|
||||||
This keeps the Plugin API centered on Tools, safe Hooks, host-managed BackgroundTasks, durable model-visible notifications, and bounded host-defined operational reporting.
|
This keeps the Plugin API centered on Tools, safe Hooks, host-managed BackgroundTasks, durable model-visible notifications, and bounded host-defined operational reporting.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- event: decision author: hare at: 2026-06-04T20:48:19Z -->
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
# Decision: add host-mediated Feature services
|
||||||
|
|
||||||
|
Add Service provider/consumer support to the Plugin/Feature base Pod API.
|
||||||
|
|
||||||
|
This is not a decision to extract currently implemented core features such as Memory or Pod management immediately. Existing implementations may remain core-backed. The new service form exists so future built-in features and plugins can expose stable APIs to other features without direct concrete dependencies or ad hoc Pod internals access.
|
||||||
|
|
||||||
|
Revised contribution/dependency model:
|
||||||
|
|
||||||
|
- Contributions:
|
||||||
|
- ToolContribution
|
||||||
|
- HookContribution
|
||||||
|
- BackgroundTaskContribution
|
||||||
|
- ServiceProvider / ServiceDeclaration
|
||||||
|
- Dependencies:
|
||||||
|
- ServiceRequirement, resolved by the host registry before feature installation
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
|
||||||
|
- A feature/plugin may provide a public service through a host-owned service registry.
|
||||||
|
- Another feature/plugin may acquire that service only through the host, after dependency resolution and capability grant checks.
|
||||||
|
- Consumers do not import provider concrete types, private state, raw process handles, raw WASM/MCP handles, or plugin-specific modules.
|
||||||
|
- Required missing services skip the consuming feature with diagnostics; optional missing services allow degraded installation when supported.
|
||||||
|
- Service cycles are rejected initially.
|
||||||
|
- In-process built-ins may use Rust trait-object handles internally, but the public design must leave room for external plugin service proxies.
|
||||||
|
- Service handles must be capability-bound so acquiring a broad service does not become an authority escalation path.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- `builtin:memory` may provide `yoi.memory.v1`; other features can optionally consume read-only memory lookup without depending on Memory internals.
|
||||||
|
- `builtin:pod-orchestration` may provide `yoi.pod-management.v1` as a controlled façade while the actual Pod lifecycle/scope authority remains host-owned.
|
||||||
|
- Future issue-tracker plugins may provide `project.issue-tracker.v1` for WorkItem integration.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user