Clarify network and test execution contracts
CI / checks (pull_request) Successful in 4m30s
Agents / bot (pull_request) Successful in 6m20s

This commit is contained in:
Danny Kim
2026-09-30 19:31:54 +09:00
parent 179c17a337
commit a3175ded3a
4 changed files with 18 additions and 14 deletions
+3 -2
View File
@@ -16,8 +16,9 @@ One provider, `ftp`, for the `ftp` and `ftps` schemes. A connection is
configured with a server name, an optional port, a TLS toggle for FTPS, and an configured with a server name, an optional port, a TLS toggle for FTPS, and an
optional username and password. An empty username signs in anonymously. optional username and password. An empty username signs in anonymously.
Public, LAN, VPN, link-local and localhost addresses work directly from the With the compatible schema 2 Memona version required by this package, public,
server name; there is no separate network permission setting. LAN, VPN, link-local and localhost addresses work directly from the server
name; that API has no separate connection network grant.
The TLS toggle currently starts TLS on the control connection only. Protected The TLS toggle currently starts TLS on the control connection only. Protected
data connections and explicit `AUTH TLS` negotiation are not implemented, so data connections and explicit `AUTH TLS` negotiation are not implemented, so
+9 -8
View File
@@ -36,9 +36,10 @@ interface host {
pull: func(limit: u32) -> result<list<u8>, host-error>; pull: func(limit: u32) -> result<list<u8>, host-error>;
} }
/// Begins a request to any HTTP or HTTPS host, including LAN and loopback /// Begins a request to any HTTP or HTTPS host, including LAN and loopback
/// addresses. Each redirect and DNS result is checked, and DNS is pinned. /// addresses. This API has no per-connection network grant. Each redirect
/// Cross-origin redirects remove request headers; HTTPS cannot downgrade. /// and DNS result is checked, and DNS is pinned. Cross-origin redirects
/// The host bounds total bytes per exchange, not buffer size. /// remove request headers; HTTPS cannot downgrade. The host bounds total
/// bytes per exchange, not buffer size.
http: func(request: request) -> result<exchange, host-error>; http: func(request: request) -> result<exchange, host-error>;
/// One open TCP connection. Dropping the handle closes the socket, and the /// One open TCP connection. Dropping the handle closes the socket, and the
@@ -51,9 +52,9 @@ interface host {
write: func(data: list<u8>) -> result<u32, host-error>; write: func(data: list<u8>) -> result<u32, host-error>;
} }
/// Opens a socket to any host, including LAN and loopback addresses, on a /// Opens a socket to any host, including LAN and loopback addresses, on a
/// package-declared port. The host resolves and pins DNS and starts TLS /// package-declared port. This API has no per-connection network grant.
/// when asked. Ports negotiated at runtime, such as an FTP data channel, /// The host resolves and pins DNS and starts TLS when asked. Ports
/// must be declared. /// negotiated at runtime, such as an FTP data channel, must be declared.
connect: func(host: string, port: u16, tls: bool) -> result<tcp, host-error>; connect: func(host: string, port: u16, tls: bool) -> result<tcp, host-error>;
/// One datagram socket connected to a single peer. /// One datagram socket connected to a single peer.
@@ -64,8 +65,8 @@ interface host {
/// means none arrived inside the host's wait, not that the peer left. /// means none arrived inside the host's wait, not that the peer left.
receive: func(limit: u32) -> result<list<u8>, host-error>; receive: func(limit: u32) -> result<list<u8>, host-error>;
} }
/// Connects a datagram socket under the same port rules as `connect`, for /// Connects a datagram socket under the same address and port rules as
/// the few filesystem protocols that still need one. /// `connect`, for the few filesystem protocols that still need one.
bind: func(host: string, port: u16) -> result<udp, host-error>; bind: func(host: string, port: u16) -> result<udp, host-error>;
/// A configuration value, typed as the package's manifest declared it. /// A configuration value, typed as the package's manifest declared it.
+3 -2
View File
@@ -1,5 +1,6 @@
//! Real FTP commands over a native test socket, with an async local server. //! Real FTP commands against an async local server. The generated guest API is
//! This verifies guest recovery; WASM host integration is exercised separately. //! synchronous, so each guest call is isolated with `spawn_blocking`; production
//! WASM host integration is exercised separately.
use super::Ftp; use super::Ftp;
use memona_plugin_sdk::{ErrorCode, Guest, Locator, Setting}; use memona_plugin_sdk::{ErrorCode, Guest, Locator, Setting};
+3 -2
View File
@@ -1,5 +1,6 @@
//! Native test transport. Guest calls run only inside `spawn_blocking`; //! Native test transport for the generated synchronous `Guest` API. It cannot
//! production WASM always uses the host's sockets and network policy. //! await a Tokio socket, so tests confine it to `spawn_blocking` while their FTP
//! server remains async. Production WASM always uses the host's async sockets.
use std::cell::RefCell; use std::cell::RefCell;
use std::io::{Read, Write}; use std::io::{Read, Write};