NAP-SHELL / Merged specification
Optional Shell Environment and Readiness
Full specification from the fetched upstream revision ↗. The document below is rendered from its original Markdown. Follow the latest source on GitHub ↗.
NAP-SHELL
Optional Shell Environment and Readiness
draft
NAP ID: NAP-SHELL
Domain: shell
Depends: none.
Web binding (NIP-5D): window.napplet.shell; domain presence signals availability.
Description
NAP-SHELL exposes optional shell environment information and readiness notifications. It is not a prerequisite for other domains. In the web projection, the runtime injects granted domain objects before napplet scripts run. A napplet discovers a domain by its presence; no handshake establishes identity or grants capabilities.
When shell is exposed, the runtime-provided binding signals that its receiver
is installed with shell.ready. The runtime replies with shell.init, containing
an environment snapshot. This exchange serves the ready, onReady, and
services operations only. Other exposed domains remain usable before, during,
and after it.
API Surface
| Operation | Parameters | Result | Wire |
|---|---|---|---|
supports |
domain (text) |
boolean |
local projection availability query |
services |
none | list of text service names | local read of shell.init |
ready |
none | ShellEnvironment |
resolves after shell.ready / shell.init |
onReady |
handler for ShellEnvironment |
Subscription handle |
fires after shell.init |
Schemas
ShellCapabilities fields:
| Field | Required | Type | Notes |
|---|---|---|---|
domains |
yes | list of text | Bare NAP domains exposed to this napplet at snapshot time. |
ShellEnvironment fields:
| Field | Required | Type |
|---|---|---|
capabilities |
yes | ShellCapabilities |
services |
yes | list of text |
The environment is descriptive. It MUST NOT grant domains or override the projection's availability signal. Service names do not grant capabilities or introduce operations outside their owning NAP contracts.
supports(domain) — Returns whether the projection currently exposes the
bare domain to this napplet. It is synchronous and local, and MUST work before
shell.init. In the web projection it reflects the presence of the corresponding
injected domain object. Unknown or unexposed domains return false. This
convenience operation does not make shell a dependency of domain discovery.
services — A read-only list from the delivered environment. It is empty
until shell.init is received.
ready() — Resolves with the retained environment once it is received. The
runtime-provided binding sends the readiness signal automatically after
installing its receiver. Repeated calls MUST NOT send additional signals.
onReady(handler) — Registers a one-shot callback for environment delivery.
A handler registered after delivery MUST receive the retained environment.
Wire Protocol
shell.* messages use the
NIP-5D wire format
({ "type": "domain.action", ...payload }). Neither readiness message carries
an id; the environment is delivered once per napplet endpoint lifecycle.
| Type | Direction | Payload fields |
|---|---|---|
shell.ready |
napplet -> runtime | none |
shell.init |
runtime -> napplet | capabilities, services |
shell.ready carries no identity or capability claims. The runtime obtains
identity from the projection's already authenticated endpoint. shell.init
reports only this napplet's environment.
Examples
Optional environment delivery:
-> { "type": "shell.ready" }
<- {
"type": "shell.init",
"capabilities": { "domains": ["shell", "theme"] },
"services": []
}
Web projection availability, without waiting for readiness:
if (window.napplet.theme) {
const theme = await window.napplet.theme.get();
}
Error Handling
The readiness exchange has no result envelope or error field. If the environment
never arrives, a napplet MAY stop waiting under its own timeout policy. This
means shell environment information is unavailable; it MUST NOT be interpreted
as absence of other exposed domains or failure to establish napplet identity.
A napplet MUST NOT gate unrelated domain calls on ready() or onReady.
Shell Behavior
- The runtime MAY omit
shellwhile exposing other domains. - The runtime MUST bind the endpoint to verified napplet identity before
servicing any domain. It MUST NOT derive or alter identity from
shell.ready. - When
shellis exposed, its binding MUST install the receiver before sendingshell.ready. - The runtime MUST send
shell.initexactly once in response to the firstshell.readyfor that authenticated endpoint. - Duplicate
shell.readymessages MUST NOT establish another session, change policy, or cause anothershell.init. - The environment MUST describe only domains and services exposed to that napplet. It MUST NOT expose another napplet's grants.
- The binding MUST retain the environment for
ready,onReady, andservices. - The runtime MUST NOT gate other domain calls or their availability on this readiness exchange. Each domain owns its own readiness and delivery contract.
Security Considerations
- The readiness signal is untrusted input, not authentication or authorization.
- Manifest capability declarations and environment snapshots are not grants. The runtime enforces per-napplet policy independently of discovery helpers.
- Withholding
shell.initMUST NOT serve as a substitute for enforcing policy on another domain. A runtime denies a domain through the projection's availability and enforcement mechanisms. - Web identity verification, namespace injection, and transport authentication remain defined by NIP-5D.
Implementations
- (none yet)
Changelog
7ea6cd3- Introduced the shell bootstrap handshake and capability query.f86fe4b- Made the shell contract self-contained and mandatory.c616fbb- Removed deferred class support and linked the upstream web binding.a31573e- Removed mandatory shell bootstrap, made availability independent of readiness, and defined the optional environment snapshot.