Releases: BourbonDog/amicus
Release list
v4.5.1
What's Changed
Bug Fixes
-
Electron validation in MCP launch path:
amicus doctornow validates Electron in the actual install that MCP councils run from, not just the doctor's own copy. This fixes the green-while-broken blind spot where doctor reported "Electron: ok" whileui: trueruns failed withelectron-absent. The fix enumerates running, global, and npx-cache installs and probes each through a dual-root resolver that accounts for npm's different nesting strategies across install types. -
Electron state distinction: Split the
electron-absentreason into two cases.electron-absentnow means the electron package was never installed (possibly intentional for headless-only setups), while the newelectron-broken: binary missing under <dir>covers the package-present-but-binary-missing state from interrupted postinstalls or AV quarantine. The broken state names the exact directory and points users toamicus doctor --fixfor automated repair.
Full Changelog: v4.5.0...v4.5.1
v4.5.0
What's Changed
Policy Packs
- Save and reuse run configurations:
amicus pack save <name> --kind council|fanout|solo [flags]captures your bench, chair, critic/lenses, options, and briefing template as a reusable JSON file. Load it with--pack <name>on any run, and explicit flags always override the pack's values. Packs are recorded on the run metadata either way, so you always know which configuration was used. - Pack management commands:
amicus pack list,pack show <name>, andpack rm <name>help you organize saved packs.--from-run <id>builds a pack from a run you already liked instead of typing flags manually. - MCP pack semantics: On
amicus_start,amicus_fanout, andamicus_council_runover MCP, packs resolve in-process without forwarding to child processes. Special handling formaxCostandtemplateensures they apply correctly even on the MCP path, and any pack field with no MCP destination surfaces as an explicit notice so nothing silently disappears. - Council packs reject invalid fields:
agent,thinking, andsummaryLengthare now rejected on council packs withPACK_INVALID, since the council engine hard-codes these values and ignores pack values anyway. They remain valid on fanout and solo packs.
Briefing Templates
- Render
{{variable}}templates before sending:--template <name|path>with optional--artifact <file>and repeatable--var k=vrenders a Markdown briefing with known variables like{{prompt}},{{artifact}},{{date}}, and{{project}}. Templates live in~/.config/amicus/templates/, and a user template shadows a built-in of the same name. - Strict template rendering: Unknown variables, missing data, or unused
--varvalues all fail withTEMPLATE_RENDERrather than silently dropping data, catching mistakes early. - Template library management:
amicus template listandtemplate show <name>inspect saved templates. v4.5 ships one built-in,review. On MCP, a pack'sbriefing.templateis the only way to reach a template since the tools have no template param of their own.
Council Workspace Auto-Open
- GUI launches automatically on MCP council runs from Claude Code (local): When
amicus_council_runis invoked from Claude Code (local), the Electron workspace window now opens automatically after the run starts, eliminating the need for a separateamicus watch <runId> --uicall. Decision order respects explicituiparams, hard guards (no Electron, noDISPLAY), and the newworkspace.autoOpenconfig key. - Workspace auto-open configuration: A new
workspace.autoOpenkey inconfig.json(default on) lets you opt out. The MCP response includesworkspaceOpened: booleanandworkspaceOpenReasonwhen it did not open, so callers know why.
Council Run Observability
- Dropped members are now recorded and surfaced: When a preset member's alias no longer resolves or has fallen out of the model catalog,
run.jsonnow carries an additivedroppedMembers: [{member, reason}]array. The--jsonenvelope andamicus_council_runMCP response include this for scripted callers, andamicus council show <name>reports the identical resolved/dropped split as a preview before you spend. - Pack-attributed errors are clear: When a pre-flight error names a value the pack supplied, the message adds
(set by pack '<name>')so pack-caused failures are never mistaken for typos in your own flags.
Workspace Rendering Fixes
- Blind-mode toggle no longer collapses open panels or repaints twice: Toggling blind mid-run now updates in place and paints once, preserving the open/loaded state of lazy-loaded prose panels instead of closing them.
- Artifact name collisions no longer misattribute prose: Two models whose sanitized filenames collide (e.g.,
vendor/aandvendor?aboth becomingvendor-a) now get deterministic suffixes (~2,~3), and the workspace consults the collision map on every lookup instead of showing the wrong model's text. - Seat rows reorder to match the composed run:
renderSeatsnow moves existing rows into place on every render, fixing the frozen row order that occurred when a repair solo or new wave changed the underlying leg order mid-run. - Failed council seats no longer render as perpetually live: A shared-server early return bypassed the terminal
progress.jsonwrite, leaving a stage marked in-progress. Terminal-write logic is now centralized inwriteTerminalProgressSafe, called at all early-return sites.
Config and Validation
- Pack validation on save and load: Packs are validated when saved (hard-fail with
PACK_INVALIDfor any fatal issues, warnings to stderr) and again on every use.pack shownever fails on an invalid pack, only reports what's wrong. - Pack precedence is explicit: Everywhere a pack applies, resolution order is flag > pack > config default > built-in default, so explicit command-line flags always win and packs only fill in what you didn't say.
- Schema normalization: Five v4.3-era schemas now use the raw-file
$idconvention, and a newschemas/pack.schema.jsondocuments all 19 schemas in the repo.
MCP Improvements
- MCP schemas reflect actual defaults:
amicus_startandamicus_fanoutno longer declare JSON-Schema defaults foragent,noUi, orincludeContext, keeping schema metadata honest while defaults are still applied at the same read sites. - Pack child pid pre-seed on fanout: The fanout wave pre-seeds pack-related child process metadata so deaths are reapable, even before pack-using child processes are created.
CLI and Tooling
- Template and pack CLI handlers: New
amicus templateandamicus packcommand trees, with full coverage of list/show/save/rm operations and robust error handling. - Explicit-flag precedence in parseArgs: The CLI's argument parser now records explicitly-typed keys for pack merge precedence, so flags always beat pack defaults.
Docs and Reference
- Comprehensive usage documentation: Policy packs, briefing templates, and auto-open are fully documented in
docs/usage.md,docs/configuration.md, anddocs/council.md. - Implementation plan captured:
docs/superpowers/plans/2026-07-27-v4.5-save-and-share.mddetails the 23-task implementation, with dispositions for all open items tabled in the design spec.
Full Changelog: v4.4.1...v4.5.0
v4.4.1
What's Changed
Critical Fixes
-
Fence extraction now parses correctly: The closing-fence pattern was unanchored, causing the first triple-backtick inside a JSON body to end the match. This truncated reviews of markdown across three of four seats on a paid council, losing 15 of 17 findings. The extractor now enumerates every fenced opener independently and lets
JSON.parsearbitrate, with the last valid parse winning. -
Council runs no longer race for OpenCode's database: Previous versions spawned 10+ OpenCode servers per run, causing concurrent database lock failures. A run now acquires one shared server for all stages, falling back to per-wave servers only if the shared acquisition fails. Lock-class failures retry up to 3 times over 750ms, eliminating the coin-flip behavior that made
--criticunreliable. -
Repair path now carries the artifact being repaired: Judge, chair, defense and re-vote repair prompts omitted the text they were asked to fix, forcing models to correct something they had never seen. All repair calls now embed the original artifact verbatim, tracked across attempts so errors and context always describe the same generation.
Behavior Changes
-
Empty findings are now valid: A review with zero findings but a non-empty
overallstatement now passes validation. This removes the structural pressure that forced models to invent findings, contradicting the shipped anti-sycophancy clause. An all-clean bench degrades gracefully, with judges and chairs stating the empty index rather than rendering headings over nothing. -
Tool-settle grace ceiling now aborts OpenCode sessions: Legs exceeding the ceiling previously completed but left their sessions running and billing for unread output. Sessions are now aborted after child-session walk (preserving cost attribution) and before server close, with
toolSettleAbortedrecorded astrueorfalseto signal success or failure. -
Inexact totals under a cost ceiling now exit with code 2: A fully-unpriced council under
--max-costpreviously exited 0 despite being unable to enforce the ceiling. Runs with inexact totals now exit 2 when a ceiling is set, matching the degraded path used for budget refusals. The ceiling still only bounds known spend and never blocks a run.
Correctness Improvements
-
Cache-only legs report unknown cost instead of false zero: Observations with only cache tokens (no input/output tokens) previously resolved to
estimated $0.0000, the exact false zero the release exists to eliminate. They now correctly report asunknown. -
Failed legs no longer show green checks: Seats that errored or timed out could display completion indicators because
timed-outwas missing from terminal-state lists. The terminal-state handling is now symmetric, with failed legs writing terminal progress records instead of leaving stale ones. -
Permission failures no longer masquerade as missing: Unreadable run artifacts were indistinguishable from ones the run had not produced, causing silent chairless folds reporting
{ok: true}. Readers now surface the actual permission error instead of silently succeeding. -
Stage-1 waves that die before launching now degrade loudly: Waves failing before their legs started wrote no
wave.json, making failure indistinguishable from "not reported yet". Such waves now degrade the run loudly with a clear error. -
Spend ledger now matches council run output:
amicus spendwas reporting exact totals thatcouncil runcalled inexact, due to unattributable subtree rows being priced instead of flagged. Rows are now marked asunattributedSubtreeRowsalongsideunpricedRows, and the unknown-spend notice re-announces on a growing count instead of sticking after the first occurrence.
Workspace & UI
-
Markdown renderer robustness improved: The workspace renderer no longer re-slices input on every inline token, eliminating a V8 string-representation dependency. Heading text is trimmed to remove trailing blanks, and an unreachable heading-level clamp is removed with a guard ensuring future widening fails loudly.
-
Workspace read-only invariant is now enforced: The workspace's promise never to write into run directories is now verified by AST parsing rather than assertion, checking that no write API appears in the code and that the registered IPC channel set is exactly the seven known channels.
-
Workspace markdown renderer certified by paid council: The component responsible for converting another model's prose into DOM was previously uncertified. A paid council reviewed it and found no exploitable DOM injection or prototype pollution, with certification recorded and adversarial coverage pinned.
Documentation & Installation
-
Documentation now ships with npm installs: The package previously excluded
docs/entirely, making troubleshooting text unreachable when users need it most. The 15 top-leveldocs/*.mdfiles now ship withnpm i -g amicus, though larger assets like images remain unshipped for size efficiency. -
Haiku alias diagnosis corrected: The hard-404 failures were attributed to a bad model ID, but the real cause is a missing
/v1suffix inANTHROPIC_BASE_URL. Documented correctly as an environment misconfiguration rather than a broken alias. -
Cost cliff terminology clarified: Documentation now correctly states that
--max-costbounds known spend only, and cost source glyphs no longer redundantly repeat "estimated" or "unknown" in adjacent text.
Tooling & Environment
-
Electron/workspace-ui linting enabled with pragmatic scope: The workspace UI now runs under the lint gate with ESLint config added for browser environment. 265 errors were resolved; 159
vardeclarations are deferred to a post-release rewrite since the renderer ships raw under CSP with no build step. -
Line endings normalized repo-wide: All text files now normalize to LF in both object database and working tree, fixing an issue where core.autocrlf caused lint-staged to fail on stashed files. Executable shebangs remain unbroken across platforms by using
eol=lfuniversally. -
Integration suite timer cleared: The live rail integration test no longer leaks SIGKILL escalation timers, allowing the CDP suite to properly release the event loop.
Testing
-
Live test suite now passes end to end: The free-local
$0path and the full end-to-end flow are now verified, clearing the live rail green. -
Fixture path resolution corrected: Fence test fixtures now resolve paths correctly so SEC-3's assertion sees one breach instead of two.
Full Changelog: v4.4.0...v4.4.1
v4.4.0
What's Changed
Features
- Council Workspace GUI: A new third Electron mode (
amicus watch <councilRunId> --ui) that visualizes council runs with live reviewer progress, anonymized peer packets, tier-colored adjudication matrix with dissent drill-in, chair verdict, and cost-by-seat gauges. Historical runs render entirely from disk; live runs poll every 1.5s when focused, 5s otherwise. Includes blind-mode toggle (labels vs. model names) and two verbs: Abort (confirm-gated, delegates to engine) and Fold (writes verdict to terminal). - Per-seat live status in terminal:
amicus watch <councilRunId>now displays per-leg rows in the terminal with model, role, status, message count, tokens, cost, and stall state, refreshed on the same poll cadence as the stage rail. - Live data factory and workspace CDP suite: Added
CdpClient.workspace(port)for e2e testing of the Workspace GUI with fixture-driven test coverage.
Bug Fixes
- Zero-cost reporting now reports unknown cost: Legs where all captured token totals were zero used to report
estimated $0.0000(claiming the work was free). They now report asunknowncost instead. Four separate defects fixed: token-gated cost resolution, post-loop usage re-poll to close a 155ms window before legalization, terminal progress records carrying settled usage, and spend ledger no longer coercing null costs into measured$0.0000. - Legs no longer marked complete while sessions are still billing: A leg was declared complete on initial reasoning preamble before tool calls finished. Root cause was shape drift: OpenCode emits no
tool_resultparts (only 36tool_userecords across 35 legs, zerotool_result). Tool-call liveness now keys on SDK's realstate.statusvocabulary (pending/running/completed/error), with a bounded grace period (AMICUS_TOOL_SETTLE_GRACE_MS, default 300s) before forcing completion. - costExact predicate now accurate: Was claiming exactness when every leg reported tokens but missing unattributed child-session spend. A leg that spawns a subagent now carries
subtreeUnknown;costExactrequires both every leg observed and no unattributed subtree. - Max-cost ceiling now threaded into council pre-flight:
--max-costwas never passed to the transport, so the soft ceiling was inert for council runs. Each wave is now measured against remaining allowance (ceiling minus known spend minus outstanding reservations), with atomic claims so concurrent waves cannot both spend the same dollars. If a wave is refused, the run continues with a partial bench; the refusal is announced, recorded onrun.json, and degrades exit code to 2. - Usage-settle re-poll boundary expanded: The try/catch covered only network reads; inspection afterward could throw and destroy a finished leg. The boundary now covers the entire loop body.
- Environment number parsing honors explicit zero:
AMICUS_USAGE_SETTLE_POLLS=0and three companion knobs were silently rewritten to defaults. All four now go throughenvNumber()which honors explicit numeric values including 0. - Subagent (child-session) spend now attributed: Child OpenCode sessions spawned by
tasktool calls were invisible to totals. Measured across four recorded runs: $0.492506 missing. The engine now walks each leg's child sessions at finalization (bounded, cycle-proof, directory-scoped) and rolls the measured spend into run total ascost.subtreeCost/cost.subtreeSessions. - Stage-1 repair re-prompt carries the review it repairs: When a review's findings JSON failed validation, a repair re-prompt was launched solo without the review text. Three paid councils burned seats on models that refused to repair empty context. The prompt now embeds the original review verbatim (or the previous repair output on second attempt), and explicitly instructs the model to emit empty findings if there genuinely is no prior text.
- Council pointer files now fenced against directory traversal: A tampered
council-<runId>.jsonpointer could redirect reads (or writes via crash detection and abort) outside the project. All pointer-consuming surfaces now resolve and check containment before touching the filesystem, using a shared fence implementation (path-fence.js). A fenced-out pointer returns the existing "not a council run" error.
Changed
- Unknown cost is visible, never hidden: A leg whose cost cannot be determined no longer halts the run or trips
--max-costby itself. Instead, the uncertainty is impossible to miss:run.jsongainsunknownLegs+costExact, the council emits aNotice:naming the count, the human summary appends+ N leg(s) unknown,amicus spendshows unpriced rows explicitly, and the workspace budget gauge switches to indeterminate (hatched) with a≥readout.
Security
- Path containment fencing for council pointers: Council pointer files (
council-<runId>.json) are now validated for realpath containment before any filesystem access, preventing directory traversal attacks on reads or writes.
Full Changelog: v4.3.0...v4.4.0
v4.3.0
What's Changed
Observability Data Layer
- Live run monitoring: New
amicus watch <id>command renders any fan-out wave, council run, or session from any terminal — displays as an in-place table on TTY, milestone lines with--plain, or NDJSON with--json. Polling-based architecture (no push/IPC) reads from three new file surfaces that every consumer shares. - Event streaming:
--followflag onfanoutandcouncil runstreams milestone events to stderr as they happen, while keeping stdout byte-identical. On council runs, tracks the run's own lifecycle and stage boundaries without exposing internal per-leg events. - Completion hooks: New
--on-completeflag runs a shell command or triggers an MCP notification when a wave or council run reaches a terminal state. Payload carries only identifiers and paths (never model-generated text), runs exit-isolated from the underlying task, and includes 8 environment variables for scripting. - Schemas and validation: Published
event.schema.json,progress.schema.json, and newlivevariants (wave-live,run-live,council-run-live) document the data layer contract; all changes are additive within existing v2 envelope versions.
Failed-Leg Resilience
- Retry-failed waves:
fanout --retry-failed <waveId>relaunches only a wave's terminal, non-complete legs as a new linked wave, preserving each leg's saved context. Original wave is never touched; retry is byte-identical to the original attempt. - Cheaper-model fallback chains: New
--fallback/--no-fallbackflags enable optional per-leg substitution to a cheaper model from the same vendor tier, triggered only by classified rate-limit or overload failures (never timeout or auth). Fallback events, attempt tracking, and final substitution details are recorded loudly in the output. - Error classification: New
classifyLegError()utility distinguishes retryable capacity signals from permanent failures, enabling smarter recovery strategies across providers and gateways.
Spend Visibility and Attribution
- Complete ledger attribution:
continue,resume, and council rows now recorded in the spend ledger with full context (op, status, waveId, councilRunId, councilName, project, gateway, fallback/retry linkage). Pre-v4.3 rows lacking status are never counted as failures. - Rich spend query surface:
amicus spendnow supports--wave,--council,--project,--model,--op,--failedfilters and--group-bybucketing (model, wave, council, project, op, day). New--rowsflag shows individual ledger rows;wastedrollup counts failed attempts and incomplete runs. - MCP spend tool: New 16th MCP tool
amicus_spendmirrors the CLI query surface for headless/automation consumers, read-only with no side effects.
Council Run Improvements
- Stage-level spend attribution: Council legs and chair solos are now attributed with their parent
councilRunId, stage op, and council name, enabling cost-per-stage analysis and per-reviewer seat accounting. - Wave linkage for retries: Council fan-out stages can now retry failed legs via the new wave linkage, inheriting the same fallback and partial-spend tracking as fanout waves.
Infrastructure and Testing
- Schema coverage: Added comprehensive test suites for observability schemas, spend ledger fields, error classification, and fallback chain derivation. Event emission and tail reading verified end-to-end in council and fanout contexts.
- File size discipline: New pure-logic modules (
src/observe/,src/sidecar/fallback-chains.js,src/sidecar/fanout-retry.js) extracted to keepfanout.js,run.js, and core sidecar files under 300-line gates. - No new dependencies: All observability, retry, and spend query logic implemented with existing Node.js and devDependencies (no new runtime deps;
ajvreused from v4.0).
Full Changelog: v4.2.1...v4.3.0
v4.2.1
What's Changed
Security
.envkey writes now sanitize CR/LF and re-assert0600permissions: Provider keys and local-provider bearers are stripped of stray carriage returns and newlines before persisting, preventing truncation or file corruption. File permissions are re-asserted on every write to re-tighten secrets files created under loose umasks.
Fixes
- Global hermetic test baseline prevents accidental config pollution: A new setup hook pins the unit test suite's config and keys directories to per-worker scratch locations, ensuring no test can read or modify your real
~/.config/amicuscredentials. - Removed redundant credential file re-read: Eliminated an unnecessary second load of the
.envfile in the credential loader, reducing I/O and simplifying the code path.
Documentation
- Claude Desktop now listed as fully supported: Updated client support matrix to reflect that Claude Desktop is tested and supported alongside Claude Code CLI and Claude Cowork.
Full Changelog: v4.2.0...v4.2.1
v4.2.0
What's Changed
Features
- Local and OpenAI-compatible providers at $0: Run Ollama, LM Studio, vLLM, or any OpenAI-compatible endpoint as a first-class model source with
amicus provider add. Supportsprovider list|test|remove, all with--jsonoutput. Local models price at an explicit $0 tier, so budget gates and the default-model picker treat them as free. - Local inference completes instead of hanging: Local provider blocks now carry a 5-minute engine request timeout and a non-empty apiKey, so
amicus start,fanout, andcouncilagainst local servers complete successfully. Local models need about 32k context loaded (LM Studio's 16k default is insufficient) and are slower to first token (30-90s cold prefill is normal). - Bearer management for local providers:
amicus key <localId> <token>manages a local provider's bearer token, stored securely in the 0600.envfile rather than config.json. Local providers without a configured bearer use a placeholder instead. - amicus init for on-demand registration: Re-run skill install and MCP registration with
amicus init [--claude] [--desktop] [--json]for plugin-channel installs, failed postinstalls, or repairing deleted~/.claudestate. - Local provider reachability checks: The
amicus doctorcommand gains alocal-providerscheck (warn, never error) that validates configured local endpoints are reachable, plus a compact summary line when all checks pass. - Setup wizard support for local providers: Both the readline wizard and Electron GUI now offer to add a local provider during setup, with preset shortcuts for Ollama, LM Studio, and vLLM.
Improvements
- Flexible local endpoint configuration: Configure local providers with preset shortcuts (
--preset ollama|lmstudio|vllm) or explicit--urlfor any OpenAI-compatible endpoint. Optional bearer tokens and custom pricing are supported. - Per-flavor local provider hints: Route errors now include flavor-specific hints when a local provider is unreachable or missing a key, guiding users to provider-specific troubleshooting.
- Council respects local provider availability: Council members using local providers are never dropped from a bench on catalog absence, preserving them when the server is temporarily down so the actual error (unreachable) bubbles up at runtime.
- Local models excluded from network refresh filter: Local-only catalog rows no longer clobber a good OpenRouter cache during an offline refresh, keeping the two data sources cleanly separated.
- Landing page highlights local and headless modes: The website now foregrounds the three ways to run the council (Claude session, headless CI, local models) and emphasizes $0 local inference.
- Documentation and troubleshooting updates: Expanded docs cover local provider setup, honest expectations for local model performance, and updated troubleshooting checklist to reflect actual amicus doctor checks.
Infrastructure
- New CLI handler for provider management:
src/cli-handlers-provider.jsimplementsamicus provider add|list|test|removewith dependency injection for testability, mirroring the pattern used by doctor checks. - Split route-suggestions module: Extracted
buildSuggestionslogic into a newsrc/utils/route-suggestions.jsto keeproute-launch.jsunder the 300-line gate while adding local provider wiring. - Separate env-var store for local bearers: Created
src/utils/env-raw-store.jsto handle arbitrary environment variable writes to the.envfile, keepingapi-key-store.jsfocused and under size limits. - Local provider merge layer: New
src/utils/local-providers.jsprovidesgetLocalProviders(), bearer derivation, validation, and preset definitions as a single source of truth for provider configuration. - Scheme-aware local probing: New
src/utils/local-probe.jsimplements secure HTTP/HTTPS probing with redirect rejection, header redaction, and configurable timeouts for local endpoint reachability and model discovery. - Test coverage for local workflows: Added 15+ new test files covering local provider e2e, setup flows, routing, pricing, and error handling to verify the full local provider pipeline.
Full Changelog: v4.1.2...v4.2.0
v4.1.2
What's Changed
Bug Fixes
- Claude model aliases no longer drift between direct API and OpenRouter: OpenRouter and Anthropic's direct API spell Claude models differently (e.g.,
anthropic/claude-opus-4.8vsanthropic/claude-opus-4-8). Three code paths were deriving the OpenRouter version by prefix-stripping, which only works when the rest of the ID is identical. For Claude, this produced invalid OpenRouter IDs while dropping the correct ones, causing fresh setups to report stale aliases and shared servers to lose fallback routes. All paths now read each gateway's authored route instead of deriving one from the other, and user overrides are left untouched rather than inheriting curated routes.
Documentation
- Added v4.2 planning notes on call-site discovery: Documented a new task to hunt for unconsidered code paths that modify functions in the plan, including a table of known gaps for v4.1.2 baseline.
Full Changelog: v4.1.1...v4.1.2
v4.1.1
What's Changed
Bug Fixes
-
Integration tests now watched and passing: The integration tier had been completely unreachable from every gate, causing six E2E tests to fail unnoticed behind a dead
gemini-flashmodel alias. These tests now point to the livegeminialias and run in CI via a new keyless wrapper that guarantees no credentials leak and no money is spent. -
Claude review reports no longer show blank judge columns: The
--claude-reviewreport was incorrectly including Claude in the adjudication judge matrix even though Claude is only judged, never judges. This resulted in a blank column (or a false self-vote marker) in the report matrix. The judge roster is now filtered independently from the council roster. -
Debate-revote stage now correctly reports skipped status: When the re-vote wave never launches (nothing was defended or cost ceiling was hit), the stage was incorrectly marked
completeinstead ofskipped. This is now a consumer-visiblerun.jsonchange that correctly reflects the actual stage state. -
Report HTML files now written with secure permissions:
amicus council verdict --rendernow writesreport.htmlwith0o600permissions instead of falling back to the process umask, matching all other artifact writers and preventing unintended world-readability of model output. -
Removed false CLI
waitcommand documentation: Both docs and help text claimedamicus wait <councilRunId>existed as a CLI command when it does not. Users are now directed to the MCPamicus_waittool instead, which is the actual blocking primitive. -
Report matrix no longer grows Claude column: Fixed
toModel()in report generation reusing the street-cred universe as the judge roster, which incorrectly included Claude and created blank or misleading columns in the adjudication matrix. -
Model alias defaults now derive from live gateway routes: The
amicus doctorcommand and CI model-drift checks were incorrectly reporting shipped default aliases as stale due to using hand-stripped OpenRouter IDs instead of routed direct forms. Defaults now come fromtoGatewayRoutes()and match their authored direct forms when available. -
Keyless integration wrapper sandboxes all credential-path roots: The previous version only sandboxed
HOME/USERPROFILE, leavingXDG_DATA_HOMEandAPPDATAopen as escape hatches for credentials. The wrapper now sandboxes all credential-path roots simultaneously.
Features
-
Free keyless integration testing in CI: A new
integrationjob in.github/workflows/ci.ymlruns the integration tier on every push and PR with all credentials scrubbed, catching regressions at zero cost and ensuring the tier is permanently watched.npm run test:integrationguarantees no credentials leak by repointingHOME,USERPROFILE,XDG_DATA_HOME,XDG_CONFIG_HOME, andAPPDATAinto an empty sandbox before spawning jest. -
Paid integration tier split to on-demand workflow:
npm run test:integration:liveand.github/workflows/integration-live.ymlisolate the money-spending E2E suites to a manually dispatched workflow, preventing accidental billing and ensuring the keyless tier stays genuinely free.
Changed
- Curated
geminialias now points to Gemini 3.6 Flash: The defaultgeminialias moves from Gemini 3.5 Flash to Gemini 3.6 Flash on both gateways. This is a silent model change: users with nogeminioverride will start talking to a newer underlying model on next use after upgrading.
Documentation
-
Testing guide clarified for keyless and paid tiers: Updated
docs/testing.md,CLAUDE.md, andCONTRIBUTING.mdto explain the two-rail integration strategy, why the pre-push hook intentionally runs unit tests only, and which CI workflows run which tier at what cost. -
Release checklist now requires both integration rails: The publishing checklist in
docs/publishing.mdnow requires runningnpm run test:integration(free keyless) andnpm run test:integration:live(paid) before release, since keyless skips the money-spending suites entirely. -
Future plans flagged for de-rotting: v4.5, v4.6, and v4.7 implementation plans now include rotation warnings and guidance for re-grounding against merged main before execution.
Full Changelog: v4.1.0...v4.1.1
v4.1.0
What's Changed
Features
- Headless debate mode:
amicus council run --debateadds a Stage-2.5 rebuttal round where findings that landed Contested or Disputed are sent back to their raisers for defense/amendment/withdrawal, then disputing judges re-vote. The engine runs exactly one round with no edge back into debate, and withdrawn findings are auto-recorded denied at Stage 4. - Claude's own review as council input:
--claude-review <file>enters Claude's review directly without launching a model leg, allowing Claude to participate in judgment without being promoted to chair or asked to defend in debate mode. - Skill fast path on the engine:
skills/second-opinion/SKILL.mdnow delegates Stages 1-3 and Stage-5 artifact generation to a singleamicus council runinvocation, leaving only the human decision stages (0 intake, 4 decisions, 6 lessons) for Claude orchestration. Manual mechanics are preserved in the newMANUAL-ORCHESTRATION.mdfallback. - Refresh HTML reports after Stage 4:
amicus council verdict --renderandamicus_verdictwithrender:truenow re-renderreport.htmlfrom the decided verdict instead of keeping the engine's pre-decision snapshot, so opened reports show the actual decisions made. - Disable cost gates globally:
--no-cost-gateoncouncil rundisables per-leg price enforcement for the entire run (repairs, chair chain, debate legs) instead of requiring per-invocation flags.
Bug Fixes
- Council Review Action bench now viable: The default models changed from
deepseek,gemini,glmwith deepseek chair (leaving only 2 seats, the minimum) toglm,qwen,minimax,qwen-coderwith deepseek chair, providing real quorum slack so one stalled leg doesn't fail the review. postinstallnow copies SEAT-BRIEFS.md: The seat briefing reference shipped in the tarball but was never installed to~/.claude/skills/second-opinion/, so it has been missing from every installation until now.- Chair verdict no longer discarded on
council verdict: Writing the decided verdict was droppingoverallVerdictbecause tally records don't carry it. The command now recovers it from the run folder'sverdict.json(with runId guard against foreign files) or re-parses the chair's markdown, preserving the chair's judgment across stages. - Cowork path recovers chair verdict:
amicus_verdictgains an explicit optionaloverallVerdictinput and no longer discards the chair's output on the Cowork path.
Documentation
- Stage 4 and 5 now specify where finding claims live: Both stages previously pointed only at
tally.jsonfor claim text, but claims actually live intally-input.json. The join (on findingid) is now spelled explicitly in both stages. - README and help text updated for new modes: Council mode description,
commands/council.md, and CLI usage now document debate mode and Claude-review input.
Configuration
- Council Review Action debate input:
.github/workflows/council-review.ymlgains adebatetoggle (default off) and--debateflag wiring, plus withdrawn-finding exclusion from PR annotations and a collapsible "Withdrawn in debate" section in the report.
Full Changelog: v4.0.1...v4.1.0