feat(net)!: network modules — contracts, SDK, sim and browser hosts, Rust core (stack A) - #305
Draft
HalfSweet wants to merge 2 commits into
Draft
feat(net)!: network modules — contracts, SDK, sim and browser hosts, Rust core (stack A)#305HalfSweet wants to merge 2 commits into
HalfSweet wants to merge 2 commits into
Conversation
…im and browser hosts, Rust core (stack A)
The contract and guest side of the network stack (stacked PR A of three;
B adds the portable C core and the POSIX/TLS drivers, C the ESP-IDF host):
- contracts/spec/{net,ws,httpd}.ts: the net spec at v2 (ops 6–9 readInto /
limits / write / endBody, op 2 retired, streaming headers / readable /
end / error events, the shared error vocabulary with the tls_* codes) and
the new ws and httpd module specs; gen-rust emits net/ws/httpd, the new
gen-c emits engine/net/include/pocketjs/net/spec.h (the generated header
rides here, the core that consumes it lands in B); tests/contract.ts
byte-compares every mirror.
- @pocketjs/framework/net is a support module (NetworkError,
AbortController/AbortSignal, URL, getNetworkLimits, shared types);
net/http (fetch, Headers, Request, Response, BodyStream, serve) and
net/websocket (connect) carry the modules. A per-module guest binding
drains one poll per tick from the framework service pump, settles
Promises inside that pump and copies bodies through readInto.
@pocketjs/framework/headless runs the frame transaction without a UI.
- contracts/spec/platforms.ts replaces net.http with the role-split
network.http.client(.tls) / network.http.server(.tls) /
network.websocket.client(.tls) ids; no stock target advertises them.
- hosts/sim/{net,httpd,ws}.ts are the deterministic hosts; hosts/web/net.js
moves to the streaming v2 contract; engine/crates/pocket-net is rewritten
to the v2 boundary over an HttpClientBackend.
BREAKING CHANGE: `@pocketjs/framework/net` no longer exports fetch /
NetError / PocketResponse — import fetch from `@pocketjs/framework/net/http`
(streaming Response, NetworkError); the capability id `net.http` is replaced
by `network.http.client` and its siblings.
…ntics, hard bounds, one frame prelude, Rust gate The review fixes for the contract/SDK/host side (stack A): - Network policy is a typed contract and plan truth (reviewer item 1): contracts/spec/network-policy.ts (connect / listen rules, credentials, switches; normalization into a canonical ResolvedNetworkPolicy v1; the reference matcher; canonical JSON). Manifest format 3 adds permissions.network (contracts/schema/pocket-3.json; format 2 stays valid and resolves to deny-all). ResolvedBuildPlan.network is covered by planHash; extractHostBuildInputs projects planHash, features and the canonical policy JSON (POCKETJS_NETWORK_POLICY). The sim hosts enforce an optional plan policy through the contract matcher (connect, listen, redirect re-check). contracts/spec/vectors/network-policy.json pins parse and match decisions for every implementation. - Wire semantics live in the spec (item 9): NET_METHODS_FORBIDDEN carries TRACK; HTTP_CORE_OWNED_REQUEST_HEADERS, HTTP_BODYLESS_STATUS, HTTP_NULL_BODY_STATUS, HTTP_REDIRECT_* join it; gen-c / gen-rust / the new gen-web (hosts/web/net-spec.js, drift-guarded) emit them; the SDK, sim and browser host drop their private copies; the sim method check is case-insensitive like the cores. contracts/spec/vectors/http-semantics.json runs on the SDK, the sim, the browser host, the C core (B) and the Rust core. - Hard bounds (item 8): teeBody sizes each pull to the remaining room so a clone's lagging branch never exceeds the aggregate limit; the browser dev host reads through a BYOB reader sized to the queue's free space. - runFramePrelude (item 10): one definition of clock → input latches → service pumps → effects for the Solid, Vue Vapor, Octane and headless entries. - Rust parity (item 3): the core owns the policy — NetPolicy parses the canonical document with the reference matcher (localNetwork enforced, no bare wildcard), backends receive a PolicyGate for every resolved address, redirect hop (spec rewrite table, hop budget, endpoint re-check) and TLS verification mode, the core classifies literal addresses and rejects a response from a URL the gate did not authorize; the shared vectors run in its tests. - Changelog (item 11): an Unreleased entry names the net change a breaking migration and introduces format 3. url.ts carried raw NUL/DEL bytes (git saw it as binary); they are escapes now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stack A of 3 for the network modules (supersedes the monolithic #299 as the review unit; B = portable C core, C = ESP-IDF host are stacked on top). This PR is the contract and guest side: the net/ws/httpd specs, the SDK, the ServicePump/headless frame entry, the deterministic sim hosts, the browser dev host and the Rust
pocket-netcore — plus the review-round fixes that belong to these layers.Breaking migration (Conventional Commits
feat(net)!):@pocketjs/framework/netis a support module now (NetworkError,AbortController/AbortSignal,URL,getNetworkLimits, types);fetch/Headers/Request/Response/BodyStream/servelive in@pocketjs/framework/net/http, the WebSocket client in@pocketjs/framework/net/websocket. The capability idnet.httpis replaced bynetwork.http.client(.tls)/network.http.server(.tls)/network.websocket.client(.tls). The changelog carries the migration note.Review-round changes in this PR (reviewer items 1, 3, 8, 9, 10, 11)
contracts/spec/network-policy.tsis the typed contract (connect/listen rules, credentials,localNetwork/insecureTransport/allowInvalidTlsForDevelopment), with normalization into a canonicalResolvedNetworkPolicy(v1), the reference matcher and the canonical JSON. Manifest format 3 (pocket: 3,schema/pocket-3.json) addspermissions.network; format 2 stays valid and resolves to deny-all.ResolvedBuildPlan.networkis covered byplanHash;extractHostBuildInputs()hands hostsnetwork.policyJson(POCKETJS_NETWORK_POLICY) — the exact string every core consumes. The sim hosts enforce a plan policy through the contract matcher. Shared vectors:contracts/spec/vectors/network-policy.json(TS reference, C core in B, Rust core here).NetPolicyparses the canonical document and enforceslocalNetwork(address classification shared with C); backends receive aPolicyGatefor every resolved address, every redirect hop (spec rewrite table, hop budget, endpoint re-check) and the TLS verification mode; the core classifies literal addresses itself and rejects a response whose URL the gate did not authorize. No bare*anywhere.NET_METHODS_FORBIDDEN(+TRACK),HTTP_CORE_OWNED_REQUEST_HEADERS,HTTP_BODYLESS_STATUS,HTTP_NULL_BODY_STATUS,HTTP_REDIRECT_*; generated intospec.h,spec.rsand the newhosts/web/net-spec.js(drift-guarded); private copies removed;contracts/spec/vectors/http-semantics.jsonruns on SDK, sim, browser host, C core (B) and Rust core.runFramePreludereplaces the four hand-typed copies (Solid, Vue Vapor, Octane, headless).!title. Also:framework/src/net/url.tscarried raw NUL/DEL bytes (git treated it as binary) — escapes now.Validation
bunx tsc --noEmit,bun tests/contract.ts(spec.rs / spec.h / net-spec.js / package exports drift),bun tools/test.ts11/11 stages green (473 unit tests incl.network-policy,net-policy-hosts,http-semantics),cargo test -p pocket-net11 tests (gate, literal classification, both shared vectors, mount).Stack
engine/netportable C core, POSIX driver, OpenSSL/ESP-TLS providers, conformance harness