/* The dev agent in a browser: the three calls, doing nothing, and saying so. * * Build selects this file over flan_agent.c on --target=web, and only there * (see Build.select_csrcs). The reason is not the compile error that led here * — emscripten's headers do not pull in transitively, so * flan_agent.c fails on `struct timeval` at line 426 — because an #include * would have fixed that and fixed nothing real. The reason is structural: * * THE AGENT IS A SOCKET SERVER, AND A BROWSER HAS NO SOCKETS. * * flan_agent_start binds an AF_UNIX socket and hands it to a listener thread. * There is no such address family under emscripten, nothing to listen on, and * nothing that could connect if there were. Adding the include produces an * agent that compiles, links, starts, and can never accept a connection. * * ── Why a no-op here, when `barf` on the web signals instead ──────────── * * NEXT.md decision 2 rejected a silent no-op for `barf` in as many words: a * no-op write is how a save file disappears with nothing said. The two look * contradictory and are not, and the difference is what the caller loses. * * `barf` is asked to make something durable. A no-op returns success to a * program that now believes the bytes are on disk; the loss is real, it is the * user's, and it is discovered later or never. So the web signals a condition * and the program decides. * * The agent is asked to accept redefinitions from an editor. On the web there * is no editor, no socket, and no session — `--dev` is refused by name on * every wasm target, so a web build has no cells to install a redefinition * into even if one arrived. There is nothing to lose because there was never * anything there. sand.flan already says the same thing about a *native* * release build, at the call site: * * "Building without --dev is fine — nothing has cells to install into, so a * module is refused on the listener thread and the loop never notices." * * A web build reaches that same outcome by a shorter route. The no-op is not * hiding a failure; it is the truthful implementation of "nothing is * available here", which is the case where Odin's own `.Unsupported` stubs are * right and the case decision 2 was careful to say it was not. * * ── Why not refuse vendor:agent on a web target ───────────────────────── * * It was the other candidate and it is ruled out by arithmetic, not taste. * Flan has no conditional compilation, so a program cannot say "skip this on * web". sand.flan calls (agent/start ...) unconditionally, Reach cannot prune * a package something reachable calls into, and a build-time refusal would * therefore mean sand.flan does not build for the browser at all without being * edited into a second program. Refusing is only honest when the caller has a * way to not ask; here it has none. * * ── What the return values say ────────────────────────────────────────── * * start returns -1, which is the same "could not listen" flan_agent.c returns * for a path it cannot bind, so a caller that checks gets the answer it * already knows how to read. poll and wait return 0 — no redefinitions * installed — which is the truth and is what the native build returns on every * frame that nothing arrived on. */ #include int32_t flan_agent_start(const uint8_t *path, int64_t len) { (void)path; (void)len; return -1; } int32_t flan_agent_poll(void) { return 0; } int32_t flan_agent_wait(int32_t ms) { (void)ms; return 0; }