docs(architecture): add OQ-19 session-scoped registries and agent-written operations

Document the three-tier registry model (core/session/promotion) and the
self-improving agent workflow where agents write their own operations in
a quickjs sandbox. The POC at /workspace/toolEnv demonstrated the sandbox
mechanism (quickjs in Deno web workers, proxy-based env bridge via
postMessage) but exposed the full registry to the sandbox — the security
gap that OQ-18's scoped composition env addresses.

The call protocol doesn't need changes: the OperationEnv trait is the
composition point, and a session-scoped env wraps the global env (session
registry first, fall through to global). The one-way door this OQ guards
against: making OperationEnv concrete instead of a trait, or hardcoding
the global registry into the dispatch path, would close the session-overlay
pattern. Session-scoped operations are always Internal, run under the
handler's identity, and are ephemeral. Promotion to core requires curation
review (architect role with promote scope).
This commit is contained in:
2026-06-18 08:31:46 +00:00
parent f27d717ac8
commit b4aadc6b93
5 changed files with 32 additions and 1 deletions

View File

@@ -72,6 +72,7 @@ See [open-questions.md](open-questions.md) for the full tracker.
- **OQ-15**: Call protocol client and adapter contract — alknet-call needs both the server (CallAdapter) and client (call invocation over QUIC), plus the adapter contract traits (from_*, to_*) that enable composition. ADR-014 constrains the adapter contract: adapters take credential sources from the assembly layer, not static tokens. - **OQ-15**: Call protocol client and adapter contract — alknet-call needs both the server (CallAdapter) and client (call invocation over QUIC), plus the adapter contract traits (from_*, to_*) that enable composition. ADR-014 constrains the adapter contract: adapters take credential sources from the assembly layer, not static tokens.
- **OQ-17**: Abort cascade semantics — `call.aborted` cascades to descendants. Default `abort-dependents`, `continue-running` opt-in. One-way door on the event schema; mechanism is a two-way door. - **OQ-17**: Abort cascade semantics — `call.aborted` cascades to descendants. Default `abort-dependents`, `continue-running` opt-in. One-way door on the event schema; mechanism is a two-way door.
- **OQ-18**: Privilege model and authority context — `internal` flag switches authority to handler identity, not blanket ACL skip. Operations have External/Internal visibility. Scoped composition env + handler identity. Protocol-level concern — every consumer inherits this model. - **OQ-18**: Privilege model and authority context — `internal` flag switches authority to handler identity, not blanket ACL skip. Operations have External/Internal visibility. Scoped composition env + handler identity. Protocol-level concern — every consumer inherits this model.
- **OQ-19**: Session-scoped operation registries — agent-written operations in a quickjs sandbox, overlaid on the global registry via `OperationEnv` trait layering. Protocol doesn't need changes; the one-way door is not closing the trait-based composition point. Promotion from session to core requires curation review.
**Deferred (not active):** **Deferred (not active):**
- **OQ-09**: WASM target boundaries — design constraint, not deliverable - **OQ-09**: WASM target boundaries — design constraint, not deliverable

View File

@@ -41,6 +41,7 @@ Structured RPC over QUIC: operations, request/response, streaming subscriptions,
| OQ-16 | Safe vault operations for call protocol exposure | resolved (ADR-014) | None exposed for now | | OQ-16 | Safe vault operations for call protocol exposure | resolved (ADR-014) | None exposed for now |
| OQ-17 | Abort cascade semantics | open | `call.aborted` cascades to descendants; default `abort-dependents`, `continue-running` opt-in. One-way door on event schema | | OQ-17 | Abort cascade semantics | open | `call.aborted` cascades to descendants; default `abort-dependents`, `continue-running` opt-in. One-way door on event schema |
| OQ-18 | Privilege model and authority context | open | `internal` flag switches authority to handler identity, not blanket ACL skip. External/Internal operation visibility. Scoped composition env + handler identity. Protocol-level concern | | OQ-18 | Privilege model and authority context | open | `internal` flag switches authority to handler identity, not blanket ACL skip. External/Internal operation visibility. Scoped composition env + handler identity. Protocol-level concern |
| OQ-19 | Session-scoped operation registries | open | Agent-written operations overlaid on global registry via `OperationEnv` trait layering. Protocol doesn't need changes; one-way door is not closing the trait-based composition point |
## Key Design Principles ## Key Design Principles

