diff --git a/TODO.md b/TODO.md index ea100690..23538422 100644 --- a/TODO.md +++ b/TODO.md @@ -306,6 +306,28 @@ everything still open, in the order it should be tackled. loops so it can be tested without them. The second is the real work. (Recorded 2026-08-20.) + - [ ] **THE SESSION AGENT DOES NOT RUN ON WINDOWS.** Found 2026-08-20, + the first time the JavaScript suite executed there: four test + files die in `beforeAll` with + `listen EACCES ... \agent.sock`. Node on Windows requires a named + pipe (`\\.\pipe\name`) for `server.listen(path)`; a filesystem + path is not a valid endpoint. Nothing about the daemon works + there — no `seedpass agent`, so no held seeds, no tokens, no + high-risk sessions, no sink delivery. + + This is not a path substitution. The agent's ACCESS CONTROL is the + socket's 0600 mode: the trust boundary is "only this user can + connect", enforced by the filesystem. Named pipes have their own + ACL model, so supporting Windows means answering what the 0600 + was buying and how to buy it again — a security design question, + and it should be decided rather than improvised. + + Until then the four files are excluded on Windows in + js/packages/cli/vitest.config.ts, with the reason written there. + With TypeScript becoming the only implementation this is a + shipping decision: either the agent gains a Windows transport, or + SeedPass documents the daemon as POSIX-only and the Windows CLI + works without it. - [ ] **Are vault files protected from other users on Windows?** SCOPE GREW 2026-08-20: this is no longer two Python tests. When the JavaScript suite first ran on Windows, eight more `0600` diff --git a/js/packages/cli/vitest.config.ts b/js/packages/cli/vitest.config.ts index 1b5a892b..db80e7e4 100644 --- a/js/packages/cli/vitest.config.ts +++ b/js/packages/cli/vitest.config.ts @@ -1,4 +1,27 @@ import { defineConfig } from "vitest/config"; +import process from "node:process"; + +/** + * The agent's transport is a Unix domain socket at a filesystem path, and its + * access control IS the socket's 0600 mode. Node on Windows wants a named + * pipe (`\\\\.\\pipe\\name`) for `server.listen(path)`, so a path like + * `C:\...\agent.sock` fails with EACCES before a single assertion runs — + * these four files die in beforeAll. + * + * Excluded here rather than skipped test by test, because the reason is one + * fact about the platform and not a property of any individual test: the + * session daemon does not run on Windows today. That is a real gap in a + * product about to ship TypeScript as its only implementation, and it is + * recorded in TODO.md — supporting it needs a named-pipe transport AND a + * Windows answer to what 0600 on the socket was buying, which is a security + * design question rather than a path substitution. + */ +const AGENT_TESTS = [ + "test/agentSecurity.test.ts", + "test/tokens.test.ts", + "test/highRisk.test.ts", + "test/profiles.test.ts", +]; export default defineConfig({ test: { @@ -7,5 +30,6 @@ export default defineConfig({ // comfortably exceeds the 5s default once several files run in parallel. testTimeout: 60_000, hookTimeout: 60_000, + ...(process.platform === "win32" ? { exclude: ["**/node_modules/**", ...AGENT_TESTS] } : {}), }, });