Release 0.5.1 - #105
Merged
Merged
Release 0.5.1#105
Conversation
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
…n-forms Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com> # Conflicts: # CHANGELOG.md
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com> # Conflicts: # CHANGELOG.md # FEATURES.md # TEST-PLAN.md
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
QwenCloud publishes an Anthropic-compatible endpoint, so the `claude` binary the image already ships is the harness: same stream protocol, tool loop, approval cards, MCP file transport, CLAUDE.md, skills and cold resume. Add it as a registry adapter rather than a per-channel environment override, because everything the PROVIDER owns differs and must not be inherited. `ANTHROPIC_*` is a reserved prefix for channel secrets precisely because a base-URL override is identity hijack, and every Claude run receives a relay of the operator's own Anthropic access token. So the provider environment is gateway-owned and applied last, after buildClaudeEnv removes the whole Anthropic credential family; a Qwen run with no key, or a rejected one, fails closed naming the remedy instead of answering from the operator's account. The Anthropic-compatible path serves no /v1/models, so discovery reads the account's own list from the sibling /compatible-mode/v1 endpoint derived from the configured base URL, filtered to text models. Claude Code prices every turn with Anthropic's table, which is fiction here, so that figure is dropped at the adapter boundary and the harness declares no rate of its own: tokens are recorded, cost is not invented. The engine is terminal in the failover graph both ways, opt-in (a missing enable entry means off, and the "never lock every harness out" rescue restores the default harnesses only), and cold-only because the warm pool key carries no engine. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
The provider credential and base URL sat inside "Engine & runtime", between the per-engine default models and the reset control, where they read as more Claude/Codex plumbing rather than one harness's own configuration. Move all three Qwen controls into a dedicated card that states the harness is off until switched on and what the credential boundary is. The enable checkbox for an opt-in harness also looked like every other one, so a missing provider key was only discoverable when a run failed in Slack. Annotate it from the settings payload's has*/last4 presence flag, resolved before the toggles paint so a configured key never shows the hint. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
A selected optional MCP server the engine cannot admit safely used to throw
out of run admission and end the whole conversation turn. Refusing to relay a
host credential into a channel container is the property that matters; killing
the turn adds no safety and takes the conversation down with an optional
connector it may not even use.
Claude, Qwen and Codex resolvers now answer { servers, rejected }: a selection
that is missing from the host configuration, needs a host credential, no longer
matches its selected transport, mismatches its own tool namespace, or carries a
reserved name is dropped from that run with a category reason. The drop is not
silent — it is logged as run_mcp_dropped and prefixed to the answer the author
is already getting, on the primary and the failover engine alike. An unreadable
operator configuration now drops every selection for the run instead of
bricking every channel that selected anything.
Also mint the MCP runtime before engineStarted flips, so a mint failure still
drops the session row the turn minted but never used.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
…arseable A Qwen run with no model configured left the choice to the claude CLI, whose default is an Anthropic id that QwenCloud rejects with 400 "Model not exist". The adapter now falls back to the first shipped Qwen model. A gateway refusal of permission_prompt (untrusted API principal, expired capability) returned plain text, which Claude Code reports as an invalid permission result. Those refusals now use the deny decision shape. The tool request stays denied either way. Also replaces a literal NUL byte in the Qwen provider fingerprint with its escape sequence so the source file is plain text. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Tiberiu Socaci <tsocaci@makeitfuture.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promotes
betatomainas the 0.5.1 release candidate.Scope: 45 beta commits — optional Qwen (Claude Code) harness, dropping unusable MCP selections instead of failing turns, admin-only
/sudohost threads, interactive Slack question cards, personal quiet-thread reminders, native Slack image attachments/previews, rclone provisioning, Codex capacity/pricing fixes. The VPN/OpenVPN 3 work already onmain(PR #103) merges with its beta twin; conflicts were limited to CHANGELOG/TEST-PLAN and two test fixtures, resolved to beta's superset with every main-side addition verified present.Local gate on the merge commit:
npm run test:coverage— 2672 pass, 0 fail, 14 skipped (live/browser self-skips); 92.86% linesnpm run check:static— clean (675 files)npm run secret-scan— cleannpm run test:security-coverage— passnpm audit --omit=dev --audit-level=high— pass (one pre-existing moderate advisory)npm run check:dco -- origin/main..HEAD— 23 commits signed offLive acceptance evidence follows in the thread before merge; not to be merged without the owner's confirmation of this exact commit.
🤖 Generated with Claude Code