Skip to content

Releases: guilt/xet-server

Release list

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 16 Sep 03:38
Release 1.1.0: transparent xet-token 401 healing in xet-proxyd

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 14 Sep 01:20
Release 1.0.0: HF Tested Release

GitHub Actions CI/CD (per-platform release zips with docs),
go install support via github.com/guilt/xet-server module path

Update GitHub Issues, Feature Request Templates.

Fix Windows-only race in fsstore: retry os.Open on transient ERROR_SHARING_VIOLATION during a concurrent Put's
stage-then-rename, which could otherwise fail the read as a 500. Fixes intermittent TestChaos_*
failures on Windows.

More Testing against HF Server revealed some gaps.

Fix chunk sizes being too small for HF large models.

Add the git-LFS batch endpoint to xetd (POST /{repo}.git/info/lfs/objects/batch,
answering transfer "xet"). This is what actually routes a real client into the Xet
upload path: huggingface_hub offers ["basic","multipart","xet"] and branches on the
server's reply, so without it every file over the ~5MB LFS threshold fell back to
plain LFS and failed. Files under the threshold commit inline and never hit it, which
is why small-file round-trips passed against a server missing it entirely.

Add siblings to repo-info. snapshot_download falls back to list_repo_tree when siblings
is empty, and that fallback hands a generator to tqdm's thread_map, which raises
"min() arg is an empty sequence" before downloading anything.

Add dataset/space support on resolve and LFS-batch URLs: models are unprefixed while
datasets/spaces carry a repo-type segment, so parse from the "/resolve/" marker rather
than a fixed index. repoType is threaded into the upstream call and X-Xet-Refresh-Route.

Fix the snapshot loop exhausting memory on any large cache: chunkHashToShard stored the
full shard body per referencing chunk, and encoding/json does not preserve aliasing, so
a ~30MB shard over ~1.7M chunks serialized toward ~50TB. Store each body once,
content-addressed, with chunks holding a 32-byte hash (snapshot format v2). This also
restores file_recon persistence, which was silently lost while every snapshot died -
xorb bytes were on disk but a restarted server could reconstruct nothing.

Harden the LFS batch endpoint: bound the request body (413 rather than unbounded
json.Decode), cap object count (the response echoes objects back, so an unbounded count
is an amplification primitive), require exactly one JSON value (Decode silently ignores
trailing data), and only create repo state after validation.

Add fuzz coverage for textual attacker input, not just wire formats: resolve-path and
LFS-batch parsers, the batch endpoint over a real httptest server, and the v2 snapshot
round-trip. Found and fixed two real bugs - "//resolve//0" was accepted as a repo ID of
"/" with empty namespace and name, and trailing bytes after a JSON body were ignored.
Both failing inputs are committed as regression corpus.

Make the integration suite hermetic and fix it on Windows: clear HF_TOKEN and friends so
an exported token no longer makes the suite pass or fail by machine; normalize the temp
dir via cygpath so native Python can open paths interpolated into -c strings; tolerate
non-zero wait status from TerminateProcess; correct "if ! cmd; then status=$?" which
captured the negated status and made timeout diagnostics unreachable.

Add $(EXE) to Makefile outputs so Windows builds produce runnable bin/*.exe, plus
test-race, test-fuzz and fuzz-seeds targets. CI now also runs the integration suite
(previously unit tests only, leaving the hf-CLI compatibility surface unexercised) and
replays the fuzz corpus under -race.

Bundle browsable HTML docs into every release zip: a dedicated docs job installs
mmdc (mermaid-cli via bun), runs make docs, and the build matrix merges docs/build/
into each platform zip alongside the Markdown docs.

Restructure release workflow so artifacts are raw staging directories and zips are created
once in the release job: avoids GitHub's artifact-download zip wrapping producing a zip-within-a-zip,
and computes checksums on the final zips.

Co-Authored-By: Deepseek Flash / OpenCode
Co-Authored-By: Claude / OpenCode