From f4fada29d0ffd181b7eb3b4335499e0c3a516f63 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 10 Jun 2026 22:53:56 -0400 Subject: [PATCH 1/3] Stage WASI 0.2 freeze by removing p3 drafts --- proposals/cli/wit-0.3.0-draft/command.wit | 10 - proposals/cli/wit-0.3.0-draft/deps.lock | 19 - proposals/cli/wit-0.3.0-draft/deps.toml | 4 - proposals/cli/wit-0.3.0-draft/environment.wit | 22 - proposals/cli/wit-0.3.0-draft/exit.wit | 17 - proposals/cli/wit-0.3.0-draft/imports.wit | 34 - proposals/cli/wit-0.3.0-draft/run.wit | 6 - proposals/cli/wit-0.3.0-draft/stdio.wit | 65 -- proposals/cli/wit-0.3.0-draft/terminal.wit | 62 -- .../wit-0.3.0-draft/monotonic-clock.wit | 48 -- .../clocks/wit-0.3.0-draft/system-clock.wit | 51 -- proposals/clocks/wit-0.3.0-draft/timezone.wit | 46 - proposals/clocks/wit-0.3.0-draft/types.wit | 8 - proposals/clocks/wit-0.3.0-draft/world.wit | 11 - .../filesystem/wit-0.3.0-draft/deps.lock | 4 - .../filesystem/wit-0.3.0-draft/deps.toml | 1 - .../filesystem/wit-0.3.0-draft/preopens.wit | 11 - .../filesystem/wit-0.3.0-draft/types.wit | 658 -------------- .../filesystem/wit-0.3.0-draft/world.wit | 9 - proposals/http/wit-0.3.0-draft/deps.lock | 22 - proposals/http/wit-0.3.0-draft/deps.toml | 2 - proposals/http/wit-0.3.0-draft/types.wit | 472 ---------- proposals/http/wit-0.3.0-draft/worlds.wit | 86 -- .../random/wit-0.3.0-draft/insecure-seed.wit | 27 - proposals/random/wit-0.3.0-draft/insecure.wit | 32 - proposals/random/wit-0.3.0-draft/random.wit | 37 - proposals/random/wit-0.3.0-draft/world.wit | 13 - proposals/sockets/wit-0.3.0-draft/deps.lock | 4 - proposals/sockets/wit-0.3.0-draft/deps.toml | 1 - .../wit-0.3.0-draft/ip-name-lookup.wit | 61 -- proposals/sockets/wit-0.3.0-draft/types.wit | 812 ------------------ proposals/sockets/wit-0.3.0-draft/world.wit | 9 - 32 files changed, 2664 deletions(-) delete mode 100644 proposals/cli/wit-0.3.0-draft/command.wit delete mode 100644 proposals/cli/wit-0.3.0-draft/deps.lock delete mode 100644 proposals/cli/wit-0.3.0-draft/deps.toml delete mode 100644 proposals/cli/wit-0.3.0-draft/environment.wit delete mode 100644 proposals/cli/wit-0.3.0-draft/exit.wit delete mode 100644 proposals/cli/wit-0.3.0-draft/imports.wit delete mode 100644 proposals/cli/wit-0.3.0-draft/run.wit delete mode 100644 proposals/cli/wit-0.3.0-draft/stdio.wit delete mode 100644 proposals/cli/wit-0.3.0-draft/terminal.wit delete mode 100644 proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit delete mode 100644 proposals/clocks/wit-0.3.0-draft/system-clock.wit delete mode 100644 proposals/clocks/wit-0.3.0-draft/timezone.wit delete mode 100644 proposals/clocks/wit-0.3.0-draft/types.wit delete mode 100644 proposals/clocks/wit-0.3.0-draft/world.wit delete mode 100644 proposals/filesystem/wit-0.3.0-draft/deps.lock delete mode 100644 proposals/filesystem/wit-0.3.0-draft/deps.toml delete mode 100644 proposals/filesystem/wit-0.3.0-draft/preopens.wit delete mode 100644 proposals/filesystem/wit-0.3.0-draft/types.wit delete mode 100644 proposals/filesystem/wit-0.3.0-draft/world.wit delete mode 100644 proposals/http/wit-0.3.0-draft/deps.lock delete mode 100644 proposals/http/wit-0.3.0-draft/deps.toml delete mode 100644 proposals/http/wit-0.3.0-draft/types.wit delete mode 100644 proposals/http/wit-0.3.0-draft/worlds.wit delete mode 100644 proposals/random/wit-0.3.0-draft/insecure-seed.wit delete mode 100644 proposals/random/wit-0.3.0-draft/insecure.wit delete mode 100644 proposals/random/wit-0.3.0-draft/random.wit delete mode 100644 proposals/random/wit-0.3.0-draft/world.wit delete mode 100644 proposals/sockets/wit-0.3.0-draft/deps.lock delete mode 100644 proposals/sockets/wit-0.3.0-draft/deps.toml delete mode 100644 proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit delete mode 100644 proposals/sockets/wit-0.3.0-draft/types.wit delete mode 100644 proposals/sockets/wit-0.3.0-draft/world.wit diff --git a/proposals/cli/wit-0.3.0-draft/command.wit b/proposals/cli/wit-0.3.0-draft/command.wit deleted file mode 100644 index 12cdb1044..000000000 --- a/proposals/cli/wit-0.3.0-draft/command.wit +++ /dev/null @@ -1,10 +0,0 @@ -package wasi:cli@0.3.0-rc-2026-03-15; - -@since(version = 0.3.0-rc-2026-03-15) -world command { - @since(version = 0.3.0-rc-2026-03-15) - include imports; - - @since(version = 0.3.0-rc-2026-03-15) - export run; -} diff --git a/proposals/cli/wit-0.3.0-draft/deps.lock b/proposals/cli/wit-0.3.0-draft/deps.lock deleted file mode 100644 index c3eb59ccc..000000000 --- a/proposals/cli/wit-0.3.0-draft/deps.lock +++ /dev/null @@ -1,19 +0,0 @@ -[clocks] -path = "../../clocks/wit-0.3.0-draft" -sha256 = "a8702c42e23c22a458207d0efa38cc1b64c8c6299b0e3152aa84327a7c1c952b" -sha512 = "da69a5d498b6afe0facf77ec3d21f6e8a2a4d4661ebfec310a2ce6f943cb01f92131a746765648febf96563ddac788e9f218941d3db2b905f3746dc8e05cf54d" - -[filesystem] -path = "../../filesystem/wit-0.3.0-draft" -sha256 = "d9db43c43b4e09899a9e54c76544eef17439fb42e2f730ed96d40eac994b0dfd" -sha512 = "3b7a1bef322ba36b1e9df768d740e4238f58d3c15d3e4c51fe899b93cf1e6641a79b5a8665ae71d38a80e1e0f852b30b023ecf318f4cbeacb36dd1ae0ac7e37b" - -[random] -path = "../../random/wit-0.3.0-draft" -sha256 = "d44de4e427505fdfd584a23479dba5899ad80aa8e174dc0528df840db8ae9a43" -sha512 = "6b08b32a197aee74076d0cdca6a09f78da9040eedd9ab3f64e5f14901ad5a0c5bbc592ad46a0d575dc6705249b3e10a413e09835616f753788aa598af605c776" - -[sockets] -path = "../../sockets/wit-0.3.0-draft" -sha256 = "ee64b45d3826b6ff2cd27f6ac24fe23c41e65ba4d155294671dc7d0a0b47ddfe" -sha512 = "dd797ab47b899aee52799f797497fa286f5e217307e8a451a7ba89bd05b7b9bfe2a6e0cf39c0e609ed4c76ed102487adff6e73156340f14baf70a9cc9e48ecbc" diff --git a/proposals/cli/wit-0.3.0-draft/deps.toml b/proposals/cli/wit-0.3.0-draft/deps.toml deleted file mode 100644 index e66b87555..000000000 --- a/proposals/cli/wit-0.3.0-draft/deps.toml +++ /dev/null @@ -1,4 +0,0 @@ -clocks = "../../clocks/wit-0.3.0-draft" -sockets = "../../sockets/wit-0.3.0-draft" -random = "../../random/wit-0.3.0-draft" -filesystem = "../../filesystem/wit-0.3.0-draft" diff --git a/proposals/cli/wit-0.3.0-draft/environment.wit b/proposals/cli/wit-0.3.0-draft/environment.wit deleted file mode 100644 index 7abda6b60..000000000 --- a/proposals/cli/wit-0.3.0-draft/environment.wit +++ /dev/null @@ -1,22 +0,0 @@ -@since(version = 0.3.0-rc-2026-03-15) -interface environment { - /// Get the POSIX-style environment variables. - /// - /// Each environment variable is provided as a pair of string variable names - /// and string value. - /// - /// Morally, these are a value import, but until value imports are available - /// in the component model, this import function should return the same - /// values each time it is called. - @since(version = 0.3.0-rc-2026-03-15) - get-environment: func() -> list>; - - /// Get the POSIX-style arguments to the program. - @since(version = 0.3.0-rc-2026-03-15) - get-arguments: func() -> list; - - /// Return a path that programs should use as their initial current working - /// directory, interpreting `.` as shorthand for this. - @since(version = 0.3.0-rc-2026-03-15) - get-initial-cwd: func() -> option; -} diff --git a/proposals/cli/wit-0.3.0-draft/exit.wit b/proposals/cli/wit-0.3.0-draft/exit.wit deleted file mode 100644 index 24e337d5b..000000000 --- a/proposals/cli/wit-0.3.0-draft/exit.wit +++ /dev/null @@ -1,17 +0,0 @@ -@since(version = 0.3.0-rc-2026-03-15) -interface exit { - /// Exit the current instance and any linked instances. - @since(version = 0.3.0-rc-2026-03-15) - exit: func(status: result); - - /// Exit the current instance and any linked instances, reporting the - /// specified status code to the host. - /// - /// The meaning of the code depends on the context, with 0 usually meaning - /// "success", and other values indicating various types of failure. - /// - /// This function does not return; the effect is analogous to a trap, but - /// without the connotation that something bad has happened. - @since(version = 0.3.0-rc-2026-03-15) - exit-with-code: func(status-code: u8); -} diff --git a/proposals/cli/wit-0.3.0-draft/imports.wit b/proposals/cli/wit-0.3.0-draft/imports.wit deleted file mode 100644 index 398b632d8..000000000 --- a/proposals/cli/wit-0.3.0-draft/imports.wit +++ /dev/null @@ -1,34 +0,0 @@ -package wasi:cli@0.3.0-rc-2026-03-15; - -@since(version = 0.3.0-rc-2026-03-15) -world imports { - @since(version = 0.3.0-rc-2026-03-15) - include wasi:clocks/imports@0.3.0-rc-2026-03-15; - @since(version = 0.3.0-rc-2026-03-15) - include wasi:filesystem/imports@0.3.0-rc-2026-03-15; - @since(version = 0.3.0-rc-2026-03-15) - include wasi:sockets/imports@0.3.0-rc-2026-03-15; - @since(version = 0.3.0-rc-2026-03-15) - include wasi:random/imports@0.3.0-rc-2026-03-15; - - @since(version = 0.3.0-rc-2026-03-15) - import environment; - @since(version = 0.3.0-rc-2026-03-15) - import exit; - @since(version = 0.3.0-rc-2026-03-15) - import stdin; - @since(version = 0.3.0-rc-2026-03-15) - import stdout; - @since(version = 0.3.0-rc-2026-03-15) - import stderr; - @since(version = 0.3.0-rc-2026-03-15) - import terminal-input; - @since(version = 0.3.0-rc-2026-03-15) - import terminal-output; - @since(version = 0.3.0-rc-2026-03-15) - import terminal-stdin; - @since(version = 0.3.0-rc-2026-03-15) - import terminal-stdout; - @since(version = 0.3.0-rc-2026-03-15) - import terminal-stderr; -} diff --git a/proposals/cli/wit-0.3.0-draft/run.wit b/proposals/cli/wit-0.3.0-draft/run.wit deleted file mode 100644 index d65831096..000000000 --- a/proposals/cli/wit-0.3.0-draft/run.wit +++ /dev/null @@ -1,6 +0,0 @@ -@since(version = 0.3.0-rc-2026-03-15) -interface run { - /// Run the program. - @since(version = 0.3.0-rc-2026-03-15) - run: async func() -> result; -} diff --git a/proposals/cli/wit-0.3.0-draft/stdio.wit b/proposals/cli/wit-0.3.0-draft/stdio.wit deleted file mode 100644 index a46ee6da0..000000000 --- a/proposals/cli/wit-0.3.0-draft/stdio.wit +++ /dev/null @@ -1,65 +0,0 @@ -@since(version = 0.3.0-rc-2026-03-15) -interface types { - @since(version = 0.3.0-rc-2026-03-15) - enum error-code { - /// Input/output error - io, - /// Invalid or incomplete multibyte or wide character - illegal-byte-sequence, - /// Broken pipe - pipe, - } -} - -@since(version = 0.3.0-rc-2026-03-15) -interface stdin { - use types.{error-code}; - - /// Return a stream for reading from stdin. - /// - /// This function returns a stream which provides data read from stdin, - /// and a future to signal read results. - /// - /// If the stream's readable end is dropped the future will resolve to success. - /// - /// If the stream's writable end is dropped the future will either resolve to - /// success if stdin was closed by the writer or to an error-code if reading - /// failed for some other reason. - /// - /// Multiple streams may be active at the same time. The behavior of concurrent - /// reads is implementation-specific. - @since(version = 0.3.0-rc-2026-03-15) - read-via-stream: func() -> tuple, future>>; -} - -@since(version = 0.3.0-rc-2026-03-15) -interface stdout { - use types.{error-code}; - - /// Write the given stream to stdout. - /// - /// If the stream's writable end is dropped this function will either return - /// success once the entire contents of the stream have been written or an - /// error-code representing a failure. - /// - /// Otherwise if there is an error the readable end of the stream will be - /// dropped and this function will return an error-code. - @since(version = 0.3.0-rc-2026-03-15) - write-via-stream: func(data: stream) -> future>; -} - -@since(version = 0.3.0-rc-2026-03-15) -interface stderr { - use types.{error-code}; - - /// Write the given stream to stderr. - /// - /// If the stream's writable end is dropped this function will either return - /// success once the entire contents of the stream have been written or an - /// error-code representing a failure. - /// - /// Otherwise if there is an error the readable end of the stream will be - /// dropped and this function will return an error-code. - @since(version = 0.3.0-rc-2026-03-15) - write-via-stream: func(data: stream) -> future>; -} diff --git a/proposals/cli/wit-0.3.0-draft/terminal.wit b/proposals/cli/wit-0.3.0-draft/terminal.wit deleted file mode 100644 index 3ae61915b..000000000 --- a/proposals/cli/wit-0.3.0-draft/terminal.wit +++ /dev/null @@ -1,62 +0,0 @@ -/// Terminal input. -/// -/// In the future, this may include functions for disabling echoing, -/// disabling input buffering so that keyboard events are sent through -/// immediately, querying supported features, and so on. -@since(version = 0.3.0-rc-2026-03-15) -interface terminal-input { - /// The input side of a terminal. - @since(version = 0.3.0-rc-2026-03-15) - resource terminal-input; -} - -/// Terminal output. -/// -/// In the future, this may include functions for querying the terminal -/// size, being notified of terminal size changes, querying supported -/// features, and so on. -@since(version = 0.3.0-rc-2026-03-15) -interface terminal-output { - /// The output side of a terminal. - @since(version = 0.3.0-rc-2026-03-15) - resource terminal-output; -} - -/// An interface providing an optional `terminal-input` for stdin as a -/// link-time authority. -@since(version = 0.3.0-rc-2026-03-15) -interface terminal-stdin { - @since(version = 0.3.0-rc-2026-03-15) - use terminal-input.{terminal-input}; - - /// If stdin is connected to a terminal, return a `terminal-input` handle - /// allowing further interaction with it. - @since(version = 0.3.0-rc-2026-03-15) - get-terminal-stdin: func() -> option; -} - -/// An interface providing an optional `terminal-output` for stdout as a -/// link-time authority. -@since(version = 0.3.0-rc-2026-03-15) -interface terminal-stdout { - @since(version = 0.3.0-rc-2026-03-15) - use terminal-output.{terminal-output}; - - /// If stdout is connected to a terminal, return a `terminal-output` handle - /// allowing further interaction with it. - @since(version = 0.3.0-rc-2026-03-15) - get-terminal-stdout: func() -> option; -} - -/// An interface providing an optional `terminal-output` for stderr as a -/// link-time authority. -@since(version = 0.3.0-rc-2026-03-15) -interface terminal-stderr { - @since(version = 0.3.0-rc-2026-03-15) - use terminal-output.{terminal-output}; - - /// If stderr is connected to a terminal, return a `terminal-output` handle - /// allowing further interaction with it. - @since(version = 0.3.0-rc-2026-03-15) - get-terminal-stderr: func() -> option; -} diff --git a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit b/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit deleted file mode 100644 index 786ae103b..000000000 --- a/proposals/clocks/wit-0.3.0-draft/monotonic-clock.wit +++ /dev/null @@ -1,48 +0,0 @@ -package wasi:clocks@0.3.0-rc-2026-03-15; -/// WASI Monotonic Clock is a clock API intended to let users measure elapsed -/// time. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -/// -/// A monotonic clock is a clock which has an unspecified initial value, and -/// successive reads of the clock will produce non-decreasing values. -@since(version = 0.3.0-rc-2026-03-15) -interface monotonic-clock { - use types.{duration}; - - /// A mark on a monotonic clock is a number of nanoseconds since an - /// unspecified initial value, and can only be compared to instances from - /// the same monotonic-clock. - @since(version = 0.3.0-rc-2026-03-15) - type mark = u64; - - /// Read the current value of the clock. - /// - /// The clock is monotonic, therefore calling this function repeatedly will - /// produce a sequence of non-decreasing values. - /// - /// For completeness, this function traps if it's not possible to represent - /// the value of the clock in a `mark`. Consequently, implementations - /// should ensure that the starting time is low enough to avoid the - /// possibility of overflow in practice. - @since(version = 0.3.0-rc-2026-03-15) - now: func() -> mark; - - /// Query the resolution of the clock. Returns the duration of time - /// corresponding to a clock tick. - @since(version = 0.3.0-rc-2026-03-15) - get-resolution: func() -> duration; - - /// Wait until the specified mark has occurred. - @since(version = 0.3.0-rc-2026-03-15) - wait-until: async func( - when: mark, - ); - - /// Wait for the specified duration to elapse. - @since(version = 0.3.0-rc-2026-03-15) - wait-for: async func( - how-long: duration, - ); -} diff --git a/proposals/clocks/wit-0.3.0-draft/system-clock.wit b/proposals/clocks/wit-0.3.0-draft/system-clock.wit deleted file mode 100644 index f8c16611d..000000000 --- a/proposals/clocks/wit-0.3.0-draft/system-clock.wit +++ /dev/null @@ -1,51 +0,0 @@ -package wasi:clocks@0.3.0-rc-2026-03-15; -/// WASI System Clock is a clock API intended to let users query the current -/// time. The clock is not necessarily monotonic as it may be reset. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -/// -/// External references may be reset, so this clock is not necessarily -/// monotonic, making it unsuitable for measuring elapsed time. -/// -/// It is intended for reporting the current date and time for humans. -@since(version = 0.3.0-rc-2026-03-15) -interface system-clock { - use types.{duration}; - - /// An "instant", or "exact time", is a point in time without regard to any - /// time zone: just the time since a particular external reference point, - /// often called an "epoch". - /// - /// Here, the epoch is 1970-01-01T00:00:00Z, also known as - /// [POSIX's Seconds Since the Epoch], also known as [Unix Time]. - /// - /// Note that even if the seconds field is negative, incrementing - /// nanoseconds always represents moving forwards in time. - /// For example, `{ -1 seconds, 999999999 nanoseconds }` represents the - /// instant one nanosecond before the epoch. - /// For more on various different ways to represent time, see - /// https://tc39.es/proposal-temporal/docs/timezone.html - /// - /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 - /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - @since(version = 0.3.0-rc-2026-03-15) - record instant { - seconds: s64, - nanoseconds: u32, - } - - /// Read the current value of the clock. - /// - /// This clock is not monotonic, therefore calling this function repeatedly - /// will not necessarily produce a sequence of non-decreasing values. - /// - /// The nanoseconds field of the output is always less than 1000000000. - @since(version = 0.3.0-rc-2026-03-15) - now: func() -> instant; - - /// Query the resolution of the clock. Returns the smallest duration of time - /// that the implementation permits distinguishing. - @since(version = 0.3.0-rc-2026-03-15) - get-resolution: func() -> duration; -} diff --git a/proposals/clocks/wit-0.3.0-draft/timezone.wit b/proposals/clocks/wit-0.3.0-draft/timezone.wit deleted file mode 100644 index 8b2e3e835..000000000 --- a/proposals/clocks/wit-0.3.0-draft/timezone.wit +++ /dev/null @@ -1,46 +0,0 @@ -package wasi:clocks@0.3.0-rc-2026-03-15; - -@unstable(feature = clocks-timezone) -interface timezone { - @unstable(feature = clocks-timezone) - use system-clock.{instant}; - - /// Return the IANA identifier of the currently configured timezone. This - /// should be an identifier from the IANA Time Zone Database. - /// - /// For displaying to a user, the identifier should be converted into a - /// localized name by means of an internationalization API. - /// - /// If the implementation does not expose an actual timezone, or is unable - /// to provide mappings from times to deltas between the configured timezone - /// and UTC, or determining the current timezone fails, or the timezone does - /// not have an IANA identifier, this returns nothing. - @unstable(feature = clocks-timezone) - iana-id: func() -> option; - - /// The number of nanoseconds difference between UTC time and the local - /// time of the currently configured timezone, at the exact time of - /// `instant`. - /// - /// The magnitude of the returned value will always be less than - /// 86,400,000,000,000 which is the number of nanoseconds in a day - /// (24*60*60*1e9). - /// - /// If the implementation does not expose an actual timezone, or is unable - /// to provide mappings from times to deltas between the configured timezone - /// and UTC, or determining the current timezone fails, this returns - /// nothing. - @unstable(feature = clocks-timezone) - utc-offset: func(when: instant) -> option; - - /// Returns a string that is suitable to assist humans in debugging whether - /// any timezone is available, and if so, which. This may be the same string - /// as `iana-id`, or a formatted representation of the UTC offset such as - /// `-04:00`, or something else. - /// - /// WARNING: The returned string should not be consumed mechanically! It may - /// change across platforms, hosts, or other implementation details. Parsing - /// this string is a major platform-compatibility hazard. - @unstable(feature = clocks-timezone) - to-debug-string: func() -> string; -} diff --git a/proposals/clocks/wit-0.3.0-draft/types.wit b/proposals/clocks/wit-0.3.0-draft/types.wit deleted file mode 100644 index 0da1a6cb9..000000000 --- a/proposals/clocks/wit-0.3.0-draft/types.wit +++ /dev/null @@ -1,8 +0,0 @@ -package wasi:clocks@0.3.0-rc-2026-03-15; -/// This interface common types used throughout wasi:clocks. -@since(version = 0.3.0-rc-2026-03-15) -interface types { - /// A duration of time, in nanoseconds. - @since(version = 0.3.0-rc-2026-03-15) - type duration = u64; -} diff --git a/proposals/clocks/wit-0.3.0-draft/world.wit b/proposals/clocks/wit-0.3.0-draft/world.wit deleted file mode 100644 index ac51f7fc9..000000000 --- a/proposals/clocks/wit-0.3.0-draft/world.wit +++ /dev/null @@ -1,11 +0,0 @@ -package wasi:clocks@0.3.0-rc-2026-03-15; - -@since(version = 0.3.0-rc-2026-03-15) -world imports { - @since(version = 0.3.0-rc-2026-03-15) - import monotonic-clock; - @since(version = 0.3.0-rc-2026-03-15) - import system-clock; - @unstable(feature = clocks-timezone) - import timezone; -} diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.lock b/proposals/filesystem/wit-0.3.0-draft/deps.lock deleted file mode 100644 index a780d3df7..000000000 --- a/proposals/filesystem/wit-0.3.0-draft/deps.lock +++ /dev/null @@ -1,4 +0,0 @@ -[clocks] -path = "../../clocks/wit-0.3.0-draft" -sha256 = "a8702c42e23c22a458207d0efa38cc1b64c8c6299b0e3152aa84327a7c1c952b" -sha512 = "da69a5d498b6afe0facf77ec3d21f6e8a2a4d4661ebfec310a2ce6f943cb01f92131a746765648febf96563ddac788e9f218941d3db2b905f3746dc8e05cf54d" diff --git a/proposals/filesystem/wit-0.3.0-draft/deps.toml b/proposals/filesystem/wit-0.3.0-draft/deps.toml deleted file mode 100644 index c54398c1a..000000000 --- a/proposals/filesystem/wit-0.3.0-draft/deps.toml +++ /dev/null @@ -1 +0,0 @@ -clocks = "../../clocks/wit-0.3.0-draft" diff --git a/proposals/filesystem/wit-0.3.0-draft/preopens.wit b/proposals/filesystem/wit-0.3.0-draft/preopens.wit deleted file mode 100644 index 2c4560af9..000000000 --- a/proposals/filesystem/wit-0.3.0-draft/preopens.wit +++ /dev/null @@ -1,11 +0,0 @@ -package wasi:filesystem@0.3.0-rc-2026-03-15; - -@since(version = 0.3.0-rc-2026-03-15) -interface preopens { - @since(version = 0.3.0-rc-2026-03-15) - use types.{descriptor}; - - /// Return the set of preopened directories, and their paths. - @since(version = 0.3.0-rc-2026-03-15) - get-directories: func() -> list>; -} diff --git a/proposals/filesystem/wit-0.3.0-draft/types.wit b/proposals/filesystem/wit-0.3.0-draft/types.wit deleted file mode 100644 index d02ce7353..000000000 --- a/proposals/filesystem/wit-0.3.0-draft/types.wit +++ /dev/null @@ -1,658 +0,0 @@ -package wasi:filesystem@0.3.0-rc-2026-03-15; -/// WASI filesystem is a filesystem API primarily intended to let users run WASI -/// programs that access their files on their existing filesystems, without -/// significant overhead. -/// -/// Paths are passed as interface-type `string`s, meaning they must consist of -/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain -/// paths which are not accessible by this API. -/// -/// The directory separator in WASI is always the forward-slash (`/`). -/// -/// All paths in WASI are relative paths, and are interpreted relative to a -/// `descriptor` referring to a base directory. If a `path` argument to any WASI -/// function starts with `/`, or if any step of resolving a `path`, including -/// `..` and symbolic link steps, reaches a directory outside of the base -/// directory, or reaches a symlink to an absolute or rooted path in the -/// underlying filesystem, the function fails with `error-code::not-permitted`. -/// -/// For more information about WASI path resolution and sandboxing, see -/// [WASI filesystem path resolution]. -/// -/// Though this package presents a portable interface modelled on POSIX, it -/// prioritizes compatibility over portability: allowing users to access their -/// files on their machine is more important than exposing a single semantics -/// across all platforms. Notably, depending on the underlying operating system -/// and file system: -/// * Paths may be case-folded or not. -/// * Deleting (unlinking) a file may fail if there are other file descriptors -/// open. -/// * Durability and atomicity of changes to underlying files when there are -/// concurrent writers. -/// -/// Users that need well-defined, portable semantics should use a key-value -/// store or a database instead. -/// -/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -@since(version = 0.3.0-rc-2026-03-15) -interface types { - @since(version = 0.3.0-rc-2026-03-15) - use wasi:clocks/system-clock@0.3.0-rc-2026-03-15.{instant}; - - /// File size or length of a region within a file. - @since(version = 0.3.0-rc-2026-03-15) - type filesize = u64; - - /// The type of a filesystem object referenced by a descriptor. - /// - /// Note: This was called `filetype` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - variant descriptor-type { - /// The descriptor refers to a block device inode. - block-device, - /// The descriptor refers to a character device inode. - character-device, - /// The descriptor refers to a directory inode. - directory, - /// The descriptor refers to a named pipe. - fifo, - /// The file refers to a symbolic link inode. - symbolic-link, - /// The descriptor refers to a regular file inode. - regular-file, - /// The descriptor refers to a socket. - socket, - /// The type of the descriptor or file is different from any of the - /// other types specified. - other(option), - } - - /// Descriptor flags. - /// - /// Note: This was called `fdflags` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - flags descriptor-flags { - /// Read mode: Data can be read. - read, - /// Write mode: Data can be written to. - write, - /// Request that writes be performed according to synchronized I/O file - /// integrity completion. The data stored in the file and the file's - /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - file-integrity-sync, - /// Request that writes be performed according to synchronized I/O data - /// integrity completion. Only the data stored in the file is - /// synchronized. This is similar to `O_DSYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - data-integrity-sync, - /// Requests that reads be performed at the same level of integrity - /// requested for writes. This is similar to `O_RSYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - requested-write-sync, - /// Mutating directories mode: Directory contents may be mutated. - /// - /// When this flag is unset on a descriptor, operations using the - /// descriptor which would create, rename, delete, modify the data or - /// metadata of filesystem objects, or obtain another handle which - /// would permit any of those, shall fail with `error-code::read-only` if - /// they would otherwise succeed. - /// - /// This may only be set on directories. - mutate-directory, - } - - /// File attributes. - /// - /// Note: This was called `filestat` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - record descriptor-stat { - /// File type. - %type: descriptor-type, - /// Number of hard links to the file. - link-count: link-count, - /// For regular files, the file size in bytes. For symbolic links, the - /// length in bytes of the pathname contained in the symbolic link. - size: filesize, - /// Last data access timestamp. - /// - /// If the `option` is none, the platform doesn't maintain an access - /// timestamp for this file. - data-access-timestamp: option, - /// Last data modification timestamp. - /// - /// If the `option` is none, the platform doesn't maintain a - /// modification timestamp for this file. - data-modification-timestamp: option, - /// Last file status-change timestamp. - /// - /// If the `option` is none, the platform doesn't maintain a - /// status-change timestamp for this file. - status-change-timestamp: option, - } - - /// Flags determining the method of how paths are resolved. - @since(version = 0.3.0-rc-2026-03-15) - flags path-flags { - /// As long as the resolved path corresponds to a symbolic link, it is - /// expanded. - symlink-follow, - } - - /// Open flags used by `open-at`. - @since(version = 0.3.0-rc-2026-03-15) - flags open-flags { - /// Create file if it does not exist, similar to `O_CREAT` in POSIX. - create, - /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. - directory, - /// Fail if file already exists, similar to `O_EXCL` in POSIX. - exclusive, - /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. - truncate, - } - - /// Number of hard links to an inode. - @since(version = 0.3.0-rc-2026-03-15) - type link-count = u64; - - /// When setting a timestamp, this gives the value to set it to. - @since(version = 0.3.0-rc-2026-03-15) - variant new-timestamp { - /// Leave the timestamp set to its previous value. - no-change, - /// Set the timestamp to the current time of the system clock associated - /// with the filesystem. - now, - /// Set the timestamp to the given value. - timestamp(instant), - } - - /// A directory entry. - @since(version = 0.3.0-rc-2026-03-15) - record directory-entry { - /// The type of the file referred to by this directory entry. - %type: descriptor-type, - - /// The name of the object. - name: string, - } - - /// Error codes returned by functions, similar to `errno` in POSIX. - /// Not all of these error codes are returned by the functions provided by this - /// API; some are used in higher-level library layers, and others are provided - /// merely for alignment with POSIX. - @since(version = 0.3.0-rc-2026-03-15) - variant error-code { - /// Permission denied, similar to `EACCES` in POSIX. - access, - /// Connection already in progress, similar to `EALREADY` in POSIX. - already, - /// Bad descriptor, similar to `EBADF` in POSIX. - bad-descriptor, - /// Device or resource busy, similar to `EBUSY` in POSIX. - busy, - /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. - deadlock, - /// Storage quota exceeded, similar to `EDQUOT` in POSIX. - quota, - /// File exists, similar to `EEXIST` in POSIX. - exist, - /// File too large, similar to `EFBIG` in POSIX. - file-too-large, - /// Illegal byte sequence, similar to `EILSEQ` in POSIX. - illegal-byte-sequence, - /// Operation in progress, similar to `EINPROGRESS` in POSIX. - in-progress, - /// Interrupted function, similar to `EINTR` in POSIX. - interrupted, - /// Invalid argument, similar to `EINVAL` in POSIX. - invalid, - /// I/O error, similar to `EIO` in POSIX. - io, - /// Is a directory, similar to `EISDIR` in POSIX. - is-directory, - /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. - loop, - /// Too many links, similar to `EMLINK` in POSIX. - too-many-links, - /// Message too large, similar to `EMSGSIZE` in POSIX. - message-size, - /// Filename too long, similar to `ENAMETOOLONG` in POSIX. - name-too-long, - /// No such device, similar to `ENODEV` in POSIX. - no-device, - /// No such file or directory, similar to `ENOENT` in POSIX. - no-entry, - /// No locks available, similar to `ENOLCK` in POSIX. - no-lock, - /// Not enough space, similar to `ENOMEM` in POSIX. - insufficient-memory, - /// No space left on device, similar to `ENOSPC` in POSIX. - insufficient-space, - /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. - not-directory, - /// Directory not empty, similar to `ENOTEMPTY` in POSIX. - not-empty, - /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. - not-recoverable, - /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. - unsupported, - /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. - no-tty, - /// No such device or address, similar to `ENXIO` in POSIX. - no-such-device, - /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. - overflow, - /// Operation not permitted, similar to `EPERM` in POSIX. - not-permitted, - /// Broken pipe, similar to `EPIPE` in POSIX. - pipe, - /// Read-only file system, similar to `EROFS` in POSIX. - read-only, - /// Invalid seek, similar to `ESPIPE` in POSIX. - invalid-seek, - /// Text file busy, similar to `ETXTBSY` in POSIX. - text-file-busy, - /// Cross-device link, similar to `EXDEV` in POSIX. - cross-device, - /// A catch-all for errors not captured by the existing variants. - /// Implementations can use this to extend the error type without - /// breaking existing code. - other(option), - } - - /// File or memory access pattern advisory information. - @since(version = 0.3.0-rc-2026-03-15) - enum advice { - /// The application has no advice to give on its behavior with respect - /// to the specified data. - normal, - /// The application expects to access the specified data sequentially - /// from lower offsets to higher offsets. - sequential, - /// The application expects to access the specified data in a random - /// order. - random, - /// The application expects to access the specified data in the near - /// future. - will-need, - /// The application expects that it will not access the specified data - /// in the near future. - dont-need, - /// The application expects to access the specified data once and then - /// not reuse it thereafter. - no-reuse, - } - - /// A 128-bit hash value, split into parts because wasm doesn't have a - /// 128-bit integer type. - @since(version = 0.3.0-rc-2026-03-15) - record metadata-hash-value { - /// 64 bits of a 128-bit hash value. - lower: u64, - /// Another 64 bits of a 128-bit hash value. - upper: u64, - } - - /// A descriptor is a reference to a filesystem object, which may be a file, - /// directory, named pipe, special file, or other object on which filesystem - /// calls may be made. - @since(version = 0.3.0-rc-2026-03-15) - resource descriptor { - /// Return a stream for reading from a file. - /// - /// Multiple read, write, and append streams may be active on the same open - /// file and they do not interfere with each other. - /// - /// This function returns a `stream` which provides the data received from the - /// file, and a `future` providing additional error information in case an - /// error is encountered. - /// - /// If no error is encountered, `stream.read` on the `stream` will return - /// `read-status::closed` with no `error-context` and the future resolves to - /// the value `ok`. If an error is encountered, `stream.read` on the - /// `stream` returns `read-status::closed` with an `error-context` and the future - /// resolves to `err` with an `error-code`. - /// - /// Note: This is similar to `pread` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - read-via-stream: func( - /// The offset within the file at which to start reading. - offset: filesize, - ) -> tuple, future>>; - - /// Return a stream for writing to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be written. - /// - /// It is valid to write past the end of a file; the file is extended to the - /// extent of the write, with bytes between the previous end and the start of - /// the write set to zero. - /// - /// This function returns once either full contents of the stream are - /// written or an error is encountered. - /// - /// Note: This is similar to `pwrite` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - write-via-stream: func( - /// Data to write - data: stream, - /// The offset within the file at which to start writing. - offset: filesize, - ) -> future>; - - /// Return a stream for appending to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be appended. - /// - /// This function returns once either full contents of the stream are - /// written or an error is encountered. - /// - /// Note: This is similar to `write` with `O_APPEND` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - append-via-stream: func(data: stream) -> future>; - - /// Provide file advisory information on a descriptor. - /// - /// This is similar to `posix_fadvise` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - advise: async func( - /// The offset within the file to which the advisory applies. - offset: filesize, - /// The length of the region to which the advisory applies. - length: filesize, - /// The advice. - advice: advice - ) -> result<_, error-code>; - - /// Synchronize the data of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fdatasync` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - sync-data: async func() -> result<_, error-code>; - - /// Get flags associated with a descriptor. - /// - /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - /// - /// Note: This returns the value that was the `fs_flags` value returned - /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - get-flags: async func() -> result; - - /// Get the dynamic type of a descriptor. - /// - /// Note: This returns the same value as the `type` field of the `fd-stat` - /// returned by `stat`, `stat-at` and similar. - /// - /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided - /// by `fstat` in POSIX. - /// - /// Note: This returns the value that was the `fs_filetype` value returned - /// from `fdstat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - get-type: async func() -> result; - - /// Adjust the size of an open file. If this increases the file's size, the - /// extra bytes are filled with zeros. - /// - /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - set-size: async func(size: filesize) -> result<_, error-code>; - - /// Adjust the timestamps of an open file or directory. - /// - /// Note: This is similar to `futimens` in POSIX. - /// - /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - set-times: async func( - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code>; - - /// Read directory entries from a directory. - /// - /// On filesystems where directories contain entries referring to themselves - /// and their parents, often named `.` and `..` respectively, these entries - /// are omitted. - /// - /// This always returns a new stream which starts at the beginning of the - /// directory. Multiple streams may be active on the same directory, and they - /// do not interfere with each other. - /// - /// This function returns a future, which will resolve to an error code if - /// reading full contents of the directory fails. - @since(version = 0.3.0-rc-2026-03-15) - read-directory: func() -> tuple, future>>; - - /// Synchronize the data and metadata of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fsync` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - sync: async func() -> result<_, error-code>; - - /// Create a directory. - /// - /// Note: This is similar to `mkdirat` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - create-directory-at: async func( - /// The relative path at which to create the directory. - path: string, - ) -> result<_, error-code>; - - /// Return the attributes of an open file or directory. - /// - /// Note: This is similar to `fstat` in POSIX, except that it does not return - /// device and inode information. For testing whether two descriptors refer to - /// the same underlying filesystem object, use `is-same-object`. To obtain - /// additional data that can be used do determine whether a file has been - /// modified, use `metadata-hash`. - /// - /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - stat: async func() -> result; - - /// Return the attributes of a file or directory. - /// - /// Note: This is similar to `fstatat` in POSIX, except that it does not - /// return device and inode information. See the `stat` description for a - /// discussion of alternatives. - /// - /// Note: This was called `path_filestat_get` in earlier versions of WASI. - @since(version = 0.3.0-rc-2026-03-15) - stat-at: async func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result; - - /// Adjust the timestamps of a file or directory. - /// - /// Note: This is similar to `utimensat` in POSIX. - /// - /// Note: This was called `path_filestat_set_times` in earlier versions of - /// WASI. - @since(version = 0.3.0-rc-2026-03-15) - set-times-at: async func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to operate on. - path: string, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code>; - - /// Create a hard link. - /// - /// Fails with `error-code::no-entry` if the old path does not exist, - /// with `error-code::exist` if the new path already exists, and - /// `error-code::not-permitted` if the old path is not a file. - /// - /// Note: This is similar to `linkat` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - link-at: async func( - /// Flags determining the method of how the path is resolved. - old-path-flags: path-flags, - /// The relative source path from which to link. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: borrow, - /// The relative destination path at which to create the hard link. - new-path: string, - ) -> result<_, error-code>; - - /// Open a file or directory. - /// - /// If `flags` contains `descriptor-flags::mutate-directory`, and the base - /// descriptor doesn't have `descriptor-flags::mutate-directory` set, - /// `open-at` fails with `error-code::read-only`. - /// - /// If `flags` contains `write` or `mutate-directory`, or `open-flags` - /// contains `truncate` or `create`, and the base descriptor doesn't have - /// `descriptor-flags::mutate-directory` set, `open-at` fails with - /// `error-code::read-only`. - /// - /// Note: This is similar to `openat` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - open-at: async func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the object to open. - path: string, - /// The method by which to open the file. - open-flags: open-flags, - /// Flags to use for the resulting descriptor. - %flags: descriptor-flags, - ) -> result; - - /// Read the contents of a symbolic link. - /// - /// If the contents contain an absolute or rooted path in the underlying - /// filesystem, this function fails with `error-code::not-permitted`. - /// - /// Note: This is similar to `readlinkat` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - readlink-at: async func( - /// The relative path of the symbolic link from which to read. - path: string, - ) -> result; - - /// Remove a directory. - /// - /// Return `error-code::not-empty` if the directory is not empty. - /// - /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - remove-directory-at: async func( - /// The relative path to a directory to remove. - path: string, - ) -> result<_, error-code>; - - /// Rename a filesystem object. - /// - /// Note: This is similar to `renameat` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - rename-at: async func( - /// The relative source path of the file or directory to rename. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: borrow, - /// The relative destination path to which to rename the file or directory. - new-path: string, - ) -> result<_, error-code>; - - /// Create a symbolic link (also known as a "symlink"). - /// - /// If `old-path` starts with `/`, the function fails with - /// `error-code::not-permitted`. - /// - /// Note: This is similar to `symlinkat` in POSIX. - @since(version = 0.3.0-rc-2026-03-15) - symlink-at: async func( - /// The contents of the symbolic link. - old-path: string, - /// The relative destination path at which to create the symbolic link. - new-path: string, - ) -> result<_, error-code>; - - /// Unlink a filesystem object that is not a directory. - /// - /// This is similar to `unlinkat(fd, path, 0)` in POSIX. - /// - /// Error returns are as specified by POSIX. - /// - /// If the filesystem object is a directory, `error-code::access` or - /// `error-code::is-directory` may be returned instead of the - /// POSIX-specified `error-code::not-permitted`. - @since(version = 0.3.0-rc-2026-03-15) - unlink-file-at: async func( - /// The relative path to a file to unlink. - path: string, - ) -> result<_, error-code>; - - /// Test whether two descriptors refer to the same filesystem object. - /// - /// In POSIX, this corresponds to testing whether the two descriptors have the - /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. - /// wasi-filesystem does not expose device and inode numbers, so this function - /// may be used instead. - @since(version = 0.3.0-rc-2026-03-15) - is-same-object: async func(other: borrow) -> bool; - - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a descriptor. - /// - /// This returns a hash of the last-modification timestamp and file size, and - /// may also include the inode number, device number, birth timestamp, and - /// other metadata fields that may change when the file is modified or - /// replaced. It may also include a secret value chosen by the - /// implementation and not otherwise exposed. - /// - /// Implementations are encouraged to provide the following properties: - /// - /// - If the file is not modified or replaced, the computed hash value should - /// usually not change. - /// - If the object is modified or replaced, the computed hash value should - /// usually change. - /// - The inputs to the hash should not be easily computable from the - /// computed hash. - /// - /// However, none of these is required. - @since(version = 0.3.0-rc-2026-03-15) - metadata-hash: async func() -> result; - - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a directory descriptor and a relative path. - /// - /// This performs the same hash computation as `metadata-hash`. - @since(version = 0.3.0-rc-2026-03-15) - metadata-hash-at: async func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result; - } -} diff --git a/proposals/filesystem/wit-0.3.0-draft/world.wit b/proposals/filesystem/wit-0.3.0-draft/world.wit deleted file mode 100644 index b4fef32ce..000000000 --- a/proposals/filesystem/wit-0.3.0-draft/world.wit +++ /dev/null @@ -1,9 +0,0 @@ -package wasi:filesystem@0.3.0-rc-2026-03-15; - -@since(version = 0.3.0-rc-2026-03-15) -world imports { - @since(version = 0.3.0-rc-2026-03-15) - import types; - @since(version = 0.3.0-rc-2026-03-15) - import preopens; -} diff --git a/proposals/http/wit-0.3.0-draft/deps.lock b/proposals/http/wit-0.3.0-draft/deps.lock deleted file mode 100644 index 6c3947e6d..000000000 --- a/proposals/http/wit-0.3.0-draft/deps.lock +++ /dev/null @@ -1,22 +0,0 @@ -[cli] -path = "../../cli/wit-0.3.0-draft" -sha256 = "5be8d35b6397517777497279f1978c71aea0d91c7d63d4f4e0b54d0c1d33efd3" -sha512 = "faf89924d5d5210d3b4df52d634deb8507c44c632bc0fd1a6fa4351a15ac36e92a039daf945c59c862ea002a748ac213b27c51affa68a90dbe529551f3d63a9b" -deps = ["filesystem", "random", "sockets"] - -[clocks] -path = "../../clocks/wit-0.3.0-draft" -sha256 = "a8702c42e23c22a458207d0efa38cc1b64c8c6299b0e3152aa84327a7c1c952b" -sha512 = "da69a5d498b6afe0facf77ec3d21f6e8a2a4d4661ebfec310a2ce6f943cb01f92131a746765648febf96563ddac788e9f218941d3db2b905f3746dc8e05cf54d" - -[filesystem] -sha256 = "d9db43c43b4e09899a9e54c76544eef17439fb42e2f730ed96d40eac994b0dfd" -sha512 = "3b7a1bef322ba36b1e9df768d740e4238f58d3c15d3e4c51fe899b93cf1e6641a79b5a8665ae71d38a80e1e0f852b30b023ecf318f4cbeacb36dd1ae0ac7e37b" - -[random] -sha256 = "d44de4e427505fdfd584a23479dba5899ad80aa8e174dc0528df840db8ae9a43" -sha512 = "6b08b32a197aee74076d0cdca6a09f78da9040eedd9ab3f64e5f14901ad5a0c5bbc592ad46a0d575dc6705249b3e10a413e09835616f753788aa598af605c776" - -[sockets] -sha256 = "ee64b45d3826b6ff2cd27f6ac24fe23c41e65ba4d155294671dc7d0a0b47ddfe" -sha512 = "dd797ab47b899aee52799f797497fa286f5e217307e8a451a7ba89bd05b7b9bfe2a6e0cf39c0e609ed4c76ed102487adff6e73156340f14baf70a9cc9e48ecbc" diff --git a/proposals/http/wit-0.3.0-draft/deps.toml b/proposals/http/wit-0.3.0-draft/deps.toml deleted file mode 100644 index 46265d48e..000000000 --- a/proposals/http/wit-0.3.0-draft/deps.toml +++ /dev/null @@ -1,2 +0,0 @@ -cli = "../../cli/wit-0.3.0-draft" -clocks = "../../clocks/wit-0.3.0-draft" diff --git a/proposals/http/wit-0.3.0-draft/types.wit b/proposals/http/wit-0.3.0-draft/types.wit deleted file mode 100644 index f6d9dd99b..000000000 --- a/proposals/http/wit-0.3.0-draft/types.wit +++ /dev/null @@ -1,472 +0,0 @@ -package wasi:http@0.3.0-rc-2026-03-15; - -/// This interface defines all of the types and methods for implementing HTTP -/// Requests and Responses, as well as their headers, trailers, and bodies. -@since(version = 0.3.0-rc-2026-03-15) -interface types { - use wasi:clocks/types@0.3.0-rc-2026-03-15.{duration}; - - /// This type corresponds to HTTP standard Methods. - @since(version = 0.3.0-rc-2026-03-15) - variant method { - get, - head, - post, - put, - delete, - connect, - options, - trace, - patch, - other(string) - } - - /// This type corresponds to HTTP standard Related Schemes. - @since(version = 0.3.0-rc-2026-03-15) - variant scheme { - HTTP, - HTTPS, - other(string) - } - - /// These cases are inspired by the IANA HTTP Proxy Error Types: - /// - @since(version = 0.3.0-rc-2026-03-15) - variant error-code { - DNS-timeout, - DNS-error(DNS-error-payload), - destination-not-found, - destination-unavailable, - destination-IP-prohibited, - destination-IP-unroutable, - connection-refused, - connection-terminated, - connection-timeout, - connection-read-timeout, - connection-write-timeout, - connection-limit-reached, - TLS-protocol-error, - TLS-certificate-error, - TLS-alert-received(TLS-alert-received-payload), - HTTP-request-denied, - HTTP-request-length-required, - HTTP-request-body-size(option), - HTTP-request-method-invalid, - HTTP-request-URI-invalid, - HTTP-request-URI-too-long, - HTTP-request-header-section-size(option), - HTTP-request-header-size(option), - HTTP-request-trailer-section-size(option), - HTTP-request-trailer-size(field-size-payload), - HTTP-response-incomplete, - HTTP-response-header-section-size(option), - HTTP-response-header-size(field-size-payload), - HTTP-response-body-size(option), - HTTP-response-trailer-section-size(option), - HTTP-response-trailer-size(field-size-payload), - HTTP-response-transfer-coding(option), - HTTP-response-content-coding(option), - HTTP-response-timeout, - HTTP-upgrade-failed, - HTTP-protocol-error, - loop-detected, - configuration-error, - /// This is a catch-all error for anything that doesn't fit cleanly into a - /// more specific case. It also includes an optional string for an - /// unstructured description of the error. Users should not depend on the - /// string for diagnosing errors, as it's not required to be consistent - /// between implementations. - internal-error(option) - } - - /// Defines the case payload type for `DNS-error` above: - @since(version = 0.3.0-rc-2026-03-15) - record DNS-error-payload { - rcode: option, - info-code: option - } - - /// Defines the case payload type for `TLS-alert-received` above: - @since(version = 0.3.0-rc-2026-03-15) - record TLS-alert-received-payload { - alert-id: option, - alert-message: option - } - - /// Defines the case payload type for `HTTP-response-{header,trailer}-size` above: - @since(version = 0.3.0-rc-2026-03-15) - record field-size-payload { - field-name: option, - field-size: option - } - - /// This type enumerates the different kinds of errors that may occur when - /// setting or appending to a `fields` resource. - @since(version = 0.3.0-rc-2026-03-15) - variant header-error { - /// This error indicates that a `field-name` or `field-value` was - /// syntactically invalid when used with an operation that sets headers in a - /// `fields`. - invalid-syntax, - - /// This error indicates that a forbidden `field-name` was used when trying - /// to set a header in a `fields`. - forbidden, - - /// This error indicates that the operation on the `fields` was not - /// permitted because the fields are immutable. - immutable, - - /// This error indicates that the operation would exceed an - /// implementation-defined limit on field sizes. This may apply to - /// an individual `field-value`, a single `field-name` plus all its - /// values, or the total aggregate size of all fields. - size-exceeded, - - /// This is a catch-all error for anything that doesn't fit cleanly into a - /// more specific case. Implementations can use this to extend the error - /// type without breaking existing code. It also includes an optional - /// string for an unstructured description of the error. Users should not - /// depend on the string for diagnosing errors, as it's not required to be - /// consistent between implementations. - other(option), - } - - /// This type enumerates the different kinds of errors that may occur when - /// setting fields of a `request-options` resource. - @since(version = 0.3.0-rc-2026-03-15) - variant request-options-error { - /// Indicates the specified field is not supported by this implementation. - not-supported, - - /// Indicates that the operation on the `request-options` was not permitted - /// because it is immutable. - immutable, - - /// This is a catch-all error for anything that doesn't fit cleanly into a - /// more specific case. Implementations can use this to extend the error - /// type without breaking existing code. It also includes an optional - /// string for an unstructured description of the error. Users should not - /// depend on the string for diagnosing errors, as it's not required to be - /// consistent between implementations. - other(option), - } - - /// Field names are always strings. - /// - /// Field names should always be treated as case insensitive by the `fields` - /// resource for the purposes of equality checking. - @since(version = 0.3.0-rc-2026-03-15) - type field-name = string; - - /// Field values should always be ASCII strings. However, in - /// reality, HTTP implementations often have to interpret malformed values, - /// so they are provided as a list of bytes. - @since(version = 0.3.0-rc-2026-03-15) - type field-value = list; - - /// This following block defines the `fields` resource which corresponds to - /// HTTP standard Fields. Fields are a common representation used for both - /// Headers and Trailers. - /// - /// A `fields` may be mutable or immutable. A `fields` created using the - /// constructor, `from-list`, or `clone` will be mutable, but a `fields` - /// resource given by other means (including, but not limited to, - /// `request.headers`) might be be immutable. In an immutable fields, the - /// `set`, `append`, and `delete` operations will fail with - /// `header-error.immutable`. - /// - /// A `fields` resource should store `field-name`s and `field-value`s in their - /// original casing used to construct or mutate the `fields` resource. The `fields` - /// resource should use that original casing when serializing the fields for - /// transport or when returning them from a method. - /// - /// Implementations may impose limits on individual field values and on total - /// aggregate field section size. Operations that would exceed these limits - /// fail with `header-error.size-exceeded` - @since(version = 0.3.0-rc-2026-03-15) - resource fields { - - /// Construct an empty HTTP Fields. - /// - /// The resulting `fields` is mutable. - constructor(); - - /// Construct an HTTP Fields. - /// - /// The resulting `fields` is mutable. - /// - /// The list represents each name-value pair in the Fields. Names - /// which have multiple values are represented by multiple entries in this - /// list with the same name. - /// - /// The tuple is a pair of the field name, represented as a string, and - /// Value, represented as a list of bytes. In a valid Fields, all names - /// and values are valid UTF-8 strings. However, values are not always - /// well-formed, so they are represented as a raw list of bytes. - /// - /// An error result will be returned if any header or value was - /// syntactically invalid, if a header was forbidden, or if the - /// entries would exceed an implementation size limit. - from-list: static func( - entries: list> - ) -> result; - - /// Get all of the values corresponding to a name. If the name is not present - /// in this `fields`, an empty list is returned. However, if the name is - /// present but empty, this is represented by a list with one or more - /// empty field-values present. - get: func(name: field-name) -> list; - - /// Returns `true` when the name is present in this `fields`. If the name is - /// syntactically invalid, `false` is returned. - has: func(name: field-name) -> bool; - - /// Set all of the values for a name. Clears any existing values for that - /// name, if they have been set. - /// - /// Fails with `header-error.immutable` if the `fields` are immutable. - /// - /// Fails with `header-error.size-exceeded` if the name or values would - /// exceed an implementation-defined size limit. - set: func(name: field-name, value: list) -> result<_, header-error>; - - /// Delete all values for a name. Does nothing if no values for the name - /// exist. - /// - /// Fails with `header-error.immutable` if the `fields` are immutable. - delete: func(name: field-name) -> result<_, header-error>; - - /// Delete all values for a name. Does nothing if no values for the name - /// exist. - /// - /// Returns all values previously corresponding to the name, if any. - /// - /// Fails with `header-error.immutable` if the `fields` are immutable. - get-and-delete: func(name: field-name) -> result, header-error>; - - /// Append a value for a name. Does not change or delete any existing - /// values for that name. - /// - /// Fails with `header-error.immutable` if the `fields` are immutable. - /// - /// Fails with `header-error.size-exceeded` if the value would exceed - /// an implementation-defined size limit. - append: func(name: field-name, value: field-value) -> result<_, header-error>; - - /// Retrieve the full set of names and values in the Fields. Like the - /// constructor, the list represents each name-value pair. - /// - /// The outer list represents each name-value pair in the Fields. Names - /// which have multiple values are represented by multiple entries in this - /// list with the same name. - /// - /// The names and values are always returned in the original casing and in - /// the order in which they will be serialized for transport. - copy-all: func() -> list>; - - /// Make a deep copy of the Fields. Equivalent in behavior to calling the - /// `fields` constructor on the return value of `copy-all`. The resulting - /// `fields` is mutable. - clone: func() -> fields; - } - - /// Headers is an alias for Fields. - @since(version = 0.3.0-rc-2026-03-15) - type headers = fields; - - /// Trailers is an alias for Fields. - @since(version = 0.3.0-rc-2026-03-15) - type trailers = fields; - - /// Represents an HTTP Request. - @since(version = 0.3.0-rc-2026-03-15) - resource request { - - /// Construct a new `request` with a default `method` of `GET`, and - /// `none` values for `path-with-query`, `scheme`, and `authority`. - /// - /// `headers` is the HTTP Headers for the Request. - /// - /// `contents` is the optional body content stream with `none` - /// representing a zero-length content stream. - /// Once it is closed, `trailers` future must resolve to a result. - /// If `trailers` resolves to an error, underlying connection - /// will be closed immediately. - /// - /// `options` is optional `request-options` resource to be used - /// if the request is sent over a network connection. - /// - /// It is possible to construct, or manipulate with the accessor functions - /// below, a `request` with an invalid combination of `scheme` - /// and `authority`, or `headers` which are not permitted to be sent. - /// It is the obligation of the `handler.handle` implementation - /// to reject invalid constructions of `request`. - /// - /// The returned future resolves to result of transmission of this request. - new: static func( - headers: headers, - contents: option>, - trailers: future, error-code>>, - options: option - ) -> tuple>>; - - /// Get the Method for the Request. - get-method: func() -> method; - /// Set the Method for the Request. Fails if the string present in a - /// `method.other` argument is not a syntactically valid method. - set-method: func(method: method) -> result; - - /// Get the combination of the HTTP Path and Query for the Request. When - /// `none`, this represents an empty Path and empty Query. - get-path-with-query: func() -> option; - /// Set the combination of the HTTP Path and Query for the Request. When - /// `none`, this represents an empty Path and empty Query. Fails is the - /// string given is not a syntactically valid path and query uri component. - set-path-with-query: func(path-with-query: option) -> result; - - /// Get the HTTP Related Scheme for the Request. When `none`, the - /// implementation may choose an appropriate default scheme. - get-scheme: func() -> option; - /// Set the HTTP Related Scheme for the Request. When `none`, the - /// implementation may choose an appropriate default scheme. Fails if the - /// string given is not a syntactically valid uri scheme. - set-scheme: func(scheme: option) -> result; - - /// Get the authority of the Request's target URI. A value of `none` may be used - /// with Related Schemes which do not require an authority. The HTTP and - /// HTTPS schemes always require an authority. - get-authority: func() -> option; - /// Set the authority of the Request's target URI. A value of `none` may be used - /// with Related Schemes which do not require an authority. The HTTP and - /// HTTPS schemes always require an authority. Fails if the string given is - /// not a syntactically valid URI authority. - set-authority: func(authority: option) -> result; - - /// Get the `request-options` to be associated with this request - /// - /// The returned `request-options` resource is immutable: `set-*` operations - /// will fail if invoked. - /// - /// This `request-options` resource is a child: it must be dropped before - /// the parent `request` is dropped, or its ownership is transferred to - /// another component by e.g. `handler.handle`. - get-options: func() -> option; - - /// Get the headers associated with the Request. - /// - /// The returned `headers` resource is immutable: `set`, `append`, and - /// `delete` operations will fail with `header-error.immutable`. - get-headers: func() -> headers; - - /// Get body of the Request. - /// - /// Stream returned by this method represents the contents of the body. - /// Once the stream is reported as closed, callers should await the returned - /// future to determine whether the body was received successfully. - /// The future will only resolve after the stream is reported as closed. - /// - /// This function takes a `res` future as a parameter, which can be used to - /// communicate an error in handling of the request. - /// - /// Note that function will move the `request`, but references to headers or - /// request options acquired from it previously will remain valid. - consume-body: static func(this: request, res: future>) -> tuple, future, error-code>>>; - } - - /// Parameters for making an HTTP Request. Each of these parameters is - /// currently an optional timeout applicable to the transport layer of the - /// HTTP protocol. - /// - /// These timeouts are separate from any the user may use to bound an - /// asynchronous call. - @since(version = 0.3.0-rc-2026-03-15) - resource request-options { - /// Construct a default `request-options` value. - constructor(); - - /// The timeout for the initial connect to the HTTP Server. - get-connect-timeout: func() -> option; - - /// Set the timeout for the initial connect to the HTTP Server. An error - /// return value indicates that this timeout is not supported or that this - /// handle is immutable. - set-connect-timeout: func(duration: option) -> result<_, request-options-error>; - - /// The timeout for receiving the first byte of the Response body. - get-first-byte-timeout: func() -> option; - - /// Set the timeout for receiving the first byte of the Response body. An - /// error return value indicates that this timeout is not supported or that - /// this handle is immutable. - set-first-byte-timeout: func(duration: option) -> result<_, request-options-error>; - - /// The timeout for receiving subsequent chunks of bytes in the Response - /// body stream. - get-between-bytes-timeout: func() -> option; - - /// Set the timeout for receiving subsequent chunks of bytes in the Response - /// body stream. An error return value indicates that this timeout is not - /// supported or that this handle is immutable. - set-between-bytes-timeout: func(duration: option) -> result<_, request-options-error>; - - /// Make a deep copy of the `request-options`. - /// The resulting `request-options` is mutable. - clone: func() -> request-options; - } - - /// This type corresponds to the HTTP standard Status Code. - @since(version = 0.3.0-rc-2026-03-15) - type status-code = u16; - - /// Represents an HTTP Response. - @since(version = 0.3.0-rc-2026-03-15) - resource response { - - /// Construct a new `response`, with a default `status-code` of `200`. - /// If a different `status-code` is needed, it must be set via the - /// `set-status-code` method. - /// - /// `headers` is the HTTP Headers for the Response. - /// - /// `contents` is the optional body content stream with `none` - /// representing a zero-length content stream. - /// Once it is closed, `trailers` future must resolve to a result. - /// If `trailers` resolves to an error, underlying connection - /// will be closed immediately. - /// - /// The returned future resolves to result of transmission of this response. - new: static func( - headers: headers, - contents: option>, - trailers: future, error-code>>, - ) -> tuple>>; - - /// Get the HTTP Status Code for the Response. - get-status-code: func() -> status-code; - - /// Set the HTTP Status Code for the Response. Fails if the status-code - /// given is not a valid http status code. - set-status-code: func(status-code: status-code) -> result; - - /// Get the headers associated with the Response. - /// - /// The returned `headers` resource is immutable: `set`, `append`, and - /// `delete` operations will fail with `header-error.immutable`. - get-headers: func() -> headers; - - /// Get body of the Response. - /// - /// Stream returned by this method represents the contents of the body. - /// Once the stream is reported as closed, callers should await the returned - /// future to determine whether the body was received successfully. - /// The future will only resolve after the stream is reported as closed. - /// - /// This function takes a `res` future as a parameter, which can be used to - /// communicate an error in handling of the response. - /// - /// Note that function will move the `response`, but references to headers - /// acquired from it previously will remain valid. - consume-body: static func(this: response, res: future>) -> tuple, future, error-code>>>; - } -} diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit deleted file mode 100644 index 9917e0545..000000000 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ /dev/null @@ -1,86 +0,0 @@ -package wasi:http@0.3.0-rc-2026-03-15; - -/// The `wasi:http/service` world captures a broad category of HTTP services -/// including web applications, API servers, and proxies. It may be `include`d -/// in more specific worlds such as `wasi:http/middleware`. -@since(version = 0.3.0-rc-2026-03-15) -world service { - /// HTTP services have access to time and randomness. - include wasi:clocks/imports@0.3.0-rc-2026-03-15; - include wasi:random/imports@0.3.0-rc-2026-03-15; - - /// Services have standard output and error streams which are expected to - /// terminate in a developer-facing console provided by the host. - import wasi:cli/stdout@0.3.0-rc-2026-03-15; - import wasi:cli/stderr@0.3.0-rc-2026-03-15; - - /// TODO: this is a temporary workaround until component tooling is able to - /// gracefully handle the absence of stdin. Hosts must return an eof stream - /// for this import, which is what wasi-libc + tooling will do automatically - /// when this import is properly removed. - import wasi:cli/stdin@0.3.0-rc-2026-03-15; - - /// This is the default `client` to use when user code simply wants to make an - /// HTTP request (e.g., via `fetch()`). - import client; - - /// The host delivers incoming HTTP requests to a component by calling the - /// `handle` function of this exported interface. A host may arbitrarily reuse - /// or not reuse component instance when delivering incoming HTTP requests and - /// thus a component must be able to handle 0..N calls to `handle`. - /// - /// This may also be used to receive synthesized or forwarded requests from - /// another component. - export handler; -} - -/// The `wasi:http/middleware` world captures HTTP services that forward HTTP -/// Requests to another handler. -/// -/// Components may implement this world to allow them to participate in handler -/// "chains" where a `request` flows through handlers on its way to some terminal -/// `service` and corresponding `response` flows in the opposite direction. -@since(version = 0.3.0-rc-2026-03-15) -world middleware { - include service; - import handler; -} - -/// This interface defines a handler of HTTP Requests. -/// -/// In a `wasi:http/service` this interface is exported to respond to an -/// incoming HTTP Request with a Response. -/// -/// In `wasi:http/middleware` this interface is both exported and imported as -/// the "downstream" and "upstream" directions of the middleware chain. -@since(version = 0.3.0-rc-2026-03-15) -interface handler { - use types.{request, response, error-code}; - - /// This function may be called with either an incoming request read from the - /// network or a request synthesized or forwarded by another component. - handle: async func( - request: request, - ) -> result; -} - -/// This interface defines an HTTP client for sending "outgoing" requests. -/// -/// Most components are expected to import this interface to provide the -/// capability to send HTTP requests to arbitrary destinations on a network. -/// -/// The type signature of `client.send` is the same as `handler.handle`. This -/// duplication is currently necessary because some Component Model tooling -/// (including WIT itself) is unable to represent a component importing two -/// instances of the same interface. A `client.send` import may be linked -/// directly to a `handler.handle` export to bypass the network. -@since(version = 0.3.0-rc-2026-03-15) -interface client { - use types.{request, response, error-code}; - - // This function may be used to either send an outgoing request over the - // network or to forward it to another component. - send: async func( - request: request, - ) -> result; -} diff --git a/proposals/random/wit-0.3.0-draft/insecure-seed.wit b/proposals/random/wit-0.3.0-draft/insecure-seed.wit deleted file mode 100644 index dc9100f78..000000000 --- a/proposals/random/wit-0.3.0-draft/insecure-seed.wit +++ /dev/null @@ -1,27 +0,0 @@ -package wasi:random@0.3.0-rc-2026-03-15; -/// The insecure-seed interface for seeding hash-map DoS resistance. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -@since(version = 0.3.0-rc-2026-03-15) -interface insecure-seed { - /// Return a 128-bit value that may contain a pseudo-random value. - /// - /// The returned value is not required to be computed from a CSPRNG, and may - /// even be entirely deterministic. Host implementations are encouraged to - /// provide pseudo-random values to any program exposed to - /// attacker-controlled content, to enable DoS protection built into many - /// languages' hash-map implementations. - /// - /// This function is intended to only be called once, by a source language - /// to initialize Denial Of Service (DoS) protection in its hash-map - /// implementation. - /// - /// # Expected future evolution - /// - /// This will likely be changed to a value import, to prevent it from being - /// called multiple times and potentially used for purposes other than DoS - /// protection. - @since(version = 0.3.0-rc-2026-03-15) - get-insecure-seed: func() -> tuple; -} diff --git a/proposals/random/wit-0.3.0-draft/insecure.wit b/proposals/random/wit-0.3.0-draft/insecure.wit deleted file mode 100644 index ee3fef733..000000000 --- a/proposals/random/wit-0.3.0-draft/insecure.wit +++ /dev/null @@ -1,32 +0,0 @@ -package wasi:random@0.3.0-rc-2026-03-15; -/// The insecure interface for insecure pseudo-random numbers. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -@since(version = 0.3.0-rc-2026-03-15) -interface insecure { - /// Return up to `max-len` insecure pseudo-random bytes. - /// - /// This function is not cryptographically secure. Do not use it for - /// anything related to security. - /// - /// There are no requirements on the values of the returned bytes, however - /// implementations are encouraged to return evenly distributed values with - /// a long period. - /// - /// Implementations MAY return fewer bytes than requested (a short read). - /// Callers that require exactly `max-len` bytes MUST call this function in - /// a loop until the desired number of bytes has been accumulated. - /// Implementations MUST return at least 1 byte when `max-len` is greater - /// than zero. When `max-len` is zero, implementations MUST return an empty - /// list without trapping. - @since(version = 0.3.0-rc-2026-03-15) - get-insecure-random-bytes: func(max-len: u64) -> list; - - /// Return an insecure pseudo-random `u64` value. - /// - /// This function returns the same type of pseudo-random data as - /// `get-insecure-random-bytes`, represented as a `u64`. - @since(version = 0.3.0-rc-2026-03-15) - get-insecure-random-u64: func() -> u64; -} diff --git a/proposals/random/wit-0.3.0-draft/random.wit b/proposals/random/wit-0.3.0-draft/random.wit deleted file mode 100644 index e40b97d7c..000000000 --- a/proposals/random/wit-0.3.0-draft/random.wit +++ /dev/null @@ -1,37 +0,0 @@ -package wasi:random@0.3.0-rc-2026-03-15; -/// WASI Random is a random data API. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -@since(version = 0.3.0-rc-2026-03-15) -interface random { - /// Return up to `max-len` cryptographically-secure random or pseudo-random - /// bytes. - /// - /// This function must produce data at least as cryptographically secure and - /// fast as an adequately seeded cryptographically-secure pseudo-random - /// number generator (CSPRNG). It must not block, from the perspective of - /// the calling program, under any circumstances, including on the first - /// request and on requests for numbers of bytes. The returned data must - /// always be unpredictable. - /// - /// Implementations MAY return fewer bytes than requested (a short read). - /// Callers that require exactly `max-len` bytes MUST call this function in - /// a loop until the desired number of bytes has been accumulated. - /// Implementations MUST return at least 1 byte when `max-len` is greater - /// than zero. When `max-len` is zero, implementations MUST return an empty - /// list without trapping. - /// - /// This function must always return fresh data. Deterministic environments - /// must omit this function, rather than implementing it with deterministic - /// data. - @since(version = 0.3.0-rc-2026-03-15) - get-random-bytes: func(max-len: u64) -> list; - - /// Return a cryptographically-secure random or pseudo-random `u64` value. - /// - /// This function returns the same type of data as `get-random-bytes`, - /// represented as a `u64`. - @since(version = 0.3.0-rc-2026-03-15) - get-random-u64: func() -> u64; -} diff --git a/proposals/random/wit-0.3.0-draft/world.wit b/proposals/random/wit-0.3.0-draft/world.wit deleted file mode 100644 index 590691347..000000000 --- a/proposals/random/wit-0.3.0-draft/world.wit +++ /dev/null @@ -1,13 +0,0 @@ -package wasi:random@0.3.0-rc-2026-03-15; - -@since(version = 0.3.0-rc-2026-03-15) -world imports { - @since(version = 0.3.0-rc-2026-03-15) - import random; - - @since(version = 0.3.0-rc-2026-03-15) - import insecure; - - @since(version = 0.3.0-rc-2026-03-15) - import insecure-seed; -} diff --git a/proposals/sockets/wit-0.3.0-draft/deps.lock b/proposals/sockets/wit-0.3.0-draft/deps.lock deleted file mode 100644 index a780d3df7..000000000 --- a/proposals/sockets/wit-0.3.0-draft/deps.lock +++ /dev/null @@ -1,4 +0,0 @@ -[clocks] -path = "../../clocks/wit-0.3.0-draft" -sha256 = "a8702c42e23c22a458207d0efa38cc1b64c8c6299b0e3152aa84327a7c1c952b" -sha512 = "da69a5d498b6afe0facf77ec3d21f6e8a2a4d4661ebfec310a2ce6f943cb01f92131a746765648febf96563ddac788e9f218941d3db2b905f3746dc8e05cf54d" diff --git a/proposals/sockets/wit-0.3.0-draft/deps.toml b/proposals/sockets/wit-0.3.0-draft/deps.toml deleted file mode 100644 index c54398c1a..000000000 --- a/proposals/sockets/wit-0.3.0-draft/deps.toml +++ /dev/null @@ -1 +0,0 @@ -clocks = "../../clocks/wit-0.3.0-draft" diff --git a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit b/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit deleted file mode 100644 index 2e9c9fe0a..000000000 --- a/proposals/sockets/wit-0.3.0-draft/ip-name-lookup.wit +++ /dev/null @@ -1,61 +0,0 @@ -@since(version = 0.3.0-rc-2026-03-15) -interface ip-name-lookup { - @since(version = 0.3.0-rc-2026-03-15) - use types.{ip-address}; - - /// Lookup error codes. - @since(version = 0.3.0-rc-2026-03-15) - variant error-code { - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - access-denied, - - /// `name` is a syntactically invalid domain name or IP address. - /// - /// POSIX equivalent: EINVAL - invalid-argument, - - /// Name does not exist or has no suitable associated IP addresses. - /// - /// POSIX equivalent: EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY - name-unresolvable, - - /// A temporary failure in name resolution occurred. - /// - /// POSIX equivalent: EAI_AGAIN - temporary-resolver-failure, - - /// A permanent failure in name resolution occurred. - /// - /// POSIX equivalent: EAI_FAIL - permanent-resolver-failure, - - /// A catch-all for errors not captured by the existing variants. - /// Implementations can use this to extend the error type without - /// breaking existing code. - other(option), - } - - /// Resolve an internet host name to a list of IP addresses. - /// - /// Unicode domain names are automatically converted to ASCII using IDNA - /// encoding. If the input is an IP address string, the address is parsed - /// and returned as-is without making any external requests. - /// - /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. - /// - /// The results are returned in connection order preference. - /// - /// This function never succeeds with 0 results. It either fails or succeeds - /// with at least one address. Additionally, this function never returns - /// IPv4-mapped IPv6 addresses. - /// - /// # References: - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - resolve-addresses: async func(name: string) -> result, error-code>; -} diff --git a/proposals/sockets/wit-0.3.0-draft/types.wit b/proposals/sockets/wit-0.3.0-draft/types.wit deleted file mode 100644 index fe2c0448b..000000000 --- a/proposals/sockets/wit-0.3.0-draft/types.wit +++ /dev/null @@ -1,812 +0,0 @@ -@since(version = 0.3.0-rc-2026-03-15) -interface types { - @since(version = 0.3.0-rc-2026-03-15) - use wasi:clocks/types@0.3.0-rc-2026-03-15.{duration}; - - /// Error codes. - /// - /// In theory, every API can return any error code. - /// In practice, API's typically only return the errors documented per API - /// combined with a couple of errors that are always possible: - /// - `other` - /// - `access-denied` - /// - `not-supported` - /// - `out-of-memory` - /// - /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - @since(version = 0.3.0-rc-2026-03-15) - variant error-code { - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - access-denied, - - /// The operation is not supported. - /// - /// POSIX equivalent: EOPNOTSUPP, ENOPROTOOPT, EPFNOSUPPORT, EPROTONOSUPPORT, ESOCKTNOSUPPORT - not-supported, - - /// One of the arguments is invalid. - /// - /// POSIX equivalent: EINVAL, EDESTADDRREQ, EAFNOSUPPORT - invalid-argument, - - /// Not enough memory to complete the operation. - /// - /// POSIX equivalent: ENOMEM, ENOBUFS - out-of-memory, - - /// The operation timed out before it could finish completely. - /// - /// POSIX equivalent: ETIMEDOUT - timeout, - - /// The operation is not valid in the socket's current state. - invalid-state, - - /// The local address is not available. - /// - /// POSIX equivalent: EADDRNOTAVAIL - address-not-bindable, - - /// A bind operation failed because the provided address is already in - /// use or because there are no ephemeral ports available. - /// - /// POSIX equivalent: EADDRINUSE - address-in-use, - - /// The remote address is not reachable. - /// - /// POSIX equivalent: EHOSTUNREACH, EHOSTDOWN, ENETDOWN, ENETUNREACH, ENONET - remote-unreachable, - - /// The connection was forcefully rejected. - /// - /// POSIX equivalent: ECONNREFUSED - connection-refused, - - /// A write failed because the connection was broken. - /// - /// POSIX equivalent: EPIPE - connection-broken, - - /// The connection was reset. - /// - /// POSIX equivalent: ECONNRESET - connection-reset, - - /// The connection was aborted. - /// - /// POSIX equivalent: ECONNABORTED - connection-aborted, - - /// The size of a datagram sent to a UDP socket exceeded the maximum - /// supported size. - /// - /// POSIX equivalent: EMSGSIZE - datagram-too-large, - - /// A catch-all for errors not captured by the existing variants. - /// Implementations can use this to extend the error type without - /// breaking existing code. - other(option), - } - - @since(version = 0.3.0-rc-2026-03-15) - enum ip-address-family { - /// Similar to `AF_INET` in POSIX. - ipv4, - - /// Similar to `AF_INET6` in POSIX. - ipv6, - } - - @since(version = 0.3.0-rc-2026-03-15) - type ipv4-address = tuple; - @since(version = 0.3.0-rc-2026-03-15) - type ipv6-address = tuple; - - @since(version = 0.3.0-rc-2026-03-15) - variant ip-address { - ipv4(ipv4-address), - ipv6(ipv6-address), - } - - @since(version = 0.3.0-rc-2026-03-15) - record ipv4-socket-address { - /// sin_port - port: u16, - /// sin_addr - address: ipv4-address, - } - - @since(version = 0.3.0-rc-2026-03-15) - record ipv6-socket-address { - /// sin6_port - port: u16, - /// sin6_flowinfo - flow-info: u32, - /// sin6_addr - address: ipv6-address, - /// sin6_scope_id - scope-id: u32, - } - - @since(version = 0.3.0-rc-2026-03-15) - variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), - } - - /// A TCP socket resource. - /// - /// The socket can be in one of the following states: - /// - `unbound` - /// - `bound` (See note below) - /// - `listening` - /// - `connecting` - /// - `connected` - /// - `closed` - /// See - /// for more information. - /// - /// Note: Except where explicitly mentioned, whenever this documentation uses - /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. - /// (i.e. `bound`, `listening`, `connecting` or `connected`) - /// - /// WASI uses shared ownership semantics: the `tcp-socket` handle and all - /// derived `stream` and `future` values reference a single underlying OS - /// socket: - /// - Send/receive streams remain functional after the original `tcp-socket` - /// handle is dropped. - /// - The stream returned by `listen` behaves similarly. - /// - Client sockets returned by `tcp-socket::listen` are independent and do - /// not keep the listening socket alive. - /// - /// The OS socket is closed only after the last handle is dropped. This - /// model has observable effects; for example, it affects when the local - /// port binding is released. - /// - /// In addition to the general error codes documented on the - /// `types::error-code` type, TCP socket methods may always return - /// `error(invalid-state)` when in the `closed` state. - @since(version = 0.3.0-rc-2026-03-15) - resource tcp-socket { - - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` - /// in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and - /// can't be configured otherwise. - /// - /// Unlike POSIX, WASI sockets have no notion of a socket-level - /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's - /// async support. - /// - /// # Typical errors - /// - `not-supported`: The `address-family` is not supported. (EAFNOSUPPORT) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - create: static func(address-family: ip-address-family) -> result; - - /// Bind the socket to the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is - /// left to the implementation to decide which network interface(s) to - /// bind to. If the TCP/UDP port is zero, the socket will be bound to a - /// random free port. - /// - /// Bind can be attempted multiple times on the same socket, even with - /// different arguments on each iteration. But never concurrently and - /// only as long as the previous bind failed. Once a bind succeeds, the - /// binding can't be changed anymore. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) - /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) - /// - /// # Implementors note - /// The bind operation shouldn't be affected by the TIME_WAIT state of a - /// recently closed socket on the same local address. In practice this - /// means that the SO_REUSEADDR socket option should be set implicitly - /// on all platforms, except on Windows where this is the default - /// behavior and SO_REUSEADDR performs something different. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - bind: func(local-address: ip-socket-address) -> result<_, error-code>; - - /// Connect to a remote endpoint. - /// - /// On success, the socket is transitioned into the `connected` state - /// and the `remote-address` of the socket is updated. - /// The `local-address` may be updated as well, based on the best network - /// path to `remote-address`. If the socket was not already explicitly - /// bound, this function will implicitly bind the socket to a random - /// free port. - /// - /// After a failed connection attempt, the socket will be in the `closed` - /// state and the only valid action left is to `drop` the socket. A single - /// socket can not be used to connect more than once. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) - /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `invalid-state`: The socket is already in the `connecting` state. (EALREADY) - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) - /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - connect: async func(remote-address: ip-socket-address) -> result<_, error-code>; - - /// Start listening and return a stream of new inbound connections. - /// - /// Transitions the socket into the `listening` state. This can be called - /// at most once per socket. - /// - /// If the socket is not already explicitly bound, this function will - /// implicitly bind the socket to a random free port. - /// - /// Normally, the returned sockets are bound, in the `connected` state - /// and immediately ready for I/O. Though, depending on exact timing and - /// circumstances, a newly accepted connection may already be `closed` - /// by the time the server attempts to perform its first I/O on it. This - /// is true regardless of whether the WASI implementation uses - /// "synthesized" sockets or not (see Implementors Notes below). - /// - /// The following properties are inherited from the listener socket: - /// - `address-family` - /// - `keep-alive-enabled` - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// - `hop-limit` - /// - `receive-buffer-size` - /// - `send-buffer-size` - /// - /// # Typical errors - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the `listening` state. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - /// # Implementors note - /// This method returns a single perpetual stream that should only close - /// on fatal errors (if any). Yet, the POSIX' `accept` function may also - /// return transient errors (e.g. ECONNABORTED). The exact details differ - /// per operation system. For example, the Linux manual mentions: - /// - /// > Linux accept() passes already-pending network errors on the new - /// > socket as an error code from accept(). This behavior differs from - /// > other BSD socket implementations. For reliable operation the - /// > application should detect the network errors defined for the - /// > protocol after accept() and treat them like EAGAIN by retrying. - /// > In the case of TCP/IP, these are ENETDOWN, EPROTO, ENOPROTOOPT, - /// > EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, and ENETUNREACH. - /// Source: https://man7.org/linux/man-pages/man2/accept.2.html - /// - /// WASI implementations have two options to handle this: - /// - Optionally log it and then skip over non-fatal errors returned by - /// `accept`. Guest code never gets to see these failures. Or: - /// - Synthesize a `tcp-socket` resource that exposes the error when - /// attempting to send or receive on it. Guest code then sees these - /// failures as regular I/O errors. - /// - /// In either case, the stream returned by this `listen` method remains - /// operational. - /// - /// WASI requires `listen` to perform an implicit bind if the socket - /// has not already been bound. Not all platforms (notably Windows) - /// exhibit this behavior out of the box. On platforms that require it, - /// the WASI implementation can emulate this behavior by performing - /// the bind itself if the guest hasn't already done so. - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - listen: func() -> result, error-code>; - - /// Transmit data to peer. - /// - /// The caller should close the stream when it has no more data to send - /// to the peer. Under normal circumstances this will cause a FIN packet - /// to be sent out. Closing the stream is equivalent to calling - /// `shutdown(SHUT_WR)` in POSIX. - /// - /// This function may be called at most once and returns once the full - /// contents of the stream are transmitted or an error is encountered. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) - /// - `invalid-state`: `send` has already been called on this socket. - /// - `connection-broken`: The connection is not writable anymore. (EPIPE, ECONNABORTED on Windows) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - send: func(data: stream) -> future>; - - /// Read data from peer. - /// - /// Returns a `stream` of data sent by the peer. The implementation - /// drops the stream once no more data is available. At that point, the - /// returned `future` resolves to: - /// - `ok` after a graceful shutdown from the peer (i.e. a FIN packet), or - /// - `err` if the socket was closed abnormally. - /// - /// `receive` may be called only once per socket. Subsequent calls return - /// a closed stream and a future resolved to `err(invalid-state)`. - /// - /// If the caller is not expecting to receive any more data from the peer, - /// they should drop the stream. Any data still in the receive queue - /// will be discarded. This is equivalent to calling `shutdown(SHUT_RD)` - /// in POSIX. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) - /// - `invalid-state`: `receive` has already been called on this socket. - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - receive: func() -> tuple, future>>; - - /// Get the bound local address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `get-local-address` to return - /// `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - get-local-address: func() -> result; - - /// Get the remote address. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - get-remote-address: func() -> result; - - /// Whether the socket is in the `listening` state. - /// - /// Equivalent to the SO_ACCEPTCONN socket option. - @since(version = 0.3.0-rc-2026-03-15) - get-is-listening: func() -> bool; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// This is the value passed to the constructor. - /// - /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2026-03-15) - get-address-family: func() -> ip-address-family; - - /// Hints the desired listen queue size. Implementations are free to - /// ignore this. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently - /// clamped and/or rounded. - /// - /// # Typical errors - /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. - /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is in the `connecting` or `connected` state. - @since(version = 0.3.0-rc-2026-03-15) - set-listen-backlog-size: func(value: u64) -> result<_, error-code>; - - /// Enables or disables keepalive. - /// - /// The keepalive behavior can be adjusted using: - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// These properties can be configured while `keep-alive-enabled` is - /// false, but only come into effect when `keep-alive-enabled` is true. - /// - /// Equivalent to the SO_KEEPALIVE socket option. - @since(version = 0.3.0-rc-2026-03-15) - get-keep-alive-enabled: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; - - /// Amount of time the connection has to be idle before TCP starts - /// sending keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// All other values are accepted without error, but may be - /// clamped or rounded. As a result, the value read back from - /// this setting may differ from the value that was set. - /// - /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2026-03-15) - get-keep-alive-idle-time: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; - - /// The time between keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// All other values are accepted without error, but may be - /// clamped or rounded. As a result, the value read back from - /// this setting may differ from the value that was set. - /// - /// Equivalent to the TCP_KEEPINTVL socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2026-03-15) - get-keep-alive-interval: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-keep-alive-interval: func(value: duration) -> result<_, error-code>; - - /// The maximum amount of keepalive packets TCP should send before - /// aborting the connection. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// All other values are accepted without error, but may be - /// clamped or rounded. As a result, the value read back from - /// this setting may differ from the value that was set. - /// - /// Equivalent to the TCP_KEEPCNT socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2026-03-15) - get-keep-alive-count: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-keep-alive-count: func(value: u32) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2026-03-15) - get-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-hop-limit: func(value: u8) -> result<_, error-code>; - - /// Kernel buffer space reserved for sending/receiving on this socket. - /// Implementations usually treat this as a cap the buffer can grow to, - /// rather than allocating the full amount immediately. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// All other values are accepted without error, but may be - /// clamped or rounded. As a result, the value read back from - /// this setting may differ from the value that was set. - /// - /// This is only a performance hint. The implementation may ignore it or - /// tweak it based on real traffic patterns. - /// Linux and macOS appear to behave differently depending on whether a - /// buffer size was explicitly set. When set, they tend to honor it; when - /// not set, they dynamically adjust the buffer size as the connection - /// progresses. This is especially noticeable when comparing the values - /// from before and after connection establishment. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2026-03-15) - get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2026-03-15) - get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - } - - /// A UDP socket handle. - @since(version = 0.3.0-rc-2026-03-15) - resource udp-socket { - - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` - /// in POSIX. On IPv6 sockets, IPV6_V6ONLY is enabled by default and - /// can't be configured otherwise. - /// - /// Unlike POSIX, WASI sockets have no notion of a socket-level - /// `O_NONBLOCK` flag. Instead they fully rely on the Component Model's - /// async support. - /// - /// # References: - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - create: static func(address-family: ip-address-family) -> result; - - /// Bind the socket to the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is - /// left to the implementation to decide which network interface(s) to - /// bind to. If the port is zero, the socket will be bound to a random - /// free port. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that can be bound to. (EADDRNOTAVAIL) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - bind: func(local-address: ip-socket-address) -> result<_, error-code>; - - /// Associate this socket with a specific peer address. - /// - /// On success, the `remote-address` of the socket is updated. - /// The `local-address` may be updated as well, based on the best network - /// path to `remote-address`. If the socket was not already explicitly - /// bound, this function will implicitly bind the socket to a random - /// free port. - /// - /// When a UDP socket is "connected", the `send` and `receive` methods - /// are limited to communicating with that peer only: - /// - `send` can only be used to send to this destination. - /// - `receive` will only return datagrams sent from the provided `remote-address`. - /// - /// The name "connect" was kept to align with the existing POSIX - /// terminology. Other than that, this function only changes the local - /// socket configuration and does not generate any network traffic. - /// The peer is not aware of this "connection". - /// - /// This method may be called multiple times on the same socket to change - /// its association, but only the most recent one will be effective. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - /// # Implementors note - /// If the socket is already connected, some platforms (e.g. Linux) - /// require a disconnect before connecting to a different peer address. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - connect: func(remote-address: ip-socket-address) -> result<_, error-code>; - - /// Dissociate this socket from its peer address. - /// - /// After calling this method, `send` & `receive` are free to communicate - /// with any remote address again. - /// - /// The POSIX equivalent of this is calling `connect` with an `AF_UNSPEC` address. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not connected. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - disconnect: func() -> result<_, error-code>; - - /// Send a message on the socket to a particular peer. - /// - /// If the socket is connected, the peer address may be left empty. In - /// that case this is equivalent to `send` in POSIX. Otherwise it is - /// equivalent to `sendto`. - /// - /// Additionally, if the socket is connected, a `remote-address` argument - /// _may_ be provided but then it must be identical to the address - /// passed to `connect`. - /// - /// If the socket has not been explicitly bound, it will be - /// implicitly bound to a random free port. - /// - /// Implementations may trap if the `data` length exceeds 64 KiB. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `connect`. (EISCONN) - /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - /// # Implementors note - /// WASI requires `send` to perform an implicit bind if the socket - /// has not been bound. Not all platforms (notably Windows) exhibit - /// this behavior natively. On such platforms, the WASI implementation - /// should emulate it by performing the bind if the guest has not - /// already done so. - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - send: async func(data: list, remote-address: option) -> result<_, error-code>; - - /// Receive a message on the socket. - /// - /// On success, the return value contains a tuple of the received data - /// and the address of the sender. Theoretical maximum length of the - /// data is 64 KiB. Though in practice, it will typically be less than - /// 1500 bytes. - /// - /// If the socket is connected, the sender address is guaranteed to - /// match the remote address passed to `connect`. - /// - /// # Typical errors - /// - `invalid-state`: The socket has not been bound yet. - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - receive: async func() -> result, ip-socket-address>, error-code>; - - /// Get the current bound address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `get-local-address` to return - /// `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - get-local-address: func() -> result; - - /// Get the address the socket is currently "connected" to. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not "connected" to a specific remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - @since(version = 0.3.0-rc-2026-03-15) - get-remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// This is the value passed to the constructor. - /// - /// Equivalent to the SO_DOMAIN socket option. - @since(version = 0.3.0-rc-2026-03-15) - get-address-family: func() -> ip-address-family; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - @since(version = 0.3.0-rc-2026-03-15) - get-unicast-hop-limit: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// Kernel buffer space reserved for sending/receiving on this socket. - /// Implementations usually treat this as a cap the buffer can grow to, - /// rather than allocating the full amount immediately. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// All other values are accepted without error, but may be - /// clamped or rounded. As a result, the value read back from - /// this setting may differ from the value that was set. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - @since(version = 0.3.0-rc-2026-03-15) - get-receive-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - @since(version = 0.3.0-rc-2026-03-15) - get-send-buffer-size: func() -> result; - @since(version = 0.3.0-rc-2026-03-15) - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - } -} diff --git a/proposals/sockets/wit-0.3.0-draft/world.wit b/proposals/sockets/wit-0.3.0-draft/world.wit deleted file mode 100644 index 227662dab..000000000 --- a/proposals/sockets/wit-0.3.0-draft/world.wit +++ /dev/null @@ -1,9 +0,0 @@ -package wasi:sockets@0.3.0-rc-2026-03-15; - -@since(version = 0.3.0-rc-2026-03-15) -world imports { - @since(version = 0.3.0-rc-2026-03-15) - import types; - @since(version = 0.3.0-rc-2026-03-15) - import ip-name-lookup; -} From 97e1422684cd9f88a7b9b7f65e174b98bfa076b0 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Wed, 10 Jun 2026 22:59:32 -0400 Subject: [PATCH 2/3] Rewrite README for WASI 0.2 branch --- README.md | 52 ++++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 27365e258..eeb288281 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,25 @@ - +# WASI 0.2 docs -# WebAssembly System Interface +This branch documents the WASI 0.2 iteration of WASI, also known as Preview 2. -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4323447.svg)](https://doi.org/10.5281/zenodo.4323447) - +WASI 0.2 is a modular collection of APIs defined using the [Wit IDL]. It +incorporates many of the lessons learned from [Preview 1], including support +for a wider range of source languages, modularity, a more expressive type +system, virtualizability, and more. It covers the `wasi:cli`, `wasi:clocks`, +`wasi:filesystem`, `wasi:http`, `wasi:io`, `wasi:random`, and `wasi:sockets` +interfaces at their 0.2.x versions. -The WebAssembly System Interface (WASI) is a set of APIs for WASI being -developed for eventual standardization by the WASI Subgroup, which is a -subgroup of the WebAssembly Community Group. +Development of WASI now continues in [WASI 0.3] (Preview 3) on the `main` +branch, which supplants Preview 2 by providing integrated and composable +`async` functionality. Implementations may continue to support WASI 0.2, +either by implementing WASI 0.3 alongside it, or by virtualizing +(polyfilling) 0.2 in terms of 0.3. -WASI started with launching what is now called [Preview 1], an API using -the witx IDL, and it is now widely used. Its major influences are POSIX and -CloudABI. - -[WASI Preview 2] is now stable, and is a modular collection of -APIs defined with the [Wit IDL], and it incorporates many of the lessons -learned from Preview 1, including adding support for a wider range of -source languages, modularity, a more expressive type system, -virtualizability, and more. +The proposals included in WASI 0.2 are documented under [`proposals/`](proposals), +and the tagged interface snapshots are under [`specifications/`](specifications). +See [Preview2.md](docs/Preview2.md) for the Preview 2 inclusion criteria and +overview. [Preview 1]: https://github.com/WebAssembly/WASI/tree/wasi-0.1 -[WASI Preview 2]: https://github.com/WebAssembly/WASI/blob/main/docs/Preview2.md +[WASI 0.3]: https://github.com/WebAssembly/WASI/tree/main [Wit IDL]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md - -## Find the APIs - -Development of each API happens in its own repo, which you can access -from the [proposals list](docs/Proposals.md). - -This repo is for general discussion, as well as documenting how we work -and high-level goals. - -## Propose a new API - -If you would like to create a new proposal, get started with our -[Contributing guide](CONTRIBUTING.md). - -All new API proposals should use the new format and the new repo structure that is shown in the [proposal template](https://github.com/WebAssembly/wasi-proposal-template). - -See the [Wit in WASI](docs/WitInWasi.md) document for more information about using Wit for WASI proposals. From c3cbbd3c476ea7cd18b0f76d8de62fe833209968 Mon Sep 17 00:00:00 2001 From: Bailey Hayes Date: Thu, 11 Jun 2026 10:31:20 -0400 Subject: [PATCH 3/3] ci: skip removed 0.3 drafts --- .github/scripts/validate-proposals.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/scripts/validate-proposals.js b/.github/scripts/validate-proposals.js index a6a85b598..baf486bad 100644 --- a/.github/scripts/validate-proposals.js +++ b/.github/scripts/validate-proposals.js @@ -71,6 +71,14 @@ for (const { proposal, version } of toValidate) { try { console.log(` Path: ${witDir}`); + // Skip when the wit directory no longer exists. A PR that removes a wit + // tree (e.g. dropping the 0.3 drafts on this branch) still surfaces its + // deleted files in the changed-file list, but there is nothing to validate. + if (!fs.existsSync(witDir)) { + console.log(` Skipping ${proposal} v${version}: ${witDir} no longer exists (removed)`); + continue; + } + // Check wit-deps lock if deps.toml exists if (fs.existsSync(`${witDir}/deps.toml`)) { console.log(' Checking dependencies...');