Repository navigation
Updater and security hotfix for 3.11.1. Agent Tools protocol, configuration and data formats are unchanged.
Upgrade notes
- Updating from 3.11.0 or 3.11.1 needs one manual step. Their built-in updater stops after downloading and verifying a release with
Failed to complete durable update transaction: prepared transaction is missing its integrity digest, and scheduled automatic updates fail the same way. Nothing is changed or damaged: the installed binary keeps running. Install this release once through the channel you installed with —curl -fsSL https://leanctx.com/install.sh | sh,brew upgrade lean-ctx,npm i -g lean-ctx-bin@latest,cargo install lean-ctx --forceor your AUR helper — andlean-ctx updateand automatic updates work again from then on. - Windows on 3.11.0 (#2039): the 3.11.0 updater also needs the external
cosigntool and looks for it under that exact name; installing cosign does not help, because its update then stops at the error above. Extract the Windows ZIP of this release over yourlean-ctx.exe, or update through npm. From 3.11.1 on, no external tool is needed.
Security
- The
homejail scope opens projects, not your home directory. 3.11.1 admitted every path below~for reading, so a prompt-injected agent could pull loose personal files (~/Documents/taxes.pdf,~/Downloads,~/Desktop) into the model context. A path is now admitted only when a folder between it and~holds a project marker (.git,Cargo.toml,package.json,go.mod,pyproject.toml,Makefile, …). Every repository below~stays readable; anything else needslean-ctx allow-path <dir>, and the refusal says so. redirect_excludefrom an untrusted workspace is withheld (#2034). Paths inredirect_excludeskip the native-read hook redirect and with it the redaction that path applies. In 3.11.1 a repository's own.lean-ctx.tomlcould extend the list even when the workspace was not trusted, so a cloned repository could opt its reads out (for example with["**"]) on hosts where the read redirect is active. Such a list is now ignored with a[SECURITY]warning until you runlean-ctx trust; the global config andLEAN_CTX_HOOK_EXCLUDEstill apply.
Fixed
- Codex threads recorded while ChatGPT routing was on stay resumable. Codex stamps
model_provider = "leanctx-chatgpt"into every such thread and refuses to resume it once that provider is missing (Model provider 'leanctx-chatgpt' not found).lean-ctx doctor --fix,proxyruns and stale-proxy cleanup deleted the[model_providers.leanctx-chatgpt]block by name, including the direct one users restored by hand. Cleanup now only touches a block that targets the local proxy, and repoints it athttps://chatgpt.com/backend-api/codexinstead of deleting it; a block aimed anywhere else is kept verbatim and no longer reported as routed or broken. ctx_multi_repo action=searchwithout a query says so. While a content policy was active, the call was refused with the cross-project policy message instead ofquery is required for search.- No downgrade as "update". Without an explicit version,
lean-ctx updateand scheduled updates only install a release newer than the running build; a build ahead of GitHub's latest release was offered, and on a schedule installed, the older release.lean-ctx update <version>and--pinstill install any version on purpose. - GitHub API rate limit (#2037): the updater now sends
GITHUB_TOKEN,GH_TOKENorLEAN_CTX_GITHUB_TOKENwhen set (only to api.github.com, without following redirects), raising GitHub's limit from 60 requests per hour per IP address to 5000. An exhausted quota now says so, with the reset time and the fix, instead ofhttp status: 403; a rejected token reports401 Bad credentials. The background version check uses the same client. lean-ctx updateandlean-ctx update --rollbackcomplete again. The updater sealed each prepared transaction with its integrity digest when writing it to disk, but then executed the unsealed copy, which the integrity check rejected every time. The updater now executes exactly the sealed transaction it persisted. A new test runs the real prepare → execute → recover path on a stand-in binary.- macOS: the update signature is applied before the swap. The updater re-signed the installed binary after moving it into place (#356, so the TCC grant survives), which changed its bytes after the transaction had recorded them; the update then stopped with "active binary does not match prepared target". The staged binary is now signed first, and the receipt records exactly the bytes that are installed; the release manifest and archive digests still record its provenance.
- A reinstall no longer blocks later updates. A failed 3.11.0/3.11.1 run leaves a prepared transaction behind; after a manual reinstall the updater refused every update with "active binary matches neither prepared state". Recovery now recognizes a transaction that a build at least as new as its target has superseded and removes its staged files without touching the binary. Likewise, an update receipt from a different, earlier version no longer refuses updates ("current binary differs from the active receipt"); the updater starts a new receipt from the running binary. A binary that differs from a receipt of the same version is still refused.
Upgrade
lean-ctx update # recommended (auto-downloads + refreshes shell hooks)
cargo install lean-ctx # or
npm update -g lean-ctx-bin # or
brew upgrade lean-ctxNote: After upgrading via cargo/npm/brew, run
lean-ctx setupto refresh shell aliases.lean-ctx updatedoes this automatically.
Full Changelog: v3.11.1...v3.11.2