diff --git a/CHANGELOG.md b/CHANGELOG.md index 365f5598..5f33b41e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,46 @@ - **Human `/plan` respects `maxChildrenPerTask` but not `dailyLimit` (AGT-4123).** `POST /api/plan/dispatch` now refuses with `decomposition_child_cap` when an approved plan would leave more children than `autonomous.decomposition.maxChildrenPerTask` on the new parent (sharing `refuseForChildCap` with the autonomous path). The automation-pacing `dailyLimit` / `reserveDailyCreations` budget remains runner-only — an explicitly confirmed plan is not refused because the daemon already spent today's slots. +## 0.24.1 — 2026-09-20 + +### Added + +- **Cost-capped GitHub Action reviews.** `openswarm review --model ` is now + exposed by the CLI and the composite action forwards its optional `model` + input through the same reviewed call chain. The action refuses as + gate-not-run when an older installed package lacks the option, rather than + silently falling back to an uncontrolled default model. The dogfood workflow + pins `deepseek/deepseek-v4-flash`. +- **Backfill for pre-publication parked branches (AGT-4124).** `openswarm + drain-parks --path ` finds unowned `NEEDS_HUMAN` rows, creates or + reuses their draft PRs, and records zero-ahead or missing-branch reasons with + CAS-protected ledger updates. `--dry-run` performs no GitHub or ledger write. +- **Resource-aware test fan-out.** Test parallelism now scales with available + CPU and memory instead of unconditionally consuming the host. + +### Changed + +- **OpenSwarm is documented as an agentic CI/CD gate first.** The README now + leads with review → fix → re-review → deterministic verification and presents + the Linear daemon as an optional orchestration layer. +- **Fleet supervision exposes thinking effort.** The supervisor can configure + reasoning effort for every role instead of treating it as an inaccessible + model default. + +### Fixed + +- **Reproducible package installation on every supported platform.** LanceDB is + pinned to the last stable release whose declared macOS, Linux, and Windows + optional native packages all exist in the registry, so `npm ci` no longer + rejects the committed lockfile. +- **OpenRouter flash routing fails over to GLM.** A failing or unavailable + `deepseek/deepseek-v4-flash` review can promote to `z-ai/glm-5.3-flash` under + the existing fallback policy. +- **Durable run state has stronger recovery evidence.** Session transcripts, + watchdog causes, staged memory promotion, write scopes, and parked + publication records now survive the retries and handoffs that previously + obscured them. + ## 0.24.0 — 2026-09-10 diff --git a/action.yml b/action.yml index 4e955c4e..d7cf127b 100644 --- a/action.yml +++ b/action.yml @@ -219,8 +219,10 @@ runs: if [ -n "${REVIEW_MODEL:-}" ]; then ARGS+=(--model "$REVIEW_MODEL"); fi if [ "${READ_ONLY:-true}" = "true" ]; then ARGS+=(--read-only); fi - # stdout is the JSON document; diagnostics go to stderr and stay on the - # job log. + # The CLI's JSON contract puts diagnostics on stderr. A dependency can + # still emit a late stdout diagnostic from a background task, so parse + # the one review document into a clean runner-temp file before trusting + # it for outputs or the exit contract below. set +e openswarm "${ARGS[@]}" > "$REVIEW_JSON" STATUS=$? @@ -228,9 +230,30 @@ runs: DECISION="" GATE_RAN="false" - if [ -s "$REVIEW_JSON" ]; then - DECISION=$(REVIEW_JSON="$REVIEW_JSON" node -e 'try{process.stdout.write(String(JSON.parse(require("fs").readFileSync(process.env.REVIEW_JSON,"utf8")).decision??""))}catch{}') - GATE_RAN=$(REVIEW_JSON="$REVIEW_JSON" node -e 'try{process.stdout.write(String(JSON.parse(require("fs").readFileSync(process.env.REVIEW_JSON,"utf8")).gateRan??false))}catch{process.stdout.write("false")}') + PARSED_REVIEW_JSON="$RUNNER_TEMP/openswarm-review-parsed.json" + if [ -s "$REVIEW_JSON" ] && REVIEW_JSON="$REVIEW_JSON" PARSED_REVIEW_JSON="$PARSED_REVIEW_JSON" node -e ' + const fs = require("fs"); + const raw = fs.readFileSync(process.env.REVIEW_JSON, "utf8"); + let review; + try { review = JSON.parse(raw); } catch { + // A review document is emitted at the start of a line. Keep the + // first complete JSON document with the required gate fields, + // rather than treating a diagnostic prefix as a successful pass. + for (const match of raw.matchAll(/^[ \t]*\{/gm)) { + try { + const candidate = JSON.parse(raw.slice(match.index)); + if (typeof candidate?.gateRan === "boolean") { review = candidate; break; } + } catch {} + } + } + if (!review || typeof review.gateRan !== "boolean") process.exit(1); + fs.writeFileSync(process.env.PARSED_REVIEW_JSON, JSON.stringify(review)); + '; then + REVIEW_JSON="$PARSED_REVIEW_JSON" + DECISION=$(REVIEW_JSON="$REVIEW_JSON" node -e 'process.stdout.write(String(JSON.parse(require("fs").readFileSync(process.env.REVIEW_JSON,"utf8")).decision??""))') + GATE_RAN=$(REVIEW_JSON="$REVIEW_JSON" node -e 'process.stdout.write(String(JSON.parse(require("fs").readFileSync(process.env.REVIEW_JSON,"utf8")).gateRan))') + elif [ -s "$REVIEW_JSON" ]; then + echo "::warning::OpenSwarm produced output but no parseable review document" fi echo "decision=$DECISION" >> "$GITHUB_OUTPUT" @@ -278,7 +301,7 @@ runs: # an unknown option, a crash, output that is not the JSON document — is # a gate that did not run, and calling that a reject both misreports the # change and hides the real failure. - if [ "$STATUS" != "0" ] && [ "$GATE_RAN" != "true" ]; then + if [ "$GATE_RAN" != "true" ]; then echo "::error::OpenSwarm exited $STATUS without producing a verdict — the gate did not run" if [ "$FAIL_ON_GATE_NOT_RUN" = "true" ]; then exit 2; fi exit 0 diff --git a/package-lock.json b/package-lock.json index a3c4097a..4ab42e72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "@intrect/openswarm", - "version": "0.24.0", + "version": "0.24.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@intrect/openswarm", - "version": "0.24.0", + "version": "0.24.1", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.72.1", "@huggingface/transformers": "^4.2.0", "@inquirer/prompts": "^8.5.2", "@intrect/cxt": "^0.3.0", - "@lancedb/lancedb": "^0.23.0", + "@lancedb/lancedb": "0.22.3", "@linear/sdk": "^19.0.0", "@modelcontextprotocol/sdk": "^1.29.0", "@types/better-sqlite3": "^7.6.13", @@ -2074,9 +2074,9 @@ } }, "node_modules/@lancedb/lancedb": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@lancedb/lancedb/-/lancedb-0.23.0.tgz", - "integrity": "sha512-aYrIoEG24AC+wILCL57Ius/Y4yU+xFHDPKLvmjzzN4byAjzeIGF0TC86S5RBt4Ji+dxS7yIWV5Q/gE5/fybIFQ==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb/-/lancedb-0.22.3.tgz", + "integrity": "sha512-nRC0fkg+d7dzCtudKHT+VH7znk6KUXRZyuS6HJYNnIrbvXBxaT6wAPjEbf70KTuqvP2znj48Zg+kiwRqkRnAJw==", "cpu": [ "x64", "arm64" @@ -2094,23 +2094,23 @@ "node": ">= 18" }, "optionalDependencies": { - "@lancedb/lancedb-darwin-arm64": "0.23.0", - "@lancedb/lancedb-darwin-x64": "0.23.0", - "@lancedb/lancedb-linux-arm64-gnu": "0.23.0", - "@lancedb/lancedb-linux-arm64-musl": "0.23.0", - "@lancedb/lancedb-linux-x64-gnu": "0.23.0", - "@lancedb/lancedb-linux-x64-musl": "0.23.0", - "@lancedb/lancedb-win32-arm64-msvc": "0.23.0", - "@lancedb/lancedb-win32-x64-msvc": "0.23.0" + "@lancedb/lancedb-darwin-arm64": "0.22.3", + "@lancedb/lancedb-darwin-x64": "0.22.3", + "@lancedb/lancedb-linux-arm64-gnu": "0.22.3", + "@lancedb/lancedb-linux-arm64-musl": "0.22.3", + "@lancedb/lancedb-linux-x64-gnu": "0.22.3", + "@lancedb/lancedb-linux-x64-musl": "0.22.3", + "@lancedb/lancedb-win32-arm64-msvc": "0.22.3", + "@lancedb/lancedb-win32-x64-msvc": "0.22.3" }, "peerDependencies": { "apache-arrow": ">=15.0.0 <=18.1.0" } }, "node_modules/@lancedb/lancedb-darwin-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@lancedb/lancedb-darwin-arm64/-/lancedb-darwin-arm64-0.23.0.tgz", - "integrity": "sha512-8w0sMCNMwBv2kv5+fczGeSVlNOL+BOKChSsO4usM0hMw3PmxasONPctQBsESDuPS8lQ6/AKAQc2HT/ddd5Mg5w==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb-darwin-arm64/-/lancedb-darwin-arm64-0.22.3.tgz", + "integrity": "sha512-oP2Kic51nLqs27Xo+AzSVlcMgmmfZbU/PseQ3KBtU92rczO5DYU2St1Y7qDUWcjw+RF3H2v/DKzYed16h1wCBQ==", "cpu": [ "arm64" ], @@ -2123,13 +2123,32 @@ "node": ">= 18" } }, + "node_modules/@lancedb/lancedb-darwin-x64": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb-darwin-x64/-/lancedb-darwin-x64-0.22.3.tgz", + "integrity": "sha512-wOwgZkvBgQM8asjolz4NeyPa8W/AjZv4fwyQxJhTqKTGlB3ntrpdn1m84K5qncTmFFDcDfGgZ4DkNVkVK+ydoQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 18" + } + }, "node_modules/@lancedb/lancedb-linux-arm64-gnu": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@lancedb/lancedb-linux-arm64-gnu/-/lancedb-linux-arm64-gnu-0.23.0.tgz", - "integrity": "sha512-+xse2IspO7hbuHT4H62q8Ct00fTojnuBxXp1X1I3/27dDvW8E+/itFiJuTZ0YMaJc7nNr9qh9YFXZ9hZdEmReg==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb-linux-arm64-gnu/-/lancedb-linux-arm64-gnu-0.22.3.tgz", + "integrity": "sha512-YUbFuBKQniTZOR9h2/es1f7lDzdHNt8qXs5GaqFmLQv2GNWpnvKXVA/vVffhCNpFB5nV132o1VhXW3KoMubPsw==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2140,12 +2159,15 @@ } }, "node_modules/@lancedb/lancedb-linux-arm64-musl": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@lancedb/lancedb-linux-arm64-musl/-/lancedb-linux-arm64-musl-0.23.0.tgz", - "integrity": "sha512-c2UCtGoYjA3oDdw5y3RLK7J2th3rSjYBng+1I03vU9g092y8KATAJO/lV2AtyxSC+esSuyY1dMEaj8ADcXjZAA==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb-linux-arm64-musl/-/lancedb-linux-arm64-musl-0.22.3.tgz", + "integrity": "sha512-jVRMtXxxYaDlZSaclCIHB2N+NJvQ1Fj9EaPeBx+HxG2VqUg0vXKef+yiaD2aGo9sAH6mMmkKJsrPhwABpUC4rQ==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2156,12 +2178,15 @@ } }, "node_modules/@lancedb/lancedb-linux-x64-gnu": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@lancedb/lancedb-linux-x64-gnu/-/lancedb-linux-x64-gnu-0.23.0.tgz", - "integrity": "sha512-OPL7tK3JCTx43ZxvbVs+CljfCer0KrojANQbcJ2V4VAp6XBhKx1sBAlIVGuCrd93pA8UOUP3iHsM7aglPo6rCg==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb-linux-x64-gnu/-/lancedb-linux-x64-gnu-0.22.3.tgz", + "integrity": "sha512-co7idTwvNAtbFoFHojhHlTpKsydOm5sZfbtAsQRdoa7g6a61yIrqrMm8D7Ngh756JfzZLFQBMkDUZEW3X4vP/g==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2172,12 +2197,15 @@ } }, "node_modules/@lancedb/lancedb-linux-x64-musl": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@lancedb/lancedb-linux-x64-musl/-/lancedb-linux-x64-musl-0.23.0.tgz", - "integrity": "sha512-1ZEoQDwOrKvwPyAG+95/r1NYqX8Ca5bRek8Vr62CzWCEmHd/pFeEGWZ5STrkh+Bt3GLdi2JOivFtRbmuBAJypQ==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb-linux-x64-musl/-/lancedb-linux-x64-musl-0.22.3.tgz", + "integrity": "sha512-+ipFsn5PCODK7mOMq1gZ5OAZWks5YlgmjAlnYMmU8XxvaK0b6lZdA3s1hTmBaBO9+wv+31ulO55oBN4/U8Yldg==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2188,9 +2216,9 @@ } }, "node_modules/@lancedb/lancedb-win32-arm64-msvc": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@lancedb/lancedb-win32-arm64-msvc/-/lancedb-win32-arm64-msvc-0.23.0.tgz", - "integrity": "sha512-OuD1mkrgXvijRlXdbx3LvfuorO04FD5qHegnTOWGXh1sIwwrvvhcJAvXUGBNLY4n/lsWvA+xTjtMwRjUitvPKg==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb-win32-arm64-msvc/-/lancedb-win32-arm64-msvc-0.22.3.tgz", + "integrity": "sha512-E0XywJYnelIe4pzOlvog+aMHKt5ChW27tgmT2V80Z6PXcX6eN9I69Fj0Q6DK6z1YCTPIPu6Na1Hd6d4GqUNKPw==", "cpu": [ "arm64" ], @@ -2204,9 +2232,9 @@ } }, "node_modules/@lancedb/lancedb-win32-x64-msvc": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@lancedb/lancedb-win32-x64-msvc/-/lancedb-win32-x64-msvc-0.23.0.tgz", - "integrity": "sha512-5ve1hvVtp8zWxSE9A+MOQaicXl2Rn0ZG/NUaMTjTD3/CQHPKFmtrqDnM5khoPICTj2O2b10F6mn4cUzl5PASgA==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@lancedb/lancedb-win32-x64-msvc/-/lancedb-win32-x64-msvc-0.22.3.tgz", + "integrity": "sha512-/1feFnjz5MIhzXOEU4+1OeGwpAFYczGfefuOGZRsmGWDdt4V6/fza7Hkkxyb2OnTzqpBfy6BdW2+iBguE1JMyQ==", "cpu": [ "x64" ], @@ -2900,7 +2928,7 @@ "version": "19.2.17", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -4002,7 +4030,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/data-urls": { diff --git a/package.json b/package.json index 012cd2ed..03facbc9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@intrect/openswarm", - "version": "0.24.0", + "version": "0.24.1", "description": "Autonomous AI agent orchestrator — Claude, GPT, Codex, and local models (Ollama/LMStudio/llama.cpp)", "license": "MIT", "type": "module", @@ -50,7 +50,7 @@ "@huggingface/transformers": "^4.2.0", "@inquirer/prompts": "^8.5.2", "@intrect/cxt": "^0.3.0", - "@lancedb/lancedb": "^0.23.0", + "@lancedb/lancedb": "0.22.3", "@linear/sdk": "^19.0.0", "@modelcontextprotocol/sdk": "^1.29.0", "@types/better-sqlite3": "^7.6.13",