View File

@@ -312,6 +312,7 @@ See [open-questions.md](../../open-questions.md) for full details.
- **OQ-16** (resolved by ADR-014): No vault operations are exposed over the call protocol for now. - **OQ-16** (resolved by ADR-014): No vault operations are exposed over the call protocol for now.
- **OQ-17** (open): Abort cascade semantics — `call.aborted` cascades to descendants, default `abort-dependents`, `continue-running` opt-in. One-way door on the event schema; mechanism is a two-way door. - **OQ-17** (open): Abort cascade semantics — `call.aborted` cascades to descendants, default `abort-dependents`, `continue-running` opt-in. One-way door on the event schema; mechanism is a two-way door.
- **OQ-18** (open): Privilege model and authority context — `internal` flag switches authority to handler identity, not blanket ACL skip. Operations have External/Internal visibility. Scoped composition env + handler identity. Protocol-level concern — every consumer inherits this model. - **OQ-18** (open): Privilege model and authority context — `internal` flag switches authority to handler identity, not blanket ACL skip. Operations have External/Internal visibility. Scoped composition env + handler identity. Protocol-level concern — every consumer inherits this model.
- **OQ-19** (open): Session-scoped operation registries — agent-written operations overlaid on global registry via `OperationEnv` trait layering. Protocol doesn't need changes.
## References ## References

View File

@@ -306,6 +306,7 @@ See [open-questions.md](../../open-questions.md) for full details.
- **OQ-16** (resolved by ADR-014): No vault operations are exposed over the call protocol for now. - **OQ-16** (resolved by ADR-014): No vault operations are exposed over the call protocol for now.
- **OQ-17** (open): Abort cascade semantics — `call.aborted` cascades to descendants, default `abort-dependents`, `continue-running` opt-in. One-way door on the event schema; mechanism is a two-way door. - **OQ-17** (open): Abort cascade semantics — `call.aborted` cascades to descendants, default `abort-dependents`, `continue-running` opt-in. One-way door on the event schema; mechanism is a two-way door.
- **OQ-18** (open): Privilege model and authority context — `internal` flag switches authority to handler identity, not blanket ACL skip. Operations have External/Internal visibility. Scoped composition env + handler identity. Protocol-level concern — every consumer inherits this model. - **OQ-18** (open): Privilege model and authority context — `internal` flag switches authority to handler identity, not blanket ACL skip. Operations have External/Internal visibility. Scoped composition env + handler identity. Protocol-level concern — every consumer inherits this model.
- **OQ-19** (open): Session-scoped operation registries — agent-written operations overlaid on the global registry via `OperationEnv` trait layering. Protocol doesn't need changes; one-way door is not closing the trait-based composition point.
## References ## References

View File

