diff --git a/content/docs/changelog.mdx b/content/docs/changelog.mdx index 9d0bd76..6d0cf7e 100644 --- a/content/docs/changelog.mdx +++ b/content/docs/changelog.mdx @@ -572,563 +572,3 @@ Fly Machines instead of Docker containers or EC2 instances. See the --- _Changelog entries are compiled by the [Documentation Specialist](https://github.com/Molecule-AI) from all merged pull requests for the day. Times are UTC._ -- **OFFSEC-003: workspace-side A2A boundary marker escaping (trust boundary hardening)**: the `tool_delegate_task` workspace tool now wraps delegation output with `_A2A_BOUNDARY_START_ESCAPED` / `_A2A_BOUNDARY_END_ESCAPED` instead of raw markers, preventing raw boundary markers from leaking into output alongside their escaped form. Additionally, responses containing the raw closer `[A2A_RESULT_FROM_PEER]` are now truncated before sanitization β€” so injection of the raw closer cannot be retroactively re-added by the sanitization pass. Together with the platform-side sanitization (shipped 2026-05-11), this closes the full OFFSEC-003 trust-boundary for delegation result delivery. (`molecule-core` [#1073](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1073)) - -### πŸ› Bug fixes - -- **`expandWithEnv` POSIX-identifier guard regression restored**: the same fix as above β€” restores the guard that was removed during a refactor, ensuring invalid shell identifiers in org YAML configs are returned literally instead of being interpreted as environment variable references. (`molecule-core` [#1030](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1030)) -- **Canvas WCAG 1.4.3 contrast ratio fixed for TIER_CONFIG legend**: the tier legend text in the canvas now meets the 4.5:1 contrast ratio required by WCAG 1.4.3 for normal text. (`molecule-core` [#990](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/990)) -- **Canvas focus-visible rings added to icon and text buttons**: focus-visible rings (`focus-visible:ring-2`) now render on icon buttons and text-only buttons in the canvas, restoring WCAG 2.1 AA compliance for all interactive elements. (`molecule-core` [#988](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/988)) -- **OpenClaw template `models` config moved to correct level**: the OpenClaw workspace template's `config.yaml` had `models` at the top level, but the platform template handler reads from `runtime_config.models`. This caused `/templates` to return empty models and providers β†’ a blank "Missing API Keys" dialog with no selectable providers, disabling the Deploy button. Moved all model entries under `runtime_config` and added Groq and OpenRouter as alternative providers alongside OpenAI. (`molecule-ai-workspace-template-openclaw` [#4](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-openclaw/pulls/4)) - -### 🧹 Internal - -- **CI infrastructure improvements** (`molecule-core`): `ci-required-drift` workflow updated with job-level `if:` guards to skip `github.ref`-gated jobs in the merge-queue context; `canvas-build` job now has an explicit 20-minute timeout; gitea merge-queue test mocks updated to match current push-gate behavior. (`molecule-core` [#1029](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1029), [#1006](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1006), [#1035](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1035)) -- **Handler test coverage additions** (`molecule-core`): 60+ new SQL-mock test cases covering `InstructionsHandler`, `ScheduleHandler` (28 cases), and the `expandWithEnv` POSIX guard regression suite. (`molecule-core` [#1030](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1030), [#1005](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1005), [#999](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/999)) - ---- - -## 2026-05-12 - -### πŸ”’ Security - -- **OFFSEC-001: MCP endpoint information disclosure fixed**: the JSON-RPC `-32601` error handler in `mcp.go` was reflecting user-controlled `req.Method` back into the error message. An agent or canvas client sending a crafted `method` field would see that value reflected in the error response. The handler now returns a constant `"method not found"` string, closing the information-disclosure vector. (`molecule-core` [#692](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/692)) - -### πŸ› Bug fixes - -- **Canvas focus-visible regression fixed in FilesTab and BudgetSection**: a regression introduced in recent canvas updates caused focus-visible rings to stop rendering on `FilesTab` and `BudgetSection` components. Restored to full WCAG 2.4.7 compliance β€” keyboard and assistive-technology users see a visible focus indicator on all interactive elements in these panels. (`molecule-core` [#614](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/614)) - -### 🧹 Internal - -- **CI quality hardening** (`molecule-core`): `status-reaper` revised to sweep the last 10 main commits (up from 1) to catch stranded statuses from concurrent workflows; fixed a broken concurrency block that caused duplicate alerts on Gitea 1.22.6. (`molecule-core` [#633](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/633), [#618](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/618)) -- **CI infrastructure fixes** (`molecule-core`): runner label pinned for docker-capable runners in publish workflows; `ubuntu-latest` runner restored after a revert; `sop-tier-check` now gracefully handles empty/invalid tokens in staging; `per-package` diagnostic step added to the publish pipeline; `workflow_run` triggers replaced with `push+paths` across affected workflows for Gitea 1.22.6 compatibility. (`molecule-core` [#636](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/636), [#609](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/609), [#606](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/606), [#694](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/694)) -- **Test coverage additions** (`molecule-core`): 180+ new test cases across canvas, UI, tabs, platform/bundle, and workspace modules β€” covering FilesTab, BudgetSection, NotAvailablePanel, FilesToolbar, KeyValueField, RevealToggle, ValidationHint, getSkills, extractSkills, exporter.go, buildBundleConfigFiles, and a2a_response.py queue envelope. (`molecule-core` [#614](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/614), [#611](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/611), [#629](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/629), [#600](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/600), [#616](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/616), [#592](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/592), [#626](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/626), [#587](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/587), [#621](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/621)) - ---- - -## 2026-05-11 - -### ✨ New features - -- **Delegation results auto-surfaced to agents**: when a `delegate_task` call completes, the results are now automatically injected into the agent's next turn β€” no explicit `check_task_status` call required. This closes the gap where parallel `delegate_task` calls returned after the SDK turn ended and the agent had no way to discover the results. (`molecule-core` [#358](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/358)) -- **`claude_code` runtime support for 4 plugins**: the `audit`, `compliance`, `hitl`, and `security-scan` plugins now include a `claude_code` adapter, resolving the registry gap warning when using Claude Code as the agent runtime with these plugins. (`molecule-ai-plugin-molecule-audit` [#6](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-audit/pulls/6), `molecule-ai-plugin-molecule-compliance` [#6](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-compliance/pulls/6), `molecule-ai-plugin-molecule-hitl` [#6](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-hitl/pulls/6), `molecule-ai-plugin-molecule-security-scan` [#6](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-security-scan/pulls/6)) -- **MCP HTTP/SSE transport improvements**: `a2a_mcp_server.py` now correctly identifies itself as `"molecule"` (was `"a2a-delegation"`), emits SSE heartbeats with `data: null` (was invalid `data: {}`), and only sends a heartbeat when the connection is idle β€” eliminating spurious heartbeat noise on every response. (`molecule-ai-workspace-runtime` [#12](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/12)) - -### πŸ”§ Fixes - -- **Canvas WCAG 2.4.7 focus-visible rings expanded**: focus-visible rings (`focus-visible:ring-2`) have been added to all interactive buttons across 15 canvas components (`AuditTrailPanel`, `MemoryInspectorPanel`, `TemplatePalette`, `CommunicationOverlay`, `ConversationTraceModal`, `ErrorBoundary`, `ExternalConnectModal`, `CreateWorkspaceDialog`, `ProviderModelSelector`, `SidePanel`, `ThemeToggle`, and others). Keyboard and assistive-technology users now see a visible focus indicator on every interactive canvas element. (`molecule-core` [#421](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/421)) -- **OFFSEC-003: delegation result fields sanitized on platform side**: `tool_check_task_status` now calls `sanitize_a2a_result()` on `summary` and `response_preview` fields before embedding them in JSON output β€” both when returning a single delegation by `delegation_id` and when listing all recent delegations. This closes the platform-side half of the OFFSEC-003 trust-boundary fix, ensuring peer-supplied fields are stripped of any boundary markers before reaching callers. (`molecule-core` [#417](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/417), [#416](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/416)) -- **Proxy-path delegation results now visible in delegation list**: when a workspace delegates via `POST /workspaces/:id/a2a` (the A2A proxy path), the result is now correctly stored and returned by `GET /workspaces/:id/delegations`. Previously these rows were logged with the wrong activity type and invisible to the delegation list endpoint β€” callers polling for results would see an incomplete set. The platform-side logging fix (`molecule-core` [#483](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/483)) and the workspace heartbeat fix (`molecule-core` [#501](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/501)) ship together β€” the proxy now writes correct rows, and the heartbeat loop now polls them so agents wake up to consume delegation results without manual `check_task_status` calls. - -- **A2A proxy response header timeout increased**: the platform's A2A proxy `ResponseHeaderTimeout` has been raised from 60 s to 180 s, eliminating premature 504 timeouts on long-running A2A dispatch operations (e.g. agent synthesis, cold-start OAuth flows). The timeout is now also configurable per-deployment via the `A2A_PROXY_RESPONSE_HEADER_TIMEOUT` environment variable. (`molecule-core` [#331](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/331)) -- **A2A push-mode queue response now correctly sets `delivery_mode`**: the A2A response parser now explicitly sets `delivery_mode="push"` on `Queued` variants returned from push-mode workspace queue envelopes. Previously it silently defaulted, causing callers that branch on `v.delivery_mode` to mis-route poll-mode responses as push-mode (and vice versa). (`molecule-core` [#356](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/356)) -- **PLATFORM_URL defaults aligned across runtime modules**: all workspace runtime modules (`a2a_cli.py`, `a2a_client.py`, `a2a_mcp_server.py`, and 10 others) now consistently default `PLATFORM_URL` to `http://host.docker.internal:8080`, eliminating an inconsistency where some modules pointed to `http://platform:8080`. (`molecule-ai-workspace-runtime` [#12](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/12)) -- **MCP server setup command corrected**: the `get_remote_agent_setup_command` tool now emits the correct pip install command (`pip install molecule-ai-sdk` and path `molecule-sdk-python/`) instead of the incorrect `pip install molecule-sdk` / `sdk/python/`. Users following the tool's output will now get a working setup. (`molecule-mcp-server` [#4](https://git.moleculesai.app/molecule-ai/molecule-mcp-server/pulls/4)) -- **CWE-117: log injection vulnerability fixed in workspace stdout/stderr routing**: `_sanitize_for_external()` and the `stderr` parameter have been restored in the workspace executor. This closes the platform-side CWE-117 finding (log injection via unsanitized agent output routed to platform logs or peer A2A responses). Related to the OFFSEC-003 trust-boundary work but is a distinct, standalone fix. (`molecule-core` [#573](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/573)) - -### 🧹 Internal - -- **CI fixes** (`molecule-core`): `publish-runtime.yml` split into two workflows (tags-only publisher + autobump) and a Gitea `workflow_dispatch.inputs` parser bug (causing the workflow to be silently ignored) has been fixed. (`molecule-core` [#349](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/349), [#352](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/352), [#353](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/353)) -- **CI infrastructure improvements** (`molecule-ci`): a graceful runner restart script with unit tests has been added, improving operational reliability of CI runners. (`molecule-ci` [#8](https://git.moleculesai.app/molecule-ai/molecule-ci/pulls/8)) -- **Delegation results sanitization** (`molecule-ai-workspace-runtime`): `read_delegation_results()` now sanitizes content from peer delegation responses before injecting them into the agent context, ensuring trust-boundary markers are stripped before results are surfaced. (`molecule-ai-workspace-runtime` [#13](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/13)) -- **CI migration wave (second pass)**: a second wave of CI workflow renames from `.github/workflows/` to `.gitea/workflows/` completed across `molecule-controlplane`, `molecule-ai-workspace-runtime`, `molecule-sdk-python`, `molecule-mcp-server`, and 12 plugin repos. (`molecule-ai-*` [#various](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/8)) -- **CI policy enforcement** (`molecule-core`): `ci-required-drift` detector (port from `molecule-controlplane#112`) and `audit-force-merge` sidecar reconcile workflow added, implementing RFC [internal#219](https://git.moleculesai.app/molecule-ai/internal/issues/219) Β§4+Β§6 phases. (`molecule-core` [#422](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/422)) -- **`main`-never-red watchdog** (`molecule-core`): new `main-red-watchdog` CI workflow added as a safety net to detect and alert when `main` enters a failing state, complementing the existing `ci-required-drift` policy. (`molecule-core` [#423](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/423)) -- **CI wave three β€” platform + templates** (`molecule-core`, workspace templates): a third CI migration wave completed, porting the `validate` workflow to `.gitea/` + inline form across `molecule-core` (OCI labels + buildx added to publish workflow; `publish-runtime-autobump` fixed for always-skipped bump-and-tag; `all-required` sentinel job added per RFC#219 Phase 4), `molecule-ai-workspace-template-claude-code`, `molecule-ai-workspace-template-hermes`, and `molecule-ai-org-template-molecule-dev`. (`molecule-core` [#559](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/559), [#563](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/563), [#553](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/553), etc.; workspace templates [various CI ports](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-claude-code/pulls/17)) -- **CI quality hardening** (`molecule-core`): `gate-check-v3` received multiple fixes β€” explicit 15 s timeout on HTTP calls, combined-state self-referential fallback removed, token no longer appears in curl argv, checkout now uses base SHA. (`molecule-core` [#604](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/604), [#564](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/564), [#549](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/549), [#556](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/556)) -- **CI policy scope extended** (`molecule-core`): `status-reaper` now compensates for Gitea 1.22.6's hardcoded `-(push)` suffix on schedule-triggered workflow failures; `publish-workspace-server-image` no longer requires `AUTO_SYNC_TOKEN` to be set. (`molecule-core` [#589](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/589), [#572](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/572)) - ---- - -## 2026-05-10 - -### ✨ New features - -- **MCP HTTP/SSE transport for Hermes**: `a2a_mcp_server.py` now speaks HTTP + SSE in addition to stdio, enabling the Hermes runtime to host MCP tools over a network endpoint rather than only via child-process stdio. (`molecule-ai-workspace-runtime` [#5](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/5)) -- **molecule-sdk-python**: `RemoteAgentClient` now accepts `org_id` and `origin` kwargs in its constructor, enabling org-scoped registration and origin tracking from the first handshake. (`molecule-sdk-python` [#7](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/7)) -- **molecule-sdk-python**: `fetch_inbound()` now supports `peer_id` and `before_ts` filter params for targeted message retrieval β€” useful for polling a specific peer's pending tasks. (`molecule-sdk-python` [#6](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/6)) -- **molecule-sdk-python**: new `strip_a2a_boundary()` helper for safely stripping the `[A2A_RESULT_FROM_PEER]` trust-boundary marker from peer A2A responses (OFFSEC-003). Works correctly on both pre- and post-OFFSEC-003 responses. (`molecule-sdk-python` [#8](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/8)) - -### πŸ”§ Fixes - -- **molecule-app**: WCAG 2.4.7 focus-visible rings added to all customer-facing buttons (`ThemeToggle`, `Track-issue Link`, and general CTA buttons) β€” keyboard and assistive-technology users now see a visible focus indicator on every interactive element. (`molecule-app` [#5](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/5), [#9](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/9), [#10](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/10)) -- **status.moleculesai.app aggregator**: the status page's probe result aggregator was rewritten to correctly compute composite uptime across all monitored endpoints β€” resolving false-down alerts caused by a data-structure bug in the previous implementation. (`molecule-ai-status` [#10](https://git.moleculesai.app/molecule-ai/molecule-ai-status/pulls/10)) -- **molecule-sdk-python**: `InboundMessage` now surfaces `peer_name`, `peer_role`, and `agent_card_url` fields, enabling callers to attribute and inspect inbound A2A messages without a separate registry lookup. (`molecule-sdk-python` [#5](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/5)) -- **molecule-cli**: CI test workflow added β€” `molecule ci test` now runs a reproducible test suite against any workspace template. (`molecule-cli` [#3](https://git.moleculesai.app/molecule-ai/molecule-cli/pulls/3)) -- **molecule-ai-workspace-runtime**: `a2a-sdk` dependency pinned to `>=1.0.0` to match the actual code β€” eliminates a version mismatch that caused `AttributeError` on newer SDK builds. (`molecule-ai-workspace-runtime` [#4](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/4)) - -### πŸ“š Docs - -- **molecule-sdk-python**: README API surface additions covering the Phase 30.8 RemoteAgentClient API, including `org_id`, `origin`, `fetch_inbound`, `InboundMessage`, and `strip_a2a_boundary()`. (`molecule-sdk-python` [#4](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/4)) -- **molecule-ai-status**: status page documentation updated to reflect the new Gitea-native uptime probe replacing the Upptime dependency. (`molecule-ai-status` [#4](https://git.moleculesai.app/molecule-ai/molecule-ai-status/pulls/4)) -- **molecule-sdk-python**: `pytest-asyncio` documented as an optional test dependency in `CLAUDE.md`. (`molecule-sdk-python` [#3](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/3)) -- **Remote Workspaces guide**: full `RemoteAgentClient` API reference added to `content/docs/guides/remote-workspaces.md`, covering constructor params, `fetch_inbound()`, `InboundMessage` fields, and the OFFSEC-003 `strip_a2a_boundary()` security section. (`docs` [#13](https://git.moleculesai.app/molecule-ai/docs/pulls/13)) -- **status.moleculesai.app**: status page aggregator fix documented in the changelog. (`docs` [#14](https://git.moleculesai.app/molecule-ai/docs/pulls/14)) - -### 🧹 Internal - -- **CI migration wave**: 22 repos migrated CI workflows from `.github/workflows/` to `.gitea/workflows/` following the GitHub org suspension (post-suspension sweep). Affected repos: `molecule-cli`, `molecule-sdk-python`, `molecule-mcp-server`, and all 21 plugin repos. -- **Plugin hygiene**: 20 plugin repos received `.gitignore` Python-ignores (`__pycache__/`, `*.pyc`) and `__pycache__` directory removal across the plugin ecosystem (`molecule-ai-plugin-*`). -- **Plugin smoke-test suites**: 13 plugin repos (`molecule-ai-plugin-*`) now ship with documented smoke-test suites and coverage rationale READMEs (`tests/README.md`), adding test counts ranging from 21 to 26 tests per plugin. -- **Hook path fixes**: `molecule-ai-plugin-molecule-freeze-scope` and `molecule-ai-plugin-molecule-audit-trail` received `get_repo_root()` layout detection fixes and corresponding test suites. -- **molecule-ai-org-template-molecule-dev**: org-level `initial_prompt` updated from GitHub to Gitea URLs. (`molecule-ai-org-template-molecule-dev` [#8](https://git.moleculesai.app/molecule-ai/molecule-ai-org-template-molecule-dev/pulls/8)) -- **molecule-ai-workspace-template-claude-code**: adapter alias-map now correctly maps `yaml_provider` for runtime-wheel defaults. (`molecule-ai-workspace-template-claude-code` [#12](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-template-claude-code/pulls/12)) -- **molecule-ai-plugin-molecule-careful-bash**: token exfiltration pattern block (OFFSEC-002) now documented in `known-issues.md`. (`molecule-ai-plugin-molecule-careful-bash` [#3](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-careful-bash/pulls/3)) -- **molecule-ci**: 7 reusable workflows ported to `.gitea/workflows/`, and Docker build smoke tests now gracefully skip when the daemon is unavailable. (`molecule-ci` [#6](https://git.moleculesai.app/molecule-ai/molecule-ci/pulls/6), [#7](https://git.moleculesai.app/molecule-ai/molecule-ci/pulls/7)) - ---- - -## 2026-04-23 - -### ✨ New features - -- **SaaS Federation v2 tutorial**: a clean, self-contained walkthrough for platform operators who want to run multi-tenant workspaces from a single control plane. Covers org onboarding via `POST /cp/orgs`, workspace provisioning per tenant, fleet inspection, quota controls, and suspension/teardown. (`molecule-core` [#1700](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1700)) -- **External workspace quickstart**: a 5-minute guide to running any HTTP-speaking agent (Python, Node, Go, Rust) on your own machine and having it appear on the canvas alongside platform-provisioned agents. Covers tunnel setup, `POST /workspaces` registration, and a working echo agent. (`molecule-core` [#1760](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1760)) - -### πŸ”§ Fixes - -- **SSRF guard in SaaS mode**: previously the SSRF protection was blocking all RFC-1918 private IP ranges (`10/8`, `172.16/12`, `192.168/16`) even in SaaS mode β€” this was a regression from the earlier SaaS-mode work. The fix wires up the `saasMode` flag correctly so private IPs are allowed in SaaS deployments (for internal service calls), while metadata ranges (`169.254/16`), CGNAT, loopback, and link-local remain blocked in every mode. IPv6 ULA (`fd00::/8`) handling is also now correct. (`molecule-core` [#1692](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1692)) -- **PUT `/workspaces/:id/files/*path` on SaaS (EC2) workspaces**: fixed a 500 error (`docker not available`) that occurred when saving files from Canvas on SaaS workspaces. The handler now detects non-Docker workspaces via `workspaces.instance_id` and routes writes via EC2 Instance Connect (SSH-backed write with an ephemeral key pair) instead of trying to `docker cp`. (`molecule-core` [#1702](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1702)) - -### πŸ“š Docs - -- **molecli shell completion**: tab completion for `molecule` CLI in bash, zsh, fish, and PowerShell β€” covers all subcommands and flags. (`docs` [#79](https://git.moleculesai.app/molecule-ai/docs/pulls/79)) -- **MCP server structured logging**: `LOG_LEVEL` env var, pino JSON output with AsyncLocalStorage context on every tool call. (`docs` [#78](https://git.moleculesai.app/molecule-ai/docs/pulls/78)) - -### 🧹 Internal - -- SaaS Federation v2 tutorial published β€” clean rewrite of #1613, now with correct HTTP status codes, fleet metrics endpoint, and security model table (`molecule-core` [#1700](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1700)); Files API SSH-backed write path for SaaS EC2 workspaces β€” fixes 500 on PUT `/workspaces/:id/files/*path` for SaaS users (`molecule-core` [#1702](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1702)); Canvas create-workspace dialog now requires hermes runtime model (`molecule-core` [#1714](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1714)). -- EC2 Instance Connect SSH tutorial published (`molecule-core` [#1617](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1617)); AI agent org-scoped key credential model blog published (`molecule-core` [#1614](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1614)); Phase 30 Day 2 social package ready (`molecule-core` [#1662](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1662)). - -### πŸŒ… Late-day updates (17:30–23:50 UTC) - -#### πŸ”’ Security - -- **Cross-tenant memory poisoning fix** (`molecule-core` [#1791](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1791)): fixes a bug where `commit_memory` with `scope=TEAM` could write to a sibling workspace's memory store under high concurrency. `commit_memory` now validates `target_workspace_id` against the caller's known peer set before any write. -- **CWE-78 shell injection hardening** (`molecule-core` [#1885](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1885)): `shellQuote` now uses `strconv.Quote` for all shell-delimited paths in the EC2 Instance Connect and bastion SSH paths. Defense-in-depth layer hardened; primary protection remains path-validation logic upstream. - -#### ✨ New features - -- **A2A priority queue β€” Phase 1** (`molecule-core` [#1892](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1892)): task dispatch now supports a `priority` field (`low` / `normal` / `high` / `urgent`). High/urgent tasks bypass the normal FIFO queue and are dispatched immediately. Phase 2 (priority inversion deadlock prevention) on the roadmap. - -#### πŸ”§ Fixes - -- **A2A queue nil-safe drain** (`molecule-core` [#1893](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1893), [#1896](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1896)): `DequeueTask` no longer panics when the in-memory queue map is uninitialized β€” graceful empty-result returned instead. -- **Workspaces stuck in `provisioning` afterε€±θ΄₯** (`molecule-core` [#1794](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1794)): provisioner now transitions workspaces to `failed` state with a descriptive error message instead of leaving them orphaned in `provisioning`. -- **Dedup settings hooks double-fire** (`molecule-core` [#1797](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1797)): the `dedup_settings_hooks` registry now correctly unsubscribes after one fire β€” eliminates the 3–4Γ— duplicate hook execution observed in CI. -- **Semantic memory search returning stale results** (`molecule-core` [#1778](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1778)): pgvector index now refreshes synchronously on `commit_memory` write instead of on a 5-minute background cycle. -- **pgvector migration race in E2E CI** (`molecule-core` [#1777](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1777)): `CREATE EXTENSION` wrapped in `IF NOT EXISTS` inside a `DO` block β€” eliminates E2E CI flakiness on fresh DB spin-up. -- **EC2 Instance Connect endpoint not found in us-west-2** (`molecule-core` [#1779](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1779)): Instance Connect endpoint SDK call now falls back gracefully to direct SSM session when the EIC endpoint is unavailable in a region. -- **Canvas topology overlay edge labels clipped** (`molecule-core` [#1802](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1802)): SVG edge labels now respect viewport bounds; labels that would render off-screen are repositioned. -- **Audit trail panel not loading for large workspaces** (`molecule-core` [#1854](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1854)): audit log fetch now uses cursor-based pagination (100 events per page) instead of returning all events at once. -- **Hermes `response_format` not forwarded to MiniMax** (`molecule-core` [#1861](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1861)): `response_format=json_schema` now propagates through the model config passthrough for hermes/MiniMax-M2.7-highspeed workspaces. -- **Memory Inspector panel memory leak** (`molecule-core` [#1871](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1871)): `useMemoryStore` hook now correctly cancels the SSE subscription on panel unmount. -- **Token revocation cache stale-read window** (`molecule-core` [#1888](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1888)): revoked-token invalidation now propagates within 5 s (down from 60 s) β€” closes the window where a revoked token could still authenticate. -- **TenantGuard same-origin bypass (regression)** (`molecule-core` [#1898](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1898)): fixes a regression introduced in the Phase 33 cloudflare-removal change that re-opened the TenantGuard same-origin bypass for EC2 tenant Canvas deployments. - -#### πŸ“š Docs - -- **Chrome DevTools MCP tutorial** (`docs` [#1798](https://git.moleculesai.app/molecule-ai/docs/pulls/1798)): hands-on guide for debugging Molecule AI agents in-browser using Chrome's built-in MCP inspector. -- **Phase 34 launch page** (`docs` [#1799](https://git.moleculesai.app/molecule-ai/docs/pulls/1799)): public-facing launch collateral for GA scheduled 2026-04-30. -- **Tool Trace demo environment** (`docs` [#1844](https://git.moleculesai.app/molecule-ai/docs/pulls/1844)): interactive demo showing the tool trace inspector in action, with sample run data. -- **Enterprise battlecard** (`docs` [#1864](https://git.moleculesai.app/molecule-ai/docs/pulls/1864)): competitive positioning doc for sales and enterprise evaluation teams. - -#### 🧹 Internal - -- `a2a-sdk` hot-pinned to `0.3.x` across all workspace template repos (`molecule-core` [#1890](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1890)); SDK upgrade path documented in `KI-009` (`internal` [#1631](https://git.moleculesai.app/molecule-ai/internal/issues/1631)). -- Phase 34 CI matrix expanded to cover Node 22 and Go 1.24 (`molecule-ci`). - -#### πŸ”§ Runtime fixes - -- **Heartbeat 401 retry** (`molecule-ai-workspace-runtime` [#40](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/40)): heartbeat worker now retries with fresh token on 401 before declaring the workspace unreachable β€” eliminates false `disconnected` status during token rotation. -- **LLM token auto-detect** (`molecule-ai-workspace-runtime` [#38](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/38)): hermes runtime now auto-detects `max_tokens` from model context window and request timeout when not explicitly configured. - ---- - - - - - - -## 2026-05-10 - -### ✨ New features - -- **A2A priority queue β€” Phase 1**: task dispatch now supports a `priority` field (`low` / `normal` / `high` / `urgent`). High/urgent tasks bypass the normal FIFO queue and are dispatched immediately. (`molecule-core` [#225](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/225)) -- **Plugin drift detector + queue + admin apply endpoint**: a new plugin drift detection system monitors loaded plugins against their pinned SHAs and surfaces drift via a queue; admins can review and apply corrections via a new `/admin/plugin-apply` endpoint. (`molecule-core` [#204](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/204)) -- **workspace-server pre-restart A2A drain signal**: the workspace-server now sends a pre-restart A2A drain signal before restarting, allowing peer workspaces to gracefully drain pending tasks instead of timing out. (`molecule-core` [#207](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/207)) -- **Admin auth runbook**: new `admin-auth.md` runbook documents the test-token route lockdown and `AdminAuth` middleware behaviour for operators. (`molecule-core` [#220](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/220)) -- **Static `.github-token` fallback to git credential helper**: workspace-server now falls back to a static `.github-token` value when no git credential helper is configured, enabling simpler air-gapped setups. (`molecule-core` [#219](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/219)) -- **Keyboard shortcuts in Toolbar help dialog**: all keyboard shortcuts are now documented in a Toolbar help dialog accessible from the canvas top bar. (`molecule-core` [#244](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/244)) -- **HTTP/SSE transport for Hermes MCP**: `a2a_mcp_server.py` now exposes `--transport=http --port=` for Hermes workspaces that prefer HTTP + SSE over stdio. Endpoints: `POST /mcp` (JSON-RPC), `GET /mcp/stream` (SSE), `GET /health`. (`molecule-ai-workspace-runtime` [#5](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/5)) -- **RemoteAgentClient `org_id` and `origin` kwargs**: `RemoteAgentClient` now accepts `org_id` (injected as `X-Molecule-Org-Id` header) and `origin` (injected as `Origin` header for request tracing) as constructor kwargs. Both propagate to all 14+ outbound call sites automatically via `_auth_headers()`. (`molecule-sdk-python` [#7](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/7)) -- **RemoteAgentClient `fetch_inbound()` filter params**: `fetch_inbound()` now accepts `peer_id` (narrow to a specific peer's messages) and `before_ts` (RFC3339 timestamp for cursor-based pagination). Enables agents to selectively consume inbound activity from known siblings. (`molecule-sdk-python` [#6](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/6)) -- **InboundMessage enrichment fields**: `InboundMessage` now exposes typed `peer_name`, `peer_role`, and `agent_card_url` attributes, surfaced from the platform's peer registry at dispatch time. Previously these were only accessible via the raw channel envelope. (`molecule-sdk-python` [#5](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/5)) -- **`strip_a2a_boundary()` β€” OFFSEC-003 trust-boundary SDK helper**: `molecule-sdk-python` now exports `strip_a2a_boundary(text)` to strip `[A2A_RESULT_FROM_PEER]...[/A2A_RESULT_FROM_PEER]` wrappers from peer-generated content. The platform wraps all external-peer responses in these markers so agents know not to re-inject the content as platform-native output. Safe on pre-OFFSEC-003 responses (returns input unchanged when markers absent) and on `None`/empty strings. (`molecule-sdk-python` [#8](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/pulls/8)) - -### πŸ”§ Fixes - -- **Canvas accessibility β€” WCAG 2.4.7 focus-visible rings (batch 2)**: `focus-visible` keyboard rings added to 9 customer-facing buttons across molecule-app β€” SignInButton on the landing page, "Request access" on the waitlist page, "+ New Workspace" CTA and Notifications bell in the app shell, "Try again" on error boundaries, "Sign out" in the header, the "I agree" button on terms-gate, and "Manage keys on canvas" in the API tokens view. ARIA attributes (`aria-current`, `aria-label`, `aria-busy`) also corrected on the billing view PlanCard and portal buttons. All rings use semantic color tokens β€” no hardcoded hex colors. (`molecule-app` [#5](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/5)) -- **Canvas accessibility β€” WCAG 2.4.7 ThemeToggle focus ring**: `focus-visible` keyboard ring added to the three theme-preference radio buttons (Light / System / Dark) in `ThemeToggle`, fixing WCAG 2.4.7 for the theme switcher. (`molecule-app` [#10](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/10)) -- **Canvas accessibility β€” WCAG 2.4.7 NotImplementedState focus ring**: `focus-visible` keyboard ring added to the "Track issue #N" link in `NotImplementedState`, completing the WCAG 2.4.7 focus-visible ring coverage across all customer-facing interactive elements. (`molecule-app` [#9](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/9)) -- **SSRF validation before writing external workspace URL**: the workspace handler now validates URLs against SSRF allowlists before writing external workspace configurations. (`molecule-core` [#221](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/221)) -- **Dockerfile tenant chown /org-templates**: `/org-templates` directory now correctly chowned to the canvas user to fix `EACCES` on `mkdir` for external resolvers. (`molecule-core` [#223](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/223)) -- **CI `ghcr` β†’ `ECR` migration + POST route smoke tests**: canary-verify workflow migrated from GHCR to ECR; new POST route smoke tests added for deployment verification. (`molecule-core` [#217](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/217)) -- **CI `dorny/paths-filter` β†’ shell-based git diff**: replaced `dorny/paths-filter` with shell-based git diff for Gitea Actions compatibility. (`molecule-core` [#208](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/208)) -- **SOP tier-check clause splitter strips newlines**: the SOP tier-check script's clause splitter now correctly preserves newlines, fixing every `tier:low` PR CI failure. (`molecule-core` [#243](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/243)) -- **SOP tier-check APPROVER_TEAMS pattern matching**: outer quotes removed from case patterns in `APPROVER_TEAMS` matching logic, fixing approval team resolution. (`molecule-core` [#231](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/231)) -- **CI port `publish-workspace-server-image.yml` to `.gitea/workflows/`**: `publish-workspace-server-image.yml` migrated from `.github/workflows/` to `.gitea/workflows/` for Gitea Actions parity. (`molecule-core` [#237](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/237)) -- **CI port `publish-runtime.yml` to `.gitea/workflows/`**: `publish-runtime.yml` migrated from `.github/workflows/` to `.gitea/workflows/` for Gitea Actions parity. (`molecule-core` [#211](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/211)) -- **Docker base image digests pinned**: base image digests pinned in all Dockerfiles to ensure reproducible builds and prevent unexpected base image updates. (`molecule-core` [#199](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/199)) -- **KeyboardShortcutsDialog corrected**: keyboard shortcuts dialog text corrected and min-clamp test expectations fixed. (`molecule-core` [#200](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/200)) -- **`MODEL_PROVIDER` env var deprecated**: the `MODEL_PROVIDER` env var was misnamed β€” it carried the model ID (e.g. `claude-opus-4-7`) despite its name, and was being misused as a runtime selector. The runtime now accepts `MODEL` and `MOLECULE_MODEL` as the canonical env var for model selection. `MODEL_PROVIDER` still works but emits a deprecation warning. (`molecule-core` [#280](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/280)) -- **`delegate_task` self-delegation guard**: calling `delegate_task` with your own workspace ID now returns an early actionable error instead of deadlocking the task lock. Previously self-delegation would hold `_run_lock`, timeout after 30 s, and waste the turn. (`molecule-core` [#291](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/291)) -- **status.moleculesai.app false "down" reports fixed**: the custom uptime-probe binary correctly writes raw JSONL results but the aggregator step β€” which renders `history/.yml` and `history/summary.json` in Upptime format β€” was not migrated when the probe moved from Upptime to the custom binary post-2026-05-06. The missing aggregator caused `status.moleculesai.app` to show false-positive outages for Canvas and other endpoints. Resolved by adding the probe result aggregator. (`molecule-ai-status` [#10](https://git.moleculesai.app/molecule-ai/molecule-ai-status/pulls/10)) - -### πŸ“š Docs - -- **Canvas known issues section cleaned up**: duplicate entries removed from known issues; pre-commit action link fixed. (`molecule-core` [#202](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/202)) -- **Canvas controls section corrected**: Canvas Controls section corrected to reflect current keyboard navigation and MiniMap state. (`molecule-core` [#201](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/201)) - -### 🧹 Internal - -- **SOP tier-check AND-composition of required team approvals per tier**: tier-check now enforces AND-composition of required team approvals per tier (`tier:high`). (`molecule-core` [#225](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/225)) -- **Canvas structural tests for TIER_CONFIG and COMM_TYPE_LABELS**: structural tests added for canvas TIER_CONFIG and COMM_TYPE_LABELS constants. (`molecule-core` [#245](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/245)) - - -## 2026-05-09 - -### ✨ New features - -- **Keyboard-accessible canvas node resize**: Cmd/Ctrl+Arrow keys now resize canvas nodes in the topology view, satisfying WCAG AA keyboard navigation requirements. (`molecule-core` [#192](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/192)) -- **Keyboard-accessible edge anchors**: Enter/Space on an edge now selects the anchor for keyboard-based topology editing. (`molecule-core` [#190](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/190)) - -### πŸ”§ Fixes - -- **Handlers auto-restart workspace after file write/delete/replace**: file mutations via the Canvas editor now correctly trigger workspace restart, ensuring the agent picks up the new file state without manual intervention. (`molecule-core` [#188](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/188)) -- **CI `gh api` β†’ Gitea API migration**: all GitHub Actions `gh api` calls replaced with Gitea-compatible alternatives β€” CI now runs cleanly in Gitea Actions without GitHub dependency. (`molecule-core` [#191](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/191)) -- **WCAG AA contrast fix + KeyboardShortcutsDialog improvements**: toolbar contrast ratios corrected for WCAG AA compliance; keyboard shortcuts dialog now scrolls properly on small viewports. (`molecule-core` [#198](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/198)) - -### πŸ“š Docs - -- **Canvas accessibility audit β€” all gaps now closed**: the accessibility audit doc updated to reflect fully closed status. (`molecule-core` [#197](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/197)) -- **Canvas controls section corrected**: keyboard accessibility and MiniMap presence now correctly documented. (`molecule-core` [#201](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/201)) -- **Stale audit doc text fixed**: stale text from PR #182 corrected in canvas audit documentation. (`molecule-core` [#187](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/187)) - -### 🧹 Internal - -- **gh-identity module path migration**: `github.com/Molecule-AI/gh-identity` imports migrated to `git.moleculesai.app/molecule-ai/gh-identity` across all workspace templates. (`molecule-core` [#189](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/189)) -- **Pending uploads test isolation fix**: sweeper test isolation corrected β€” eliminates cross-test pollution in CI. (`molecule-core` [#185](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/185)) -- **Poll error counter to 0 before assert**: RecordsMetricsOnSuccess now polls error counter to 0 before asserting, eliminating flaky E2E test failures. (`molecule-core` [#194](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/194)) - ---- - -## 2026-05-08 - -### πŸ”§ Fixes - -- **molecule-app CI testTimeout bumped to 20s**: vitest `testTimeout` increased to 20 s to handle shared act_runner load on the molecule-app repo. (`molecule-app` [#4](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/4)) -- **molecule-app drops staging branch β€” trunk-based migration**: first repo of the trunk-based development migration; staging branch removed. (`molecule-app` [#3](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/3)) -- **docs CI switches to ubuntu-latest**: docs repo CI now uses `ubuntu-latest` now that the repo is public. (`docs` [#4](https://git.moleculesai.app/molecule-ai/docs/pulls/4)) - ---- - -## 2026-05-07 - -### πŸ“š Docs - -- **Install guide β€” GitHub.com refs β†’ Gitea**: all active `github.com/Molecule-AI` references migrated to `git.moleculesai.app/molecule-ai` in the installation docs. (`docs` #1) -- **Website github.com β†’ Gitea link migration**: `molecules-market` website links updated to point at Gitea. (`landingpage` #3) -- **molecule-monorepo β†’ molecule-core rename (Phase 4)**: landingpage follow-up renaming of `molecule-monorepo` to `molecule-core` in all cross-repo references. (`landingpage` #4) -- **CI lowercase 'molecule-ai/' in cross-repo workflow refs**: cross-repo workflow references now consistently lowercase for Gitea Actions compatibility. (`landingpage` #2) -- **Market Purchase button on tier cards**: demo Mock #1 β€” Purchase button now appears on tier cards in the molecules-market. (`landingpage` #5) - -### πŸ”§ Fixes - -- **molecule-app runs-on ubuntu-latest**: Hetzner runner labels post-suspension; CI now uses `ubuntu-latest`. (`molecule-app` [#1](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/1)) -- **molecule-app GitHub β†’ Gitea URL migration**: all `github.com/Molecule-AI` references migrated to `git.moleculesai.app/molecule-ai` in molecule-app. (`molecule-app` [#2](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/2)) -- **docs GitHub β†’ Gitea URL migration**: `github.com/Molecule-AI` references migrated to Gitea across docs repo. (`docs` [#3](https://git.moleculesai.app/molecule-ai/docs/pulls/3)) - ---- - -## 2026-05-06 - -### 🧹 Internal - -- **molecule-core org-wide Gitea URL migration**: all `github.com/Molecule-AI` references migrated to `git.moleculesai.app/molecule-ai` across all repos in the org. (`molecule-core`) -- **Hetzner act-runner suspension**: CI runners updated to use `ubuntu-latest` labels following Hetzner act-runner suspension. (`molecule-app` [#1](https://git.moleculesai.app/molecule-ai/molecule-app/pulls/1)) - ---- - -## 2026-04-22 - -### ✨ New features - -#### Workspace model propagation β€” hermes MiniMax flow -Customer selects `model=minimax/MiniMax-M2.7-highspeed` in Canvas β†’ the model and -API key now propagate correctly into the runtime environment instead of being dropped -on the floor at provisioning time. Works for hermes workspaces in both hosted SaaS -and self-hosted EC2 deployments. -(`molecule-core` [#1685](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1685)) - -#### EC2 Instance Connect Endpoint β€” one-click shell from Canvas -Canvas Terminal tab now uses AWS EC2 Instance Connect Endpoint to open a PTY inside -any workspace EC2 instance β€” no SSH keys to manage, no IP to copy, no security group -rules to configure. IAM policy gates access, STS pushes a short-lived key that -auto-expires, and every tunnel open is recorded in CloudTrail. -See the [EC2 Instance Connect guide](/docs/infra/workspace-terminal). -(`molecule-core` [#1554](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1554)) - -#### Phase 33 β€” Cloudflare Tunnel replaced with direct-connect public IPs -Cloud-hosted workspaces no longer route through `cloudflared`. Each workspace gets -its own public IP from the VPC subnet and connects directly to the platform over -TLS on port 443. Reduces latency by ~20–40 ms (region-dependent), removes the -Cloudflare egress cost dependency, and enables direct `curl` debugging without -the tunnel path. -See the [migration blog post](/blog/cloudflare-tunnel-migration). -(`molecule-core` [#1612](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1612)) - -### πŸ”’ Security - -- **F1085 deleteViaEphemeral**: `rm` scope restricted to `/configs` volume only β€” - prevents deletion of application code or workspace files if the exec form is - exploited. Applied to both `main` and `staging`. (`molecule-core` [#1682](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1682), [#1616](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1616)) - -### πŸ”§ Fixes - -- Canvas now fetches the runtime and model dropdown from the `/templates` registry - at load time β€” runtime list stays current without code deploys. (`molecule-core` [#1666](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1666)) -- Canvas accessibility: `aria-hidden` correctly applied to decorative SVGs; - `MissingKeysModal` now uses correct dialog semantics and manages focus. (`molecule-core` [#1594](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1594)) -- Provisioner pulls workspace template images from GHCR instead of Docker Hub - for faster cold starts and reduced third-party dependency. (`molecule-core` [#1624](https://git.moleculesai.app/molecule-ai/molecule-core/pulls/1624)) -- Shared runtime heartbeat no longer leaves workspaces in a phantom-busy state after - task completion. (`molecule-ai-workspace-runtime` [#37](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pulls/37)) - -### πŸ“š Docs - -- **MCP server structured logging**: `LOG_LEVEL` env var (`trace`/`debug`/`info`/`warn`/`error`/`fatal`), - pino JSON output in production, pretty-print in development, AsyncLocalStorage - context on every log entry (tool name, request ID, workspace ID). (`docs` [#78](https://git.moleculesai.app/molecule-ai/docs/pulls/78)) -- **molecli shell completion**: tab completion for `molecule` CLI in bash, zsh, fish, - and PowerShell β€” covers all subcommands and flags. (`docs` [#79](https://git.moleculesai.app/molecule-ai/docs/pulls/79)) - -### 🧹 Internal - -- 34 internal changes across `molecule-core`, `molecule-ci`, and template repos: - CI workflow migration to `ubuntu-latest`, security patch backports (CWE-22/CWE-78), - Go build fixes, canvas Dockerfile GID fix, Go linter upgrades, duplicate-symbol - resolution, and reusable `publish-template-image` workflow for all workspace template - repos. (`molecule-core`, `molecule-ci`) - ---- - - - -## 2026-04-17 - -A high-velocity day: 80+ PRs merged across platform, canvas, runtimes, security, and channels. - -### ✨ New features - -#### opencode Integration β€” MCP bridge for AI coding agents -Connect [opencode](https://opencode.ai) to any Molecule AI workspace over a -standard `Authorization: Bearer` remote MCP connection. opencode gains the full -A2A tool surface (`delegate_task`, `list_peers`, `recall_memory`, and more) -via two transports: Streamable HTTP (`POST /workspaces/:id/mcp`) and SSE -(backwards-compat `GET /workspaces/:id/mcp/stream`). Rate-limited to 120 req/min -per token. See the [opencode Integration guide](/docs/opencode). -(#840, #842) - -#### Slack β€” per-agent identity with Bot Token mode -The Slack channel adapter now supports dual-mode outbound: **Bot Token** (new, -recommended) and Incoming Webhook (legacy, unchanged). With a `bot_token` each -workspace posts under its own display name and icon via `chat:write.customize`. -Markdown is automatically converted to Slack `mrkdwn` format. -See [Channels](/docs/channels). -(#844, #851) - -#### AG-UI compatible SSE endpoint -New `GET /workspaces/:id/events` endpoint streams agent events as AG-UI -compatible Server-Sent Events. Enables AG-UI frontend integrations to subscribe -to live workspace activity without polling. -(#601) - -#### A2A topology overlay on the canvas -The canvas now renders a live A2A topology overlay β€” every workspace as a node, -every in-flight delegation as an animated directed edge. Zoom to team, click any -edge to inspect the task payload. -(#751) - -#### Audit trail visualisation panel -A new audit trail panel in the canvas surfaces the HMAC-SHA256 immutable event -log per workspace β€” every task received, LLM call, and completion in -chronological order with chain-of-custody verification. -(#651, #759) - -#### Workspace hibernation β€” auto-pause idle workspaces -Workspaces that receive no tasks for `HIBERNATION_IDLE_MINUTES` (default: 30) -are automatically hibernated (containers paused, resources freed). They -auto-wake on the next inbound task with full state restored. Manage via -`POST /workspaces/:id/hibernate` and `POST /workspaces/:id/wake`. -See [API Reference](/docs/api-reference). -(#724) - -#### Temporal workflow checkpoints β€” step-level persistence -Workspace templates now persist intermediate workflow steps to the database. -On container restart (crash, deploy, hibernate/wake) the workspace resumes from -the last completed step rather than restarting the whole task. Step endpoints -documented in the [API Reference](/docs/api-reference). -(#797, #803) - -#### Semantic memory search -Agent memory is now vector-indexed via pgvector. `recall_memory` accepts an -optional `?q=` parameter for semantic (embedding) search in addition to exact -keyword match. Nearest-neighbour results are ranked by cosine similarity and -colour-coded in the canvas Memory Inspector. -(#784, #787) - -#### Memory Inspector panel -A new canvas panel lets you browse, search, and inspect all `LOCAL` and `TEAM` -memory keys for any workspace β€” live, without leaving the canvas. -(#738) - -#### Hermes β€” stacked system messages -The Hermes runtime now accepts a `system_blocks` list: each block (persona, -tools, reasoning policy) is merged in order rather than overwriting the previous -system prompt. Enables persona stacking for complex multi-role workflows. -See [API Reference](/docs/api-reference) β†’ Runtimes section. -(#655, #798) - -#### Hermes β€” native `tools` parameter -Hermes passes tools to the model via the native `tools=[]` API parameter instead -of text-in-prompt injection. Structured tool definitions, better token efficiency, -and full compatibility with Nous/Hermes-3 tool call format. -(#644) - -#### Hermes β€” structured output (`response_format`) -`response_format=json_schema` is now wired through to the model. Hermes -workspaces can request strict JSON output against a defined schema. -(#645) - -#### AGENTS.md auto-generation -Platform workspaces now auto-generate an `AGENTS.md` file in the workspace -container at boot. The file lists all peer workspaces visible to this workspace, -their roles, and their capabilities β€” giving LLMs automatic context about the -org topology without manual prompt engineering. -(#763) - -#### Discord channel adapter -A new Discord adapter joins Telegram, Slack, and Lark. Configure with a -`bot_token` and `channel_id` to send and receive messages on Discord. -(#656) - -#### Per-workspace budget limits -Set a `budget_limit` (USD) on any workspace. The A2A executor enforces the limit -at task dispatch β€” tasks that would exceed the monthly cap are rejected with a -`429 Budget Exceeded` error. Configure via `PATCH /workspaces/:id`. -(#611, #606) - -#### Per-workspace token metrics -`GET /workspaces/:id/metrics` returns token counts (input, output, cache read/write) -aggregated over rolling 1-hour and 30-day windows. Live usage is displayed in the -canvas WorkspaceUsage panel. -(#602, #627) - -#### Claude Opus 4.7 β€” effort levels and task budget -Workspace config now exposes `effort` (`low` / `medium` / `high` / `xhigh` / -`max`) and `task_budget` (token ceiling) for Anthropic Claude workspaces. -`xhigh` and `max` activate extended thinking (Opus 4.7+ only). Configure in the -Canvas Config tab or via `PATCH /workspaces/:id`. -(#639, #654, #669) - -#### Plugin supply-chain hardening -All plugin refs must now be pinned (no `latest`, no floating branches). Unpinned -refs are blocked at load time unless `PLUGIN_ALLOW_UNPINNED=true`. SHA-256 -integrity checking available for plugin archives. -(#775) - -#### Org-level plugin governance registry -A new per-org allowlist controls which plugins workspaces in that org are -permitted to load. Managed via `POST/DELETE /admin/orgs/:orgId/plugins/allowlist`. -(#610) - -#### Schedule health endpoint -`GET /admin/schedules/health` returns cross-workspace cron health: last-fired, -next-scheduled, consecutive-empty count, and phantom detection status for every -schedule in the org. -(#671, #796) - -#### Fly Machines provisioner -The platform now supports `PROVISIONER=flyio` β€” workspaces are provisioned as -Fly Machines instead of Docker containers or EC2 instances. See the -[self-hosting guide](/docs/self-hosting). -(#578 β€” docs PR #7) - -### πŸ”’ Security - -- **Auth hardening** β€” PATCH `/workspaces/:id` now requires ownership - validation; UUID fields are validated before DB queries; input lengths bounded - across all handlers. (#692, #701) -- **Admin token isolation** β€” `AdminAuth` middleware correctly rejects workspace - bearer tokens when `ADMIN_TOKEN` is set, preventing privilege escalation from - workspace token β†’ admin. (#684, #729) -- **Metrics route auth** β€” `GET /workspaces/:id/metrics` now requires workspace - bearer token; previously it was unauthenticated. (#696) -- **X-Workspace-ID forgery** β€” Requests spoofing the `system-caller/` prefix in - `X-Workspace-ID` headers are rejected. (#766) -- **GLOBAL memory injection safeguards** β€” `commit_memory` with `scope: GLOBAL` - now validates content for prompt injection patterns before persisting. (#769) -- **Security headers** β€” `X-Content-Type-Options: nosniff` and - `X-Frame-Options: DENY` added to all API responses. (#629) -- **Token revocation hardening** β€” Revoked tokens are purged from the in-memory - cache within 60s; previously the cache could serve revoked tokens until TTL - expiry. (#696) -- **MCP server** β€” npm version pinned; `-y` flag removed from install commands. - (SAFE-MCP NEW-003, #808 β€” docs PR #18) -- **Canvas test-token endpoint** β€” gated behind `AdminAuth` and removed from - general router. (#612, #708) - -### πŸ”§ Fixes - -- Fixed `POST /workspaces` not persisting the secrets envelope on create. (#568) -- Fixed self-delegation deadlock when a workspace delegates to itself. (#570) -- Fixed GitHub installation token expiry β€” tokens now refresh automatically before - expiry rather than failing mid-operation. (#567) -- Fixed `TenantGuard` same-origin bypass for EC2 tenant Canvas. (#584) -- Fixed pgvector migration to wrap in `DO` block, eliminating E2E CI failures - from duplicate extension install. (#843, #670, #636) -- Fixed scheduler dropping schedules with `NULL next_run_at` permanently. (#728) -- Fixed `ValidateToken` not checking `removed` workspace status, allowing tokens - for deleted workspaces to authenticate. (#719) -- Fixed canvas hydration error UI, radio keyboard nav, and zoom-to-team - shortcut. (#565) -- Fixed canvas UX: error handling, accessibility, loading state. (#587) -- Fixed canvas deploy preflight to require env keys for Hermes and Gemini CLI - runtimes. (#588) -- Fixed budget/spend counters capping before DB upsert to prevent NUMERIC - overflow. (#630, #634) -- Fixed pgvector TEXTβ†’UUID FK type mismatch in migrations 028 and 031 that - blocked all E2E runs. (#646, #670, #843) -- Fixed duplicate hook firings (3–4Γ—) in `dedup_settings_hooks`. (#551, #597) -- Accessibility fixes: keyboard access on `TeamMemberChip`, `role=alert` on - status banners, close button label, `ProvisioningTimeout` modal. (#841) - -### πŸ“š Docs - -- Google ADK runtime β€” added hands-on Quickstart section. (docs PR #8) -- Hermes β€” full runtime reference page. (docs PR #9) -- AGENTS.md β€” auto-generation documented in concepts. (docs PR #10) -- Semantic memory search β€” `?q=` param documented in API reference. (docs PR #11) -- Canvas A2A topology overlay + audit trail panel. (docs PR #12) -- molecule-medo plugin β€” opt-in platform plugin page. (docs PR #13) -- Workspace hibernation β€” status lifecycle, endpoints, auto-wake behaviour. (docs PR #14) -- molecule-audit-ledger β€” HMAC chain, `/audit` endpoint, `LedgerHooks`, CLI. (docs PR #15) -- Hermes stacked system messages β€” `system_blocks` kwarg. (docs PR #16) -- Plugin supply chain security β€” pinned refs required, SHA-256 integrity. (docs PR #17) -- SAFE-MCP audit report 2026-04-17. (docs PR #18) -- Temporal workflow checkpoints β€” step endpoints, auto-resume behaviour. (docs PR #19) - ---- - -_Changelog entries are compiled by the [Documentation Specialist](https://github.com/Molecule-AI) from all merged pull requests for the day. Times are UTC._