--- id: SMH-ISSUE-2Y6OFOWN type: issue title: "Nushell Plugin Authoring Path" specs: [SMH-SPEC-SPEC0001, SMH-SPEC-PLUG0001, SMH-SPEC-WASM0001, SMH-SPEC-ZVMD_XYT] --- # Nushell Plugin Authoring Path ## Gap Embedded Nu evaluation ≠ Nu plugin authoring. [Embedded Nushell](../../specs/SMH-SPEC-ZVMD_XYT-embedded-nushell/index.md) describes a granted native evaluator called by wasm plugins; it does not define how Nu source becomes a plugin component. Authors still need a contribution declaration, WIT exports, typed SDK bindings, artifact packaging, build/check/test support. No end-to-end Nu authoring path was established by this investigation. ## Existing contracts - [Plugin System](../../specs/SMH-SPEC-PLUG0001-plugin-system/index.md): ordinary components, effect-free registration, atomic generations, shared child budgets, no privileged built-in path. - [Wasm Plugin Runtime](../../specs/SMH-SPEC-WASM0001-wasm-plugin-runtime/index.md): prebuilt component plus KDL manifest, artifact hashes, no rebuild at load, sealed imports, language-adapter tooling. - [Embedded Nushell](../../specs/SMH-SPEC-ZVMD_XYT-embedded-nushell/index.md): invocation-local native evaluation, no installed interpreter, independent native bounds, controlled effects. - [Smith Specification](../../specs/SMH-SPEC-SPEC0001-smith-specification/index.md): native effect mechanisms separated from plugin-owned tool definitions; offline generated reference plus tested example source. Rust remains primary; TypeScript remains maintained compatibility target. Nu authoring support needs an explicit language contract, not silent reinterpretation of those guarantees. ## Evidence scope Desk research only. Sampled upstream Nu 0.116.0; not an adoption or version-pinning decision. No build, target-compatibility test, sandbox proof, cost measurement, or source copying performed. [Current WIT](../../../wit/smith-plugin.wit) exports only `declare-tools` and JSON `invoke`; it imports no Nu evaluator or effect interfaces. Proposed authoring paths cannot be implemented against that unchanged surface. ### Upstream distinctions - Nu custom commands provide functions, signatures, documentation, structured pipeline values.[^custom] - Rust `Command` supplies signature, description, evaluation hooks; possible SDK-command integration mechanism, not a Smith ABI.[^command] - `nu-engine` explicitly identifies itself as an internal Nu crate; Smith must own the facade and upgrade burden.[^engine] - Nu `compile` produces evaluation IR, not a wasm component.[^compile] - Native interruption uses cooperative `Signals`; this alone does not prove parsing, allocation, native-command, or deadline bounds.[^signals] - Third-party embedding examples demonstrate selective command registration on Nu 0.108; their sandbox claims are not Smith security evidence.[^embed] - Historical upstream browser demo uses `wasm-bindgen`, JS/browser imports, old Nu APIs, Git dependencies; its last inspected commit is from 2021.[^demo] - Nu plugins extend Nu through a version-matched executable protocol; they are not Smith WIT components.[^plugins] ## Candidate paths | Path | Author writes | Contract fit | Unresolved cost or risk | | --- | --- | --- | --- | | Generated wasm bridge → native Nu SDK facility | Nu handlers plus declarative contributions | Closest to existing native-evaluator intent; ordinary installed component | Native author logic lies outside wasm fuel and memory; independent bounds mandatory | | Nu evaluator compiled into each guest component | Nu handlers; generated Rust embedding glue | Author computation remains under wasm fuel and memory | Nu 0.116 target support, sealed imports, fixed memory, interpreter placement unproven | | Nu → Rust/wasm ahead-of-time compiler | Nu source | Could produce ordinary components | Inspected upstream compiler emits Nu IR; new compiler and semantic conformance work | | External `nu` or Nu plugin protocol adapter | Scripts or Nu-protocol executables | Not a substitute for the in-process evaluator or Smith component ABI | Interpreter launches, installed-version coupling, separate supervision and protocol | | Native source-only `.nu` plugin loader | Nu source | Violates current prebuilt-component identity and execution contract unless wrapped at explicit build | Requires architectural change; cannot be smuggled in as a language adapter | No measured performance ranking exists. Guest interpretation remains interpretation; compiling the Rust evaluator into wasm does not compile Nu source ahead of time. Command allow-listing does not establish native memory isolation or deadline compliance. ## Candidate to prove first Generated wasm bridge around the existing granted native Nu facility. Reason: contract reuse, not a claimed speed advantage. Reject this candidate if independent native bounds or effect mediation cannot be proved. Guest-contained evaluation remains a separate feasibility candidate, not an automatic fallback. Proposed runtime boundary: ```mermaid flowchart TB h["Host dispatch"] --> w["Ordinary wasm bridge"] w --> n["Granted native Nu facility"] n --> e["Typed Smith effects"] ``` The bridge preserves component identity; it does not place Nu computation inside the wasm sandbox. Nu command registration inside the evaluator implements SDK primitives, never a separate native tool registry. ### Authoring and artifact questions - Nu handlers own behavior; generic generated glue owns WIT adaptation, never handwritten Rust per plugin. - Contributions must come from an authoritative source declaration; do not grow manifest statics into a second contribution registry. - Build derives effect-free wasm registration data; registration cannot call the native evaluator before generation publication. - Explicit build packages source and modules inside hash-covered component bytes; no ambient source-file reads or rebuilds at load. - Invoke resolved definitions with typed arguments; never interpolate untrusted input into executable source text. - Define WIT/Nu mappings for records, variants, options, bytes, errors, resources; do not silently reduce every SDK contract to JSON strings. - Resource handles remain host-validated, invocation- and generation-scoped; no unchecked IDs, pointers, or transferable authority. - Clarify runtime Nu parsing/IR compilation versus the existing no-recompile-at-load law before promising a source-containing artifact format. - Immutable compiled declarations may be cached only with complete identity keys; mutable stack, variables, definitions, cwd, environment remain invocation-local. - Parser imports, const evaluation, redirection, externals, jobs, parallel pipelines, clocks, randomness must share controlled effect and budget boundaries. - Cancellation, exhausted budgets, sandbox violations, recording failures cannot become catchable success through Nu `try`. ### Tooling and documentation questions Language adapter extends existing `smith plugin init/build/check/test/dev`; Cargo remains build system for generated Rust components. No installed `nu` dependency at runtime. Validation uses Smith's exact exposed evaluator, not an unrelated local shell version. Generated Rust passes guest lint gates; Nu source needs explicit syntax, type, command-surface, effect, determinism, and runtime tests. Start with a real tool vertical; do not advertise providers, events, layouts, or modules until their mappings and semantics are tested. Provider decoding remains pure under the provider contract; an evaluator grant cannot introduce hidden I/O into codec calls. Two genuine consumers must earn new world interfaces. SDK reference derives from authoritative WIT/declarations; Nu binding reference derives from the same mapping. Real packages belong under `examples//`; shipped source is not auto-loaded executable configuration. Offline `smith docs` covers authoring, bindings, supported Nu semantics, diagnostics, complete tested source; bounded retrieval only. ## Proof required before implementation approval - [ ] Resolve authoring contract gaps through explicit spec approval; no spec edits implied by this issue. - [ ] Build and load two real Nu-authored consumers without handwritten Rust handlers or installed Nu. - [ ] Demonstrate ordinary registration, trust, grants, artifact hashing, failed-load rollback, atomic reload, active-generation pinning. - [ ] Prove parser and command paths cannot escape effects through files, network, processes, environment, clock, randomness, or startup configuration. - [ ] Prove independent native bounds across parsing, loops, recursion, streams, allocations, conversion, output; cancellation remains uncatchable. - [ ] Prove invocation and plugin isolation; replay repeats no external mutations. - [ ] Exercise exact exposed language and SDK bindings through built Smith with real files and supervised processes. - [ ] Compare matching cold/warm workloads for native-bridge and guest-contained candidates: allocations, instructions, artifact bytes, startup, retained memory; wall clock only as same-machine evidence. - [ ] Ship checked example packages and offline language/SDK reference with pinned provenance and license review. ## Sources [^custom]: [Nu custom commands](https://www.nushell.sh/book/custom_commands.html); live documentation, not a pinned release contract. [^command]: [Nu 0.116.0 `Command`](https://github.com/nushell/nushell/blob/0.116.0/crates/nu-protocol/src/engine/command.rs). [^engine]: [Nu 0.116.0 engine API](https://docs.rs/nu-engine/0.116.0/nu_engine/). [^compile]: [Nu 0.116.0 compiler API](https://docs.rs/nu-engine/0.116.0/nu_engine/fn.compile.html). [^signals]: [Nu 0.116.0 interruption API](https://docs.rs/nu-protocol/0.116.0/nu_protocol/struct.Signals.html). [^embed]: [Embedding guide, commit `07b212a992cebdfbafd7c75f1b9b6b8eb3113e78`](https://github.com/cablehead/how-to-embed-nu/tree/07b212a992cebdfbafd7c75f1b9b6b8eb3113e78); inspected root manifest and restricted-environment README, not executed. [^demo]: [Browser demo, commit `3fccd11c2af42127d177f6e77f6dc58768c91b91`](https://github.com/nushell/demo/tree/3fccd11c2af42127d177f6e77f6dc58768c91b91); inspected manifest and `src/lib.rs`, not executed. [^plugins]: [Nu plugins](https://www.nushell.sh/book/plugins.html); live documentation describing Nu's executable protocol, not Smith's WIT world.