Status: design vision
This document captures the userspace direction for Aesynx. The important decision is that Aesynx should not begin by copying Unix userspace. It should be a new OS idea: capability-native, object-native, structured-data-native, WebAssembly-extensible, and AI-assisted.
Unix compatibility is not the default path. A future compatibility service can exist, but it must not define the native userspace model.
Aesynx userspace should not center on:
Unix shell -> fork native process -> text pipe -> parse text
It should center on:
aesh shell
-> launches native components or WASM components
-> grants explicit capabilities
-> connects typed streams and object channels
-> renders rich structured output
-> records telemetry, provenance, and authority use
Text remains useful, but it is not the primary OS data model. Text is a display format, import/export format, and fallback format.
Native Aesynx userspace should be:
- Capability-native: every command receives explicit authority.
- Object-native: commands work with object IDs, object caps, and immutable records.
- Structured-data-native: pipelines pass typed values, streams, and tables.
- WASM-extensible: third-party commands and scripts can run in a sandbox.
- Rust-first: core shell, runtime, and system tools are Rust.
- AI-assisted: autocomplete, explanation, summarization, and query building are integrated but constrained.
It should also expose a native OS world layer. The kernel and core services emit bounded facts; userspace stores, indexes, queries, redacts, and explains those facts. See Aesynx OS World Roadmap.
- Auditable: commands can explain what they accessed and what authority they used.
- Fast: avoid fork/text-parse overhead as the normal path.
- Portable: WASM components can run across Aesynx architectures and, where useful, on other hosts.
Do not make WASM replace all native binaries. Use two classes of components.
Native Rust components:
- Core shell.
- Core system tools.
- Device/admin tools.
- Performance-critical tools.
- Trusted services.
- Native runtime services.
WASM components:
- Downloaded tools.
- Plugins.
- Automation.
- Third-party commands.
- Sandboxed extensions.
- Portable apps and scripts.
The shell should be an orchestrator, not a place where arbitrary code receives ambient authority. WASM modules may be lightweight, precompiled, cached, and fast, but they still run in a capability-limited execution context controlled by Aesynx.
Aesynx userspace
|-- aesh
| |-- parser
| |-- planner
| |-- capability prompt/gate
| |-- structured pipeline engine
| |-- TUI renderer
| `-- AI assistant integration
|-- native components
| |-- built-ins
| |-- system commands
| `-- services
|-- WASM components
| |-- plugins
| |-- tools
| `-- automation modules
|-- component store
| |-- signed objects
| |-- manifests
| |-- cached AOT artifacts
| `-- provenance
`-- value/schema ABI
|-- typed values
|-- typed streams
|-- tables
`-- errors
The native shell is aesh.
Responsibilities:
- Parse commands and pipelines.
- Resolve command objects.
- Check command manifests.
- Ask for or verify required capabilities.
- Connect typed pipeline channels.
- Launch native and WASM components.
- Render structured outputs.
- Provide interactive views.
- Emit telemetry.
- Record provenance.
- Integrate bounded AI assistance.
aesh should support familiar command shapes, but not by copying Bash semantics.
Example:
aesh> drivers | where state == "Running" | view
aesh> objects /bin | sort name | view
aesh> fetch-logs --service api | where severity == Error | view
aesh> caps --explain
Traditional shells pass bytes or text. Aesynx pipelines pass typed values.
Traditional:
ls -l | grep "Jun"
Aesynx-native:
objects /bin | where kind == "Executable" && modified.month == "June" | view
Pipeline values may be:
- Single values.
- Records.
- Tables.
- Streams.
- Object references.
- Capability references.
- Binary blobs.
- Errors.
The shell should know what each command emits and what the next command accepts. If types do not match, the shell should fail early with a useful explanation.
The kernel and shell should not literally share Rust's compile-time type system. Rust types are implementation details. Aesynx needs a stable value/schema ABI that Rust, WASM, and future languages can all speak.
Core value model:
Unit
Bool
Int
UInt
Float
String
Bytes
Time
Duration
ObjectId
CapId
List<T>
Record { fields }
Table<T>
Stream<T>
Result<T, Error>
Option<T>
Schema metadata:
- Type name.
- Version.
- Field names.
- Field types.
- Optional/required flags.
- Units.
- Display hints.
- Security sensitivity.
- Redaction rules.
This value model should be stable enough for native commands, WASM components, object-store records, telemetry, and AI tools.
The Aesynx Component ABI is the stable interface for native components and WASM components.
It should define:
- Startup info.
- Arguments.
- Environment.
- Input/output channels.
- Capability handles.
- Object references.
- Error reporting.
- Structured value encoding.
- Telemetry hooks.
- Exit status.
For native Rust components, aesynx-rt wraps this ABI.
For WASM components, the runtime maps it to the WASM component interface. WASI concepts can be used where they fit, but Aesynx should not blindly inherit POSIX-like WASI assumptions.
Aesynx needs a first-class SDK. Developers should not write against informal kernel internals, copied C headers, or unstable syscall numbers. Native apps should build through versioned crates, target specifications, startup/runtime support, package manifests, and capability manifests. The detailed SDK plan lives in Aesynx SDK Roadmap.
The SDK should include:
aesynx-abi: stable ABI types, syscall/message numbers, handles, object IDs, capability IDs, value-schema identifiers, error codes, and wire formats.aesynx-rt: safe Rust wrappers for startup info, capability handles, structured input/output channels, logging, panic reporting, allocation hooks, and raw syscall or IPC entry points.- A minimal syscall/endpoint ABI with fixed-width numbers, flags, handles, lengths, timeouts, transaction IDs, and error codes. It does not expose Rust enum layout, slices, references, pointers, or compiler-dependent types across the kernel/user boundary.
- A process/domain lifecycle model where spawn, executable mapping, initial capability grants, scheduling context, and launch result commit atomically; failed construction restores quotas, mappings, capabilities, and scheduler state before any child runs.
- A termination lifecycle where fatal user faults, exits, kills, watchdog resets, and service restarts fence execution, revoke authority, drain resources, zero sensitive state where required, and publish exit status only through an explicit capability.
- Rust target specifications such as
x86_64-unknown-aesynxandaarch64-unknown-aesynxfor native apps. - A WASM target/profile such as
wasm32-wasip2-aesynxfor portable components, mapped onto Aesynx host calls rather than POSIX-shaped ambient filesystem assumptions. - A userspace linker/startup path comparable in purpose to
crt0, but exposed throughaesynx-rtinstead of C headers. - App templates for native commands, services, WASM components, and drivers.
- A package/app manifest schema that records artifact kind, target, entry point, exported commands, required schemas, requested capabilities, SBOM, and provenance.
- Local tooling to build, package, sign, inspect, and run a minimal app in QEMU.
The intended developer flow should eventually be:
cargo aesynx new hello --kind native-command
cargo build --target x86_64-unknown-aesynx
aepkg build
aepkg run ./target/aesynx/hello.aepkgFor WASM:
cargo aesynx new log-view --kind wasm-component
cargo build --target wasm32-wasip2-aesynx
aepkg buildThe SDK must keep the same security model as the OS. A native binary is not automatically trusted with broad access. At launch it receives an explicit capability bundle from the shell, package manager, service manager, or policy engine. Missing authority is a structured error, not an invitation to inspect a global filesystem path.
Rust target support can start as repo-owned JSON targets and build-std
experiments. Upstream Rust target support is a later ecosystem milestone, not a
requirement for the first SDK.
Every component declares the authority it wants.
Example:
name = "fetch-logs"
kind = "wasm-component"
version = "0.1.0"
[requires]
network = ["service:api-logs"]
read_objects = []
write_objects = []
[outputs]
stream = "LogEntry"The shell and component loader enforce:
- Required capabilities are explicit.
- User or policy grants are explicit.
- Components cannot gain authority by asking another component unless a grant is allowed.
- Authority use is logged.
- Denied authority produces a structured error.
Example run:
aesh> fetch-logs --service api | where severity == Error | view
The shell knows:
- What
fetch-logsmay access. - What type it emits.
- What type
whereexpects. - What type
viewexpects. - What capabilities were used.
- What provenance to record.
WASM should be the default untrusted extension format.
Why:
- Sandboxed execution.
- Portable across CPU architectures.
- Multiple source languages.
- Cacheable AOT artifacts.
- Clean host-call boundary.
- Natural fit for capability-controlled plugins.
WASM components can be written in:
- Rust.
- Go.
- TypeScript.
- Python-like languages if runtime support exists.
- Other component-model-compatible languages later.
WASM host calls must be capability-checked:
- Read object.
- Write object builder.
- Open service queue.
- Send message.
- Read typed stream.
- Emit typed value.
- Get time.
- Emit telemetry.
No WASM component gets filesystem-style ambient authority by default.
Native Rust is the right path for trusted and performance-sensitive tools.
Examples:
aesh.help.version.caps.objects.ps.cores.drivers.log.view.store.model.trace.
Native components still use capabilities. Native does not mean unrestricted.
A modern CLI should not be only monochrome text.
The shell should support:
- Tables.
- Tree views.
- Inspectors.
- Filterable logs.
- Sortable grids.
- Progress dashboards.
- Split panes.
- Inline charts.
- Error sidebars.
- Keyboard and mouse interaction where available.
The view command is a first-class renderer:
aesh> log | where severity >= Warn | view
aesh> drivers | view
aesh> trace --boot latest | view
If the terminal is limited, output falls back to plain text.
AI should be integrated, but bounded.
Allowed AI roles:
- Suggest commands.
- Explain commands.
- Explain capability requests.
- Build filters from natural language.
- Summarize structured output.
- Inspect schemas.
- Highlight anomalies.
- Help write WASM automation modules.
- Explain telemetry and traces.
Forbidden AI roles:
- Gain capabilities by itself.
- Run commands without explicit user approval.
- Bypass object/capability policy.
- Hide authority use.
- Modify system state without a reviewed plan.
- Make irreversible decisions without policy permission.
AI context should be capability-limited. If the assistant cannot read an object, it cannot summarize it.
Example:
aesh> ask "show failed driver restarts from this boot"
plan:
log --boot current
where event.kind == DriverRestart && result == Failed
view
requires:
read telemetry stream
run? yes/no
Every pipeline should be able to answer:
- Which command objects ran?
- What versions?
- What hashes?
- What capabilities were granted?
- What objects were read?
- What objects were written?
- What network/service endpoints were used?
- Which AI suggestions influenced it?
- What output object was produced?
This makes userspace naturally auditable.
Commands should work with object IDs and object capabilities naturally.
Examples:
aesh> objects /config
aesh> inspect object:01K...
aesh> store publish ./new-config
aesh> diff object:old object:new | view
aesh> rollback system-root --to object:01J...
Text paths can exist as human-friendly names, but internally they resolve through name-index objects to object IDs.
Errors should be structured, not just strings.
Error {
code: CapabilityDenied,
message: "fetch-logs cannot access service:api-logs",
missing_capability: Network("service:api-logs"),
suggested_action: GrantCapability,
safe_to_retry: true
}
This lets the shell render useful messages and lets AI explain errors without guessing from text.
- Native
aesynx-initstarts. aeshstarts with text fallback output.- Built-ins work:
- help
- version
- echo
- caps
- objects
- ps
- log
- Aesynx Value Model exists for simple records and tables.
objects /bin | viewrenders a table.- Native typed pipeline works.
- Component manifests declare capabilities.
- WASM runtime prototype runs a no-authority command.
- WASM command requests a capability and is denied/granted explicitly.
- AI command explanation works with no authority escalation.
Native userspace should eventually grow into the package-management model in Aesynx Package Manager Roadmap.
The important userspace connection is that package installation, removal,
updates, health repair, and rollback should be ordinary capability-checked
structured operations. aesh can expose them as pkg commands and typed
pipelines, while future GUI or TUI store clients use the same package daemon
API.
Package lookup can also support lazy command execution: when a command is not
present locally, aesh may ask the package service for signed command exports
and present track, publisher, capability, price, and persistence choices before
running or installing anything. This must be policy-controlled and disabled by
default in high-security contexts.
Minimum 1.0:
- Native
aesynx-init. - Native
aesh. - Native core commands.
- Text fallback rendering.
- Initial structured values.
- Basic typed tables.
- Capability manifests for commands.
- Object-name lookup.
- Shell telemetry.
- AI-ready command/explanation hooks.
Preferred 1.0:
viewTUI for tables/logs.- WASM no-authority component.
- WASM capability prompt demo.
- Structured pipeline type checking.
- Pipeline provenance log.
- AI-assisted command explanation.
Not required for 1.0:
- Bash.
- POSIX shell semantics.
- Linux binary compatibility.
- Full WASI compatibility.
- Dynamic native shared libraries.
- Browser-grade GUI.
- Cloud AI integration.
The core userspace rule is:
Aesynx is not Unix-compatible by default.
Aesynx is capability-native, object-native, structured-data-native, WASM-extensible, and AI-assisted.