@@ -222,4 +222,31 @@ These questions are acknowledged but not active. They will be promoted to open w
This is a protocol-level concern. The call protocol is a general-purpose cross-boundary RPC mechanism — every consumer (NAPI adapter, Python adapter, agent service, future services speaking the EventEnvelope wire format) inherits whatever privilege model is locked in. The privilege boundary between external and internal calls, and the authority context switch for composition, are core protocol semantics, not features of any single consumer. The agent use case is a useful test case for thinking through the edge cases (parameterized dispatch via LLM tool selection makes the escalation vector concrete), but the decisions belong to the call protocol. This is a protocol-level concern. The call protocol is a general-purpose cross-boundary RPC mechanism — every consumer (NAPI adapter, Python adapter, agent service, future services speaking the EventEnvelope wire format) inherits whatever privilege model is locked in. The privilege boundary between external and internal calls, and the authority context switch for composition, are core protocol semantics, not features of any single consumer. The agent use case is a useful test case for thinking through the edge cases (parameterized dispatch via LLM tool selection makes the escalation vector concrete), but the decisions belong to the call protocol.
This OQ will be resolved with an ADR before alknet-call implementation begins. This OQ will be resolved with an ADR before alknet-call implementation begins.
- **Cross-references**: ADR-014, [call-protocol.md](crates/call/call-protocol.md), [operation-registry.md](crates/call/operation-registry.md) - **Cross-references**: ADR-014, [call-protocol.md](crates/call/call-protocol.md), [operation-registry.md](crates/call/operation-registry.md)
### OQ-19: Session-Scoped Operation Registries and Agent-Written Operations
- **Origin**: [operation-registry.md](crates/call/operation-registry.md)
- **Status**: open
- **Door type**: Two-way (protocol doesn't need changes), one-way (if implementation closes the door)
- **Priority**: medium
- **Resolution**: The agent service pattern includes a self-improving workflow where agents write their own operations (tools, scripts) within a session. A POC at `/workspace/toolEnv` demonstrated the mechanism: a quickjs WASM sandbox inside Deno web workers, with a `Proxy`-based env that intercepts property access and bridges to the operation registry via `postMessage`. The sandbox runs with locked-down permissions (no net, no fs, no env). The POC exposed the full registry to the sandbox — a security gap that the scoped composition env (OQ-18) addresses.
The registry model has three tiers:
| Tier | Scope | Lifetime | Visibility | Who populates it |
|------|-------|----------|------------|-------------------|
| Core (global) | All sessions | Process lifetime, static at startup | External + Internal (curated) | Assembly layer at startup |
| Session | One session | Session lifetime, dynamic | Internal only (never wire-facing) | Agent during session (sandbox) |
| Promotion | Session → Core | One-time transition | Manual/curated review | Human or architect agent reviews, then redeploys |
Session-scoped operations are always `Internal` (never wire-facing, never in `services/list`), run under the handler's identity (the agent handler that authorized the sandbox), can only compose operations in the handler's scoped env, and are ephemeral (gone when the session ends). Core operations are curated — reviewed by a human or architect agent before promotion. The promotion path is the curation checkpoint where autonomous (session-scoped) becomes curated (core). This is not auto-promotion.
The call protocol does not need changes to support this. The `OperationEnv` trait is the composition point — a session-scoped env wraps the global env (check session registry first, fall through to global). The protocol constraints all apply regardless of which registry an operation lives in: abort cascade (OQ-17), privilege model (OQ-18), visibility (OQ-18), capabilities (ADR-014). The static registration constraint (OQ-04) applies to the global registry only; session registries are dynamic by nature and are a different registry overlaying the global one.
The one-way door this OQ guards against: an implementation that makes `OperationEnv` concrete instead of a trait, or hardcodes the global registry into the dispatch path, would close the session-overlay pattern. The trait-based design already accommodates layering — this OQ documents the pattern so a future implementation doesn't accidentally close it.
The security boundary: session-scoped operations run in a locked-down sandbox (no direct net/fs/env access), can only reach operations in the handler's scoped env, and their output should be validated against their declared schema before returning. The promotion path requires review — an agent with a `promote` scope (the architect role) performs the promotion; the writing agent (lower-privileged role) requests it. This is the role-based escalation pattern: privileges escalate through a chain of command, not through direct authority.
This is a protocol-level concern in the sense that the protocol must not prevent it, but the agent-specific mechanism (quickjs sandbox, session registry lifecycle, promotion workflow) belongs to the agent crate spec. The call protocol's job is to keep the `OperationEnv` trait composable and the visibility/ACL model consistent across tiers.
- **Cross-references**: OQ-04, OQ-17, OQ-18, ADR-014, [operation-registry.md](crates/call/operation-registry.md)