ken v1.1.0 — security hardening + int8 reranker by default
A feature-and-hardening release. The int8 reranker becomes the default now that it's free, output: "json" reaches the last tool, the remote-clone path closes its two known SSRF gaps, and a govulncheck gate joins CI.
No breaking changes. mcp.Run / mcp.NewServer / the chunk.Chunker interface and the MCP wire format are unchanged from 1.0. The int8 default and the new KEN_MAX_CLONE_BYTES knob are both backward-compatible — existing configs keep working.
Highlights
⚡ int8 reranker is now the default
aikit v1.5.0 fixed the q8 path, so int8 now matches f32 reranker latency (50-doc cold: 7.35 s vs 7.75 s on arm64) at ~21× less runtime memory (18 MiB vs 379 MiB) and ¼ the weight footprint (~140 MB resident vs ~547 MB) — with cosine 0.997 vs f32, unchanged ranking quality. KEN_MCP_RERANK_QUANT and --rerank-quant now default to int8; pass f32 for the full-precision path. No re-download needed — LoadQ8 quantizes your existing CodeRankEmbed snapshot in-process.
This reverses the "int8 is slower on Apple Silicon" note from 1.0.1 — that was the pre-fix aikit path.
🧩 All nine MCP tools now speak JSON
recently_changed was the last markdown-only tool; it now accepts output: "json" and returns a typed RecentlyChangedResponse (considered-count + per-commit hash / short_hash / subject / author / RFC3339 timestamp / changed_files), built from the same rows as the markdown render so the two can't drift.
🔒 Security
- Clone SSRF guard hardened + a byte cap.
ken-mcp's remote-repo clone now re-validates the resolved IP at connect time and dials it literally (TLS still verifies the hostname via SNI) — closing the DNS-rebinding TOCTOU the pre-flight check couldn't catch, including redirects to internal hosts. It also byte-caps the clone stream (KEN_MAX_CLONE_BYTES, default 2 GiB) so a hostile server can't stream an unbounded/pathological pack. Both checks honorKEN_ALLOW_PRIVATE_CLONE_TARGETS=1. govulncheckCI gate. Go's symbol-level vulnerability scanner now runs on every push. Bringing it green fixed 9 reachable CVEs (bumpedgolang.org/x/cryptoto v0.52.0 and the toolchain to go 1.26.4). The gate blocks any reachable-CVE regression from landing.
🐛 Fixed
- Data race in the definition-pattern cache.
internal/search'sdefPatternCache(the compiled-regex memo behind thedefinitiontool) was read and written unsynchronized; concurrent queries could race it. Now guarded by anRWMutex, with a race-detector regression test.
📚 Docs & tooling
New top-level CONTRIBUTING.md and SECURITY.md, a Makefile, a "Compared to other agent code-search tools" table in the README, and a "Personally-namespaced dependencies" section in DEVELOPERS.md documenting the gotreesitter dependency delta and the go.work local-aikit workflow.
Install / upgrade
# Homebrew (macOS/Linux) — ken ships as a cask
brew upgrade --cask ken # new install: brew install --cask townsendmerino/tap/ken# Windows (Scoop)
scoop update ken # new install: scoop bucket add townsendmerino https://github.com/townsendmerino/scoop-bucket; scoop install ken# Or with Go
go install github.com/townsendmerino/ken/cmd/ken@v1.1.0
go install github.com/townsendmerino/ken/cmd/ken-mcp@v1.1.0No config changes are required to upgrade. If you run the reranker (KEN_MCP_RERANK=on) and want to keep the full-precision path, set KEN_MCP_RERANK_QUANT=f32.
Full changelog: CHANGELOG.md · compare v1.0.1...v1.1.0