| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| install.ps1 | 2026-10-23 | 14.6 kB | |
| install.sh | 2026-10-23 | 12.0 kB | |
| semlith-v0.46.0-aarch64-apple-darwin.tar.gz | 2026-10-23 | 26.7 MB | |
| semlith-v0.46.0-aarch64-apple-darwin.tar.gz.sig | 2026-10-23 | 294 Bytes | |
| semlith-v0.46.0-aarch64-unknown-linux-gnu.tar.gz | 2026-10-23 | 26.4 MB | |
| semlith-v0.46.0-aarch64-unknown-linux-gnu.tar.gz.sig | 2026-10-23 | 294 Bytes | |
| semlith-v0.46.0-x86_64-pc-windows-msvc.zip | 2026-10-23 | 24.4 MB | |
| semlith-v0.46.0-x86_64-pc-windows-msvc.zip.sig | 2026-10-23 | 294 Bytes | |
| semlith-v0.46.0-x86_64-unknown-linux-gnu.tar.gz | 2026-10-23 | 27.6 MB | |
| semlith-v0.46.0-x86_64-unknown-linux-gnu.tar.gz.sig | 2026-10-23 | 294 Bytes | |
| SHA256SUMS | 2026-10-23 | 603 Bytes | |
| SHA256SUMS.sig | 2026-10-23 | 294 Bytes | |
| README.md | 2026-10-23 | 7.1 kB | |
| Semlith 0.46.0 source code.tar.gz | 2026-10-23 | 9.2 MB | |
| Semlith 0.46.0 source code.zip | 2026-10-23 | 9.5 MB | |
| Totals: 15 Items | 123.7 MB | 0 | |
The two security audits of 0.45.1 (2026-10-23) found nothing Critical or High. This release closes all eighteen of their findings, or records why one is accepted. Each fix comes with a test that fails on 0.45.1.
Security
- Only a commit on main can become a signed release (SEC-001). Before,
any pushed
v*tag was built, signed with the project key, attested and published as Latest, so anyone who could push a branch and a tag could ship a release every installer accepted. The release workflow now refuses a tag whose commitmaindoes not contain, before anything is built. Only an organisation admin can create av*tag. The signing key lives in areleaseenvironment that onlyv*tags can deploy to. - Each release job holds one permission (SEC-007).
signholds the key and no write token.attestholds the OIDC token.releasewrites the release and runs the one third-party action.- Tag builds use
--lockedwith no build cache. - Checkouts drop their credentials.
- Latest moves only to the highest version released.
- The shared-library and glibc gates fail on empty
readelforobjdumpoutput instead of passing. - The packs workflow builds with a read-only token and publishes in a separate job that runs no third-party code.
- The installers check who built a release, and refuse an old one
(SEC-007, SEC-015).
install.shandinstall.ps1askghfor an attestation signed byrelease.ymlfor the tag being installed. They refuse a resolvedlatestolder than v0.46.0, and any tag that is not a wholevMAJOR.MINOR.PATCH.install.shrefuses busybox wget.install.ps1runs in one script block, soirm | iexleaves nothing in the caller's session, and it restores the process-wide TLS setting afterwards. semlith addnever fetches through a proxy (SEC-003). ureq readALL_PROXY,HTTPS_PROXYandHTTP_PROXY. Through a proxy, the proxy resolves the name, so the private-address guard checked only the proxy's address. A failed fetch now names any proxy variable that is set. 198.18.0.0/15, 192.0.0.0/24, 192.88.99.0/24 and fec0::/10 are private (SEC-009).semlith upgradeunpacks the bytes it checked (SEC-004, SEC-014). It used to write the checked archive out and open it again, in a work directory that might already exist. It now unpacks from memory into a directory it has just created, owner-only. Both archive readers refuse an entry with a colon (a Windows drive-relative path or alternate data stream) or a Windows device name.- Packs and the embedding model are used as they were checked (SEC-004). A pack is extracted from the bytes that matched its digest. A bare-version stamp from before 0.41.0 no longer counts as installed. The embedding model's files are checked against their pinned digests once per process, as they are loaded.
- On macOS, a native parser cannot grow past its worker's memory limit
(the second audit's Medium). Darwin refuses a lower
RLIMIT_AS, so the limit used to cover only Rust's allocations, and the deadline bounded the rest. The daemon now reads each worker's memory footprint every 25 ms and ends one that passes its idle footprint plus the limit. The file is refused with the peak and the cap, and the next file parses. A poll can overshoot by what a parse allocates in 25 ms, about 13 MiB on an M1. A worker that has already read other files gets the file once more on a fresh worker before it is refused, because malloc keeps what earlier files freed. - Isolation headers (SEC-015). Every portal response sends
Permissions-Policy,Cross-Origin-Opener-Policy: same-originandCross-Origin-Resource-Policy: same-origin. - Every lockfile is audited (SEC-010, SEC-011, SEC-013, SEC-016).
cargo denychecks every feature's dependency graph (the Linux release builds withdynamic-ort), and denies yanked crates and wildcard requirements.- The fuzz harness's lockfile moves to rustls-webpki 0.103.16, webpki-roots 1.0.11 and zip 9.0.5.
- The Core ML pack installs a lock with every package pinned by hash, and CI audits it beside both Cargo lockfiles.
ttf-parserandpastestay unmaintained with no replacement upstream, so their ignores carry today's reasons. ttf-parser reads only fonts semlith picks for its own PDF reports. lopdf calls it only to write a PDF, never when an indexed PDF is read. The font readers that do see indexed PDFs run in the parse worker.tests/parse_pdf.rsindexes a PDF whose embedded Type 1 font overflows its reader's stack, and one whose CFF font panics. The first is refused as a crash, the second as having no text, and the daemon stays up.- A secret scan gates every push (SEC-002). gitleaks runs over the tree, with a rule for crates.io tokens. Publishing has gone through Trusted Publishing since 0.41.0, and the stale local token is gone.
Changed
- CI decides more carefully what is prose (SEC-005, SEC-006).
changes.shused to treat the agent rules, skill and clients guide thatsemlith setupwrites into users' clients as prose, because they live underdocs/. It now treats them as code. A rename counts as both of its paths. A previous head is trusted only if its run, on the same branch, ran the heavy lanes green. Self-tests cover it and the new tag check. - The bug hunt in
native-smoke.ymlreads its own budget-cappedANTHROPIC_BUGHUNT_KEYand skips without it. Its tools are installed at pinned versions.
Accepted
- A process running as you that writes the model cache while the daemon runs
could change an unpacked pack's files, or the model graph ONNX Runtime opens
by path, after the check. Such a process can already replace the binary.
docs/security.mdsays so (SEC-004). - Two expired confidential-VM attestation tokens remain in the history behind the v0.37.0-rc.5 and rc.6 tags, which the tag ruleset keeps immutable. They grant nothing (SEC-012).
Install
macOS and Linux
:::sh
curl --proto '=https' --tlsv1.2 -fsSL https://raw.githubusercontent.com/semlith/semlith/main/install.sh | sh
Windows
:::powershell
irm https://raw.githubusercontent.com/semlith/semlith/main/install.ps1 | iex
Or download the archive for your platform below, unpack it, and put
semlith on your PATH. Intel macOS has no prebuilt binary: ONNX
Runtime no longer publishes x86_64 macOS builds.
Verify a download against SHA256SUMS before running it, SHA256SUMS
against its signature (release key
SHA256:a5oJmrakIwDHEWTDWqWe51Ttt6m2tQ0dsGzIqyxDuxs) with
echo "semlith-release ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICMTHiHMzeSHzzc+8UDZHUzJcvb6XGUBb+TJdFes91xm" > allowed_signers
and ssh-keygen -Y verify -f allowed_signers -I semlith-release -n file -s SHA256SUMS.sig < SHA256SUMS,
and its provenance with gh attestation verify <file> --repo semlith/semlith --signer-workflow semlith/semlith/.github/workflows/release.yml.