WEFT_OS/docs/architecture/app-package-format.md
Marco Allegretti 668063c34b docs: specify WEFT application package format
Defines the .wapp package structure used by weft-appd to resolve an
app_id to a launchable Wasm module and UI assets.

Covers:
- App ID naming convention (reverse-domain, validation regex).
- Package store layout (, user-before-system search).
- Directory structure: wapp.toml manifest, app.wasm, ui/ subtree.
- wapp.toml schema: [package], [runtime], [ui] sections with all fields,
  types, and required/optional status documented.
- Wasm module contract with weft-runtime: READY newline startup signal,
  30-second timeout, exit code semantics, stdio handling.
- Full launch flow sequence diagram from servo-shell through weft-appd
  to weft-runtime child process.
- Explicit non-scope: signing, dependency resolution, update channels,
  sandboxing beyond WASI, multi-arch fat packages.
2026-03-11 09:04:19 +01:00

5.1 KiB

WEFT Application Package Format

Status: Design — not yet implemented.


Purpose

This document specifies the on-disk format for WEFT application packages (.wapp files). A .wapp file is the unit of distribution and installation for WEFT OS applications.

weft-appd uses this format to resolve an app_id to a launchable Wasm module and associated UI assets.


Package Identity

Each package is identified by a reverse-domain app ID — a dot-separated string using DNS naming conventions:

com.example.notes
org.weft.calculator
io.github.username.app

The app ID uniquely identifies the application within a WEFT session. It is used:

  • As the app_id field in IPC LaunchApp / TerminateApp messages.
  • As the directory name under the package store root.
  • In session registry lookups.

The app ID must match ^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*){2,}$.


Package Store

Packages are installed to:

$WEFT_APP_STORE / <app_id> /

Where WEFT_APP_STORE defaults to /usr/share/weft/apps (system) or $HOME/.local/share/weft/apps (user). weft-appd searches user store first, then system store.

The resolved package directory must contain a wapp.toml manifest.


Directory Structure

<app_id>/
├── wapp.toml          # Required. Package manifest.
├── app.wasm           # Required. The WebAssembly module (Wasm 2.0).
└── ui/                # Required. UI assets served to Servo.
    ├── index.html     # Required. Entry point loaded by servo-shell.
    └── ...            # Optional CSS, JS, images.

No other top-level files are specified. Tools must ignore unknown files.


Manifest: wapp.toml

[package]
id = "com.example.notes"
name = "Notes"
version = "1.0.0"
description = "A simple note-taking application."
author = "Example Author"

[runtime]
module = "app.wasm"

[ui]
entry = "ui/index.html"

[package] fields

Field Type Required Description
id string yes Reverse-domain app ID. Must match identity rules above.
name string yes Human-readable display name. Max 64 characters.
version string yes SemVer string.
description string no One-line description. Max 256 characters.
author string no Author name or email.

[runtime] fields

Field Type Required Description
module string yes Path to the Wasm module, relative to package directory.

[ui] fields

Field Type Required Description
entry string yes Path to the HTML entry point, relative to package directory.

Wasm Module Contract

The Wasm module is run by weft-runtime (a separate binary embedding Wasmtime).

Startup signal

The module signals readiness by writing the literal string READY\n to its standard output. weft-appd monitors the process stdout; on receiving READY\n it transitions the session state from Starting to Running and broadcasts APP_READY to connected clients.

If the module exits before writing READY\n, the session transitions to Stopped and no APP_READY is sent.

If the module does not write READY\n within 30 seconds, weft-appd sends SIGTERM and transitions the session to Stopped.

Exit codes

Exit code Meaning
0 Clean shutdown. Session transitions to Stopped.
Non-zero Abnormal exit. Session transitions to Stopped. weft-appd logs the code.

No automatic restart is performed by weft-appd. Restart policy (if any) is the responsibility of the calling client (servo-shell).

Stdio

  • stdin: closed.
  • stdout: monitored for READY\n. All other output is discarded.
  • stderr: captured and forwarded to weft-appd's tracing log at WARN level.

Capability Model

Capabilities are not yet specified. This section is reserved.

Initial implementation: no capabilities are declared or checked. The Wasm module runs with the WASI permissions granted by weft-runtime's command-line configuration.


Launch Flow

servo-shell                weft-appd               weft-runtime (child)
    |                          |                          |
    |-- LAUNCH_APP(app_id) --> |                          |
    |                          | resolve package store    |
    |                          | create session           |
    |                          | spawn weft-runtime --app |
    |                          |                       -->|
    |<-- LAUNCH_ACK(id) ---    |                          |
    |                          |        (monitors stdout) |
    |                          |<-- "READY\n" ------------|
    |                          | broadcast APP_READY      |
    |<== WS push APP_READY === |                          |

What This Format Does Not Cover

  • Package signing or verification. Not designed.
  • Dependency resolution. Not designed.
  • Update channels. Not designed.
  • Sandboxing beyond WASI. Not designed.
  • Multi-arch fat packages. Not designed. Packages are x86-64 Wasm only.