From a2e7abc2bb488df0d1b7265a2952c552ce038ee9 Mon Sep 17 00:00:00 2001 From: Yasyf Mohamedali Date: Thu, 17 Sep 2026 15:24:16 -0700 Subject: [PATCH] =?UTF-8?q?deps:=20=F0=9F=94=92=EF=B8=8F=20raise=20the=20s?= =?UTF-8?q?pawnllm=20floor=20to=200.13.4=20so=20a=20killed=20spawn=20leave?= =?UTF-8?q?s=20no=20token=20on=20disk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: spawnllm 0.13.3 and earlier ran their isolated `claude -p` calls against a temp config directory and wrote a `.credentials.json` copy of the OAuth token into it for the child to read. Every spawn killed before its cleanup left that copy on disk, and Claude Code migrated each one into a login-Keychain item. One machine carried 345. Summary: `spawnllm>=0.13.2,<0.14` becomes `spawnllm>=0.13.4,<0.14`, and `uv lock` moves the pin from 0.13.2 to 0.13.4. Motivation: the `<0.14` ceiling already admitted 0.13.4, so a fresh resolve picked the fix up while an existing lock stayed on 0.13.2. Raising the floor makes the fixed version the only resolution, which is what a security fix needs. Details: spawnllm 0.13.4 (yasyf/spawnllm#9) passes the token through `CLAUDE_CODE_OAUTH_TOKEN`, so there is nothing on disk for a kill to strand. capt-hook drives those spawns from `captain_hook/context.py` and `captain_hook/review/pipeline.py`, on every LLM hook and every review, and a hook whose caller's deadline abandons it is killed by design. The lock diff carries spawnllm's own version and artifacts and no transitive dependency change. --- CHANGELOG.md | 11 +++++++++++ pyproject.toml | 2 +- uv.lock | 10 +++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c4bdc78..953f160f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- **A killed hook spawn no longer leaves a copy of the OAuth token on disk.** + spawnllm ran its isolated `claude -p` calls against a temp config directory + and wrote a `.credentials.json` copy of the token into it for the child to + read. Every spawn killed before its cleanup left that copy behind, and Claude + Code migrated each one into a login-Keychain item. One machine carried 345. + 0.13.4 passes the token through `CLAUDE_CODE_OAUTH_TOKEN`, so spawnllm writes + no copy at all. The floor moves from `>=0.13.2` to `>=0.13.4`: an older + resolution still carries the leak. + ## [12.41.0] - 2026-09-17 ### Added diff --git a/pyproject.toml b/pyproject.toml index b1525aeb..87c74953 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ dependencies = [ "filelock>=3", "pathspec>=0.12", "loguru>=0.7.3", - "spawnllm>=0.13.2,<0.14", + "spawnllm>=0.13.4,<0.14", "mcp>=2.0,<3", ] diff --git a/uv.lock b/uv.lock index abcab29b..6a07c366 100644 --- a/uv.lock +++ b/uv.lock @@ -294,7 +294,7 @@ requires-dist = [ { name = "rich", specifier = ">=13" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8" }, { name = "spacy", specifier = ">=3.7" }, - { name = "spawnllm", specifier = ">=0.13.2,<0.14" }, + { name = "spawnllm", specifier = ">=0.13.4,<0.14" }, { name = "wn", specifier = ">=1.1.0" }, ] provides-extras = ["dev"] @@ -2467,7 +2467,7 @@ wheels = [ [[package]] name = "spawnllm" -version = "0.13.2" +version = "0.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -2476,10 +2476,10 @@ dependencies = [ { name = "pydantic" }, { name = "wasmtime" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/26/1e/f3debb81fd4fcc5d291483b5dabca7ce3e7b8958e5539d1052495b63792b/spawnllm-0.13.2.tar.gz", hash = "sha256:ba23da0e48546f989cec4d2375c3043977770c9a95f141c73002bcba885c7fb3", size = 212644, upload-time = "2026-09-14T22:01:01.329Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/19/f9e69af9b0775a2a95a2b3da81eb62097c4f2a772b1b5d16102dc9e55171/spawnllm-0.13.4.tar.gz", hash = "sha256:bc9d7d62cfb2a3599888c50c530f4d548c4f8612f7a1fb5d29dd4053c340d8dc", size = 279205, upload-time = "2026-09-17T20:21:26.48Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/f2/5877b19194d3bf70dbc99019352f3e767b5f612adfc9025df9e61506f2c5/spawnllm-0.13.2-py3-none-any.whl", hash = "sha256:7f75cec516661628936288442fc76b715487b30e5d48c37ff43e00fbf681a835", size = 225285, upload-time = "2026-09-14T22:00:58.663Z" }, - { url = "https://files.pythonhosted.org/packages/41/c5/e60728b94a44d360233fa4a788dcc02522e8e817df81672db40e1ded0da7/spawnllm-0.13.2-py3-none-macosx_26_0_arm64.whl", hash = "sha256:d1659c96873b254d956f706daee2c0911c1d310d009664219e8063741a2cd31b", size = 312509, upload-time = "2026-09-14T22:01:00.101Z" }, + { url = "https://files.pythonhosted.org/packages/24/94/da1411382cd7b114527b6d539519b979543d8aa868d3e79e2123cf2837c9/spawnllm-0.13.4-py3-none-any.whl", hash = "sha256:e6390e943193720d22e0aff10d454ba6590988dfe9a165f7cf8ceffad4c9830e", size = 290125, upload-time = "2026-09-17T20:21:23.553Z" }, + { url = "https://files.pythonhosted.org/packages/ce/57/c43fc9bdd0517855ebd01bb504fbdc95e702ff8bca0131765a7960c7ca40/spawnllm-0.13.4-py3-none-macosx_26_0_arm64.whl", hash = "sha256:18275a8bdc2cced7bcca1013ec1dfb46d2335f16a440501da2c20a6558b5bfc3", size = 376439, upload-time = "2026-09-17T20:21:25.191Z" }, ] [[package]]