zooqueenandHanzo Dev 481d69e8b7 jail: decide socketpair by its family, so Node can start a process
TypeScript and JavaScript were the two languages the new image could not serve.
The daemon said why and kept going: `language server did not start … spawn
EPERM`, once per root, while the other eight answered.

socketpair was denied beside socket, on the reading that a served process must
be able to obtain no socket fd at all. But libuv gives a child its stdio through
a socketpair, so what that denied was not a network — it was Node starting a
process, and typescript-language-server exists to run tsserver.

A socketpair reaches nothing: both ends come back already connected to each
other, in AF_UNIX, inside this jail's namespaces. It cannot be connect()ed
elsewhere, and a peer that could pass a network fd over it would have to be
outside the jail, where nothing is. socket() is still denied, so there is still
no way to obtain a fd to a network.

The filter now reads args[0] and admits AF_UNIX alone. Allowing it outright
would have been equivalent today — the kernel implements socketpair for no other
family — but that is a fact about the kernel, not a property of this program,
and the claim in the header is worth keeping true by construction.

The arithmetic is the risk: those two jump edges are hand-computed offsets over
a list whose length changes with the phase, and an off-by-one reads as ALLOW.
TestSocketpairIsDecidedByItsFamily interprets the program for AF_UNIX and for
five families that must fail, in both phases, and pins that the carve-out did
not widen to socket().

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-09 12:17:33 -07:00

lsp

The jailed language-server daemon. It holds immutable per-(org, repo, commit) working trees, runs a language server over each one inside a jail with no network, and answers position questions about them.

The answer it exists for is a definition that leaves the repository and lands in a dependency — which a static symbol index structurally cannot give you.

POST /root       {org, repo, rev, files}       → {ready, cold, langs}
POST /root/warm  same body, only for a held repo
POST /ask        {org, repo, rev, op, path, line, character, relation}
                                               → the answer, or 409 {"need":"tree"}
GET  /healthz    liveness
GET  /readyz     readiness — green only once the jail proved out on this host

Everything else — the wire contract in full, the two-phase security model, the deployment, and what phase 2 is — is in LLM.md.

S
Description
Jailed language-server daemon: immutable per-(org,repo,commit) roots, gopls behind a seccomp jail with no network. Backs /v1/code/lsp.
Readme Apache-2.0
192 KiB
Languages
Go 93%
Dockerfile 7%