zooqueenandHanzo Dev 60a74ec341 lsp: locate a fetch only where it can run, and say why a server died
Two defects, found from one report: a TypeScript tree with a package.json and no
lockfile answered the first query and then 502'd every one after it.

FIRST, the fetch. `npm ci` installs exactly what a lockfile pins and refuses
outright without one, so naming package.json as the marker bought a fetch that
could only ever fail — on every library that commits no lock, which is most of
them. Roots locates the FETCH and nothing else reads it, so the marker has to be
the file the fetch REQUIRES: package-lock.json or npm-shrinkwrap.json, and
Cargo.lock for `cargo fetch --locked`, which had the same defect and was only
quieter about it. A locked tree fetches exactly as before; a lockless one is
served from source, which is the trade every other fetchless language already
makes.

SECOND, and the reason the first took guesswork to investigate: a server that
died MID-SESSION took its reason with it. attach already keeps the last 4 KiB of
its stderr, but only spent it on a handshake failure — so a server that started
cleanly and died on the third query reported `write |1: broken pipe`, which
names the symptom and nothing about the cause. That is the blindness `exit
status 126` was for Probe, and it is fixed the same way: stopped() carries the
server's last words, and a failed write waits briefly for the reader to reach
the same conclusion rather than racing it and reporting the pipe.

The tree left behind by the failed fetch is CLEAN — npm refuses before it writes
anything — and package.json, a read-only tree and an unreachable registry all
fail to reproduce the death outside the jail. So the crash itself is not yet
explained, and this is what makes explaining it possible: the next occurrence
arrives with the words the server died saying.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-09 23:28:11 -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%