From 5429880b6782abfcfbce22acdf637f66e7f8a3a7 Mon Sep 17 00:00:00 2001
From: Hongming Wang
Date: Mon, 13 Apr 2026 17:46:28 -0700
Subject: [PATCH] docs: sync documentation with 2026-04-13 merges (PRs #1-#8)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Covers today's quality + infra pass: brand/structural cleanup, MCP
per-domain refactor (1697 -> 89 lines, 87 tools), canvas ConfirmDialog
unification, 4 platform handler decompositions (+47 Go tests), E2E
hardening for Phase 30.1/30.6 auth, and two new CI jobs (e2e-api +
shellcheck).
- CLAUDE.md: updated test counts (Go 536, canvas 357, SDK 121, MCP 97,
workspace 1084); documented MCP per-domain split + new api.ts; added
handler-decomposition section; Phase 30.1/30.6 auth callout; new
CI jobs; env vars cross-ref.
- PLAN.md: Phase 31 "Quality + Infra Pass" marked shipped; test totals
refreshed to 2,295.
- README.zh-CN.md: license badge MIT -> BSL 1.1; added BSL license block.
- docs/api-protocol/platform-api.md: registry table gains Auth column
documenting Phase 30.1 bearer-token and Phase 30.6 X-Workspace-ID
requirements on heartbeat/update-card/discover/peers.
- docs/development/local-development.md: updated stale test counts;
added e2e-api + shellcheck CI jobs; pointer to new testing-e2e.md.
- docs/development/testing-e2e.md: new — per-script reference, auth
prerequisites, local run, CI coverage, adding-a-new-check checklist.
- docs/edit-history/2026-04-13.md: top-of-file summary section added
spanning PRs #1-#8; preserves existing per-feature entries below.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
CLAUDE.md | 38 ++++++---
PLAN.md | 27 +++++--
README.zh-CN.md | 6 +-
docs/api-protocol/platform-api.md | 18 +++--
docs/development/local-development.md | 21 +++--
docs/development/testing-e2e.md | 68 ++++++++++++++++
docs/edit-history/2026-04-13.md | 112 ++++++++++++++++++++++++++
7 files changed, 257 insertions(+), 33 deletions(-)
create mode 100644 docs/development/testing-e2e.md
diff --git a/CLAUDE.md b/CLAUDE.md
index c6d163fb..83377d9c 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -56,6 +56,8 @@ Must run from `platform/` directory (not repo root). Env vars: `DATABASE_URL`, `
See `docs/plugins/sources.md` for the two-axis source/shape plugin model.
+Additional env vars documented in `.env.example` (2026-04-13 sync — all 21 distinct `os.Getenv`/`envx.*` keys now documented): `MOLECULE_ENV`, `GITHUB_WEBHOOK_SECRET`, `MOLECULE_URL` (MCP server target; same semantic as `PLATFORM_URL`).
+
`molecli` reads `MOLECLI_URL` (default http://localhost:8080) to locate the platform. Logs are written to `molecli.log` in the working directory (already covered by `*.log` in `.gitignore`).
### Canvas (Next.js)
@@ -108,20 +110,23 @@ OPENAI_API_KEY=... bash scripts/test-team-e2e.sh # E2E: Multi-template
### Unit Tests
```bash
-cd platform && go test -race ./... # 487 Go tests (handlers, registry, provisioner, CLI, delegation, org, channels, wsauth — sqlmock + miniredis)
-cd canvas && npm test # 352 Vitest tests (store, components, hydration, buildTree, secrets API, org template import)
-cd workspace-template && python -m pytest -v # 1078 pytest tests (adds platform_auth token store for Phase 30.1)
-cd sdk/python && python -m pytest -v # 87 SDK tests (agentskills.io spec validator, CLI, AgentskillsAdaptor round-trip, workspace/org/channel validators)
+cd platform && go test -race ./... # 536 Go tests (handlers, registry, provisioner, CLI, delegation, org, channels, wsauth — sqlmock + miniredis; +47 on 2026-04-13 covering extracted helpers from the a2a_proxy / delegation / discovery / activity refactor)
+cd canvas && npm test # 357 Vitest tests (store, components, hydration, buildTree, secrets API, org template import, ConfirmDialog singleButton + 7 native-dialog replacements)
+cd workspace-template && python -m pytest -v # 1084 pytest tests (adds platform_auth token store for Phase 30.1, memory_write activity logging)
+cd sdk/python && python -m pytest -v # 121 SDK tests (agentskills.io spec validator, CLI, AgentskillsAdaptor round-trip, workspace/org/channel validators, RemoteAgentClient Phase 30 flows)
+cd mcp-server && npm test # 97 Jest tests (per-domain tool modules + smoke test on tool count)
```
### Integration Tests
```bash
-bash tests/e2e/test_api.sh # 62 API tests against localhost:8080
+bash tests/e2e/test_api.sh # 62 API tests against localhost:8080 (Phase 30.1 bearer-token auth aware; shellcheck-clean; also runs in CI `e2e-api` job)
bash tests/e2e/test_a2a_e2e.sh # 22 A2A end-to-end tests (requires 2 online agents)
-bash tests/e2e/test_activity_e2e.sh # 25 activity/task E2E tests (requires 1 online agent)
-bash tests/e2e/test_comprehensive_e2e.sh # 68 checks — ALL endpoints, memory, runtime, bundles, approvals
+bash tests/e2e/test_activity_e2e.sh # 25 activity/task E2E tests (requires 1 online agent; re-registers detected agent to capture bearer token)
+bash tests/e2e/test_comprehensive_e2e.sh # 67 checks — ALL endpoints, memory, runtime, bundles, approvals (registers workspaces immediately after create to beat the provisioner token race)
```
-`test_api.sh` requires platform running. Tests full CRUD, registry, heartbeat, discovery, peers, access control, events, degraded/recovery lifecycle, activity logging, current task tracking, bundle round-trip (export → delete → import → verify).
+All five E2E scripts share `tests/e2e/_lib.sh` + `tests/e2e/_extract_token.py` helpers and are shellcheck-clean. `test_api.sh` is the quick local-verify command — use it after any platform change. Tests full CRUD, registry, heartbeat, discovery, peers, access control, events, degraded/recovery lifecycle, activity logging, current task tracking, bundle round-trip (export → delete → import → verify).
+
+**Phase 30.1 / 30.6 auth callout (future-proofing):** `/registry/heartbeat` and `/registry/update-card` require `Authorization: Bearer ` once a workspace has any live token on file (Phase 30.1 — legacy workspaces grandfathered). `/registry/discover/:id` and `/registry/:id/peers` additionally require `X-Workspace-ID` + bearer token on the caller side (Phase 30.6 — fail-open on DB hiccup since hierarchy check is primary). If you change these routes, update `tests/e2e/test_api.sh` and `docs/api-protocol/platform-api.md` in the same PR.
`test_a2a_e2e.sh` requires platform + two provisioned agents (Echo Agent, SEO Agent) running with a valid `OPENROUTER_API_KEY`. Tests message/send, JSON-RPC wrapping, error handling, peer discovery, agent cards, heartbeat. Timeout configurable via `A2A_TIMEOUT` env var (default 120s).
@@ -133,14 +138,18 @@ cd mcp-server
npm install && npm run build # Build MCP server
node dist/index.js # Run (stdio transport)
```
-Exposes 87 tools for managing Molecule AI from Claude Code, Cursor, Codex, or any MCP client. Includes workspace CRUD, async delegation, plugins (install/uninstall/list), global secrets, pause/resume, org import, A2A chat, approvals, memory, files, config, discovery, bundles, templates, traces, activity logs, and social channels (add/update/remove/send/test). Configured in `.mcp.json`. Env: `MOLECULE_URL` (default http://localhost:8080).
+Exposes **87 tools** for managing Molecule AI from Claude Code, Cursor, Codex, or any MCP client. Includes workspace CRUD, async delegation, plugins (install/uninstall/list), global secrets, pause/resume, org import, A2A chat, approvals, memory, files, config, discovery, bundles, templates, traces, activity logs, remote agents (Phase 30), and social channels (add/update/remove/send/test). Configured in `.mcp.json`. Env: `MOLECULE_URL` (default http://localhost:8080).
+
+**Structure (refactored 2026-04-13, PRs #2/#4/#7):** `src/index.ts` shrank from 1697 → 89 lines and now only wires `createServer()`. Per-domain tool modules live in `src/tools/`: `workspaces.ts`, `agents.ts`, `secrets.ts`, `files.ts`, `memory.ts`, `plugins.ts`, `channels.ts`, `delegation.ts`, `schedules.ts`, `approvals.ts`, `discovery.ts`, `remote_agents.ts`. Each exports its handlers and a `registerXxxTools(srv)` function. Shared HTTP layer in `src/api.ts` (`PLATFORM_URL`, `apiCall`, `ApiError`, `isApiError()`, `toMcpResult()`, `toMcpText()`). When adding a tool, pick the matching domain file or create a new one and wire it in `createServer()`.
### CI Pipeline
GitHub Actions (`.github/workflows/ci.yml`) runs on push to main and PRs:
-- **platform-build**: Go build, vet, `go test -race` with coverage profiling (25% baseline threshold)
+- **platform-build**: Go build, vet, `go test -race` with coverage profiling (25% baseline threshold; `setup-go` uses module cache)
- **canvas-build**: npm build, `vitest run` (no `--passWithNoTests` -- tests must exist and pass)
- **mcp-server-build**: npm build
- **python-lint**: `pytest --cov=. --cov-report=term-missing` (pytest-cov enabled)
+- **e2e-api** (added 2026-04-13): spins up Postgres + Redis service containers, runs platform migrations via `docker exec`, then executes `tests/e2e/test_api.sh` against a locally-built binary (62/62 must pass)
+- **shellcheck** (added 2026-04-13): lints every `tests/e2e/*.sh` via the shellcheck marketplace action
### Docker Compose
```bash
@@ -183,6 +192,15 @@ When a workspace specifies a template that doesn't exist, the Create handler fal
The A2A proxy (`POST /workspaces/:id/a2a`) enforces this for agent-to-agent calls. Canvas requests (no `X-Workspace-ID`), self-calls, and system callers (`webhook:*`, `system:*`, `test:*` prefixes via `isSystemCaller()` in `a2a_proxy.go`) bypass the check.
+### Handler Decomposition (2026-04-13)
+Four oversize handler functions were split into private helpers (pure refactor, behavior unchanged — 47 new unit tests cover the helpers directly; `handlers` package coverage 56.1% → 57.6%):
+- `a2a_proxy.go::proxyA2ARequest` (257→56 lines) — helpers: `resolveAgentURL`, `normalizeA2APayload`, `dispatchA2A`, `handleA2ADispatchError`, `maybeMarkContainerDead`, `logA2AFailure`, `logA2ASuccess`; sentinel `proxyDispatchBuildError`
+- `delegation.go::Delegate` (127→60 lines) — helpers: `bindDelegateRequest`, `lookupIdempotentDelegation`, `insertDelegationRow`; typed `insertDelegationOutcome` enum replaces `(bool, bool)` positional return
+- `discovery.go::Discover` (125→40 lines) — helpers: `discoverWorkspacePeer`, `writeExternalWorkspaceURL`, `discoverHostPeer`
+- `activity.go::SessionSearch` (109→24 lines) — helpers: `parseSessionSearchParams`, `buildSessionSearchQuery`, `scanSessionSearchRows`
+
+When modifying any of these, prefer extending the helper rather than inlining back.
+
### JSONB Gotcha
When inserting Go `[]byte` (from `json.Marshal`) into Postgres JSONB columns, you must:
1. Convert to `string()` first
diff --git a/PLAN.md b/PLAN.md
index 1f2a268b..0f98a686 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -166,6 +166,20 @@ for the full code audit.
---
+## Phase 31 — Quality + Infra Pass (Q2 2026) — SHIPPED 2026-04-13
+
+Completed in PRs #1–#8 and documented in `docs/edit-history/2026-04-13.md`:
+
+- [x] **Brand migration cleanup** — LICENSE "Agent Molecule" → "Molecule AI"; new icon assets (PR #1).
+- [x] **Repo structural cleanup** — moved `examples/remote-agent/` → `sdk/python/examples/`, `docs/superpowers/plans/` → `plugins/superpowers/plans/`; deleted empty `platform/plugins/`; gitignored `.agents/`, `platform/workspace-configs-templates/`, `backups/`, `logs/`, `test-results/`; added READMEs under `tests/` and `docs/` (PR #3).
+- [x] **MCP per-domain split** — `mcp-server/src/index.ts` 1697 → 89 lines; 12 per-domain modules in `src/tools/`; shared `src/api.ts`; startup log now reports 87 tools (PRs #2, #4, #7).
+- [x] **Canvas dialog unification** — native `confirm()`/`alert()` replaced with `ConfirmDialog` in 7 sites; new `singleButton` prop + 5 tests (vitest 352 → 357).
+- [x] **Platform handler decomposition** — 4 oversize functions (`proxyA2ARequest`, `Delegate`, `Discover`, `SessionSearch`) split into testable helpers; +47 Go tests; `handlers` coverage 56.1% → 57.6%.
+- [x] **Env-var documentation** — `.env.example` gained 11 previously-undocumented vars; all 21 distinct `os.Getenv`/`envx.*` keys now documented.
+- [x] **E2E hardening + CI** — Phase 30.1 bearer auth + Phase 30.6 `X-Workspace-ID` requirements baked into `test_api.sh` (62/62) and `test_comprehensive_e2e.sh` (67/67); shared `_lib.sh` + `_extract_token.py`; new CI jobs `e2e-api` and `shellcheck`; `setup-go` gains module cache (PRs #5, #7, #8).
+
+---
+
## PR Workflow Rules
All PRs must follow this checklist:
@@ -224,13 +238,14 @@ point for "what else is out there."
| Stack | Tests | Framework |
|-------|-------|-----------|
-| Go (platform) | 476 | `go test -race` |
-| Python (workspace) | 1,040 | pytest |
-| Canvas (frontend) | 352 | Vitest |
-| SDK (python) | 87 | pytest |
-| **Total** | **1,955** | |
+| Go (platform) | 536 | `go test -race` |
+| Python (workspace) | 1,084 | pytest |
+| Canvas (frontend) | 357 | Vitest |
+| SDK (python) | 121 | pytest |
+| MCP server | 97 | Jest |
+| **Total** | **2,295** | |
-E2E: 68/68 comprehensive checks passing, 62 API tests.
+E2E: 67/67 comprehensive checks passing, 62/62 API tests (also gated in CI `e2e-api` job), shellcheck-clean across all 5 E2E scripts.
---
diff --git a/README.zh-CN.md b/README.zh-CN.md
index fafe1655..682a11a9 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -21,7 +21,7 @@
全球最强大的 Agent Team 治理方案。
-[](https://opensource.org/licenses/MIT)
+[](LICENSE)
[](https://golang.org/)
[](https://www.python.org/)
[](https://nextjs.org/)
@@ -287,4 +287,6 @@ npm run dev
## License
-MIT
+[Business Source License 1.1](LICENSE) — 版权所有 © 2025 Molecule AI。
+
+允许个人、内部与非商业用途。不得使用本作品提供与本产品竞争的商业服务。2029 年 1 月 1 日起转为 Apache 2.0。
diff --git a/docs/api-protocol/platform-api.md b/docs/api-protocol/platform-api.md
index 06661238..5beb3409 100644
--- a/docs/api-protocol/platform-api.md
+++ b/docs/api-protocol/platform-api.md
@@ -64,14 +64,16 @@ Workspace creation also assigns an `awareness_namespace` on the workspace row. T
### Registry
-| Method | Path | Description |
-|---|---|---|
-| `POST` | `/registry/register` | Workspace registration on startup |
-| `POST` | `/registry/heartbeat` | Liveness and task updates |
-| `POST` | `/registry/update-card` | Push Agent Card updates after runtime/skill changes |
-| `GET` | `/registry/discover/:id` | Resolve workspace URL for A2A calls |
-| `GET` | `/registry/:id/peers` | List reachable peers |
-| `POST` | `/registry/check-access` | Validate reachability/access |
+| Method | Path | Description | Auth |
+|---|---|---|---|
+| `POST` | `/registry/register` | Workspace registration on startup. First register issues a per-workspace bearer token in the response body (`auth_token`); re-register is idempotent and omits the token. | — |
+| `POST` | `/registry/heartbeat` | Liveness and task updates. | Phase 30.1 — `Authorization: Bearer ` required if the workspace has any live token on file; legacy workspaces grandfathered (fail-open). |
+| `POST` | `/registry/update-card` | Push Agent Card updates after runtime/skill changes. | Phase 30.1 — same grandfather rule as `/heartbeat`. |
+| `GET` | `/registry/discover/:id` | Resolve workspace URL for A2A calls. | Phase 30.6 — caller sends `X-Workspace-ID` + own bearer token; fail-open on DB hiccup (hierarchy check is primary gate). |
+| `GET` | `/registry/:id/peers` | List reachable peers. | Phase 30.6 — same as `/discover/:id`. |
+| `POST` | `/registry/check-access` | Validate reachability/access. | — |
+
+**Why the auth callout matters:** remote (Phase 30) agents authenticate themselves with the bearer token returned by `POST /registry/register`. Local containers are transparent to this during the lazy-bootstrap grace window — the provisioner threads the token in as an env var on first register. See `docs/development/testing-e2e.md` for how E2E scripts handle token capture. If you change these routes, update `tests/e2e/test_api.sh` in the same PR.
### Activity and recall
diff --git a/docs/development/local-development.md b/docs/development/local-development.md
index 12e1ee8a..449f3952 100644
--- a/docs/development/local-development.md
+++ b/docs/development/local-development.md
@@ -92,26 +92,33 @@ Docker Compose 2.x
### Unit Tests
```bash
-cd platform && go test -race ./... # Go tests with race detection (358 tests)
-cd canvas && npm test # Vitest tests (188 tests)
-cd workspace-template && python -m pytest -v # Workspace runtime tests (148 tests)
+cd platform && go test -race ./... # Go tests with race detection (536 tests)
+cd canvas && npm test # Vitest tests (357 tests)
+cd workspace-template && python -m pytest -v # Workspace runtime tests (1084 tests)
+cd sdk/python && python -m pytest -v # SDK tests (121 tests)
+cd mcp-server && npm test # MCP server tests (97 Jest tests)
```
### Integration Tests
```bash
-bash test_api.sh # 62 API tests (requires platform running)
-bash test_a2a_e2e.sh # 22 A2A e2e tests (requires platform + 2 agents)
-bash test_activity_e2e.sh # 25 activity/task E2E tests (requires platform + 1 agent)
+bash tests/e2e/test_api.sh # 62 API tests (quick local verify; Phase 30.1 bearer-auth aware; also runs in CI)
+bash tests/e2e/test_a2a_e2e.sh # 22 A2A e2e tests (requires platform + 2 agents)
+bash tests/e2e/test_activity_e2e.sh # 25 activity/task E2E tests (requires platform + 1 agent)
+bash tests/e2e/test_comprehensive_e2e.sh # 67 endpoint/memory/bundle/approval checks
```
+All E2E scripts share `tests/e2e/_lib.sh` helpers and are shellcheck-clean (enforced in CI). See [`./testing-e2e.md`](./testing-e2e.md) for auth prerequisites and what CI runs.
+
### CI Pipeline
GitHub Actions runs automatically on push to `main` and on PRs (`.github/workflows/ci.yml`):
-- **platform-build** — Go build, vet, `go test -race` with coverage profiling (25% baseline threshold)
+- **platform-build** — Go build, vet, `go test -race` with coverage profiling (25% baseline threshold; setup-go uses module cache)
- **canvas-build** — npm build, `vitest run` (no `--passWithNoTests` -- tests must exist and pass)
- **mcp-server-build** — npm build
- **python-lint** — `pytest --cov=. --cov-report=term-missing` (pytest-cov enabled)
+- **e2e-api** (added 2026-04-13) — Postgres + Redis service containers, migrations applied via `docker exec`, `tests/e2e/test_api.sh` must pass 62/62
+- **shellcheck** (added 2026-04-13) — lints every `tests/e2e/*.sh`
Postgres and Redis are not exposed to the host -- use `docker compose exec postgres psql` or `docker compose exec redis redis-cli` for direct access.
diff --git a/docs/development/testing-e2e.md b/docs/development/testing-e2e.md
new file mode 100644
index 00000000..8b8caef6
--- /dev/null
+++ b/docs/development/testing-e2e.md
@@ -0,0 +1,68 @@
+# E2E Testing
+
+End-to-end test scripts live under `tests/e2e/` and exercise the platform against a real Postgres + Redis. Every script is shellcheck-clean and shares helpers from `tests/e2e/_lib.sh` + `tests/e2e/_extract_token.py`.
+
+## Scripts
+
+| Script | Checks | Prerequisites |
+|--------|--------|--------------|
+| `test_api.sh` | 62 | platform running on :8080; no live agents required |
+| `test_comprehensive_e2e.sh` | 67 | platform running; spins up its own workspaces |
+| `test_a2a_e2e.sh` | 22 | platform + 2 provisioned agents (Echo + SEO) with `OPENROUTER_API_KEY` |
+| `test_activity_e2e.sh` | 25 | platform + 1 online agent |
+| `test_claude_code_e2e.sh` | — | platform + Claude Code runtime; exercises CLI adapter |
+
+## Auth Prerequisites (Phase 30)
+
+After Phase 30.1, the following routes require `Authorization: Bearer ` once a workspace has any live token on file (legacy workspaces are grandfathered):
+
+- `POST /registry/heartbeat`
+- `POST /registry/update-card`
+
+After Phase 30.6, the following routes additionally require `X-Workspace-ID` on the caller side (bearer token validated, fail-open on DB hiccup):
+
+- `GET /registry/discover/:id`
+- `GET /registry/:id/peers`
+
+The scripts handle this by:
+
+1. Creating a workspace → platform returns no token yet.
+2. Calling `POST /registry/register` — response body includes `auth_token` once per workspace.
+3. Extracting the token via `_extract_token.py` (reads JSON from stdin).
+4. Passing it in subsequent heartbeat / discover / peers calls.
+
+`test_comprehensive_e2e.sh` registers each workspace **immediately after creation** so the provisioner's auto-register doesn't race the test's explicit register. `test_activity_e2e.sh` re-registers a detected-already-online agent to capture a fresh bearer token.
+
+## Running Locally
+
+```bash
+# Quickest check after any platform change:
+cd platform && go build ./cmd/server && ./server &
+bash tests/e2e/test_api.sh # expect 62/62 pass
+
+# Comprehensive sweep:
+bash tests/e2e/test_comprehensive_e2e.sh # expect 67/67 pass
+```
+
+Both scripts include a pre-test cleanup that deletes workspaces from previous runs so a stale DB won't cause spurious failures.
+
+## What CI Runs
+
+`.github/workflows/ci.yml` (added 2026-04-13):
+
+- **e2e-api** — spins up Postgres + Redis via service containers, applies migrations with `docker exec`, builds the platform binary, runs `tests/e2e/test_api.sh`. All 62 checks must pass.
+- **shellcheck** — runs the shellcheck marketplace action against every `tests/e2e/*.sh`.
+
+The other E2E scripts are not yet in CI because they require provisioned agents and LLM credentials; run them locally before merging runtime-touching changes.
+
+## Adding a New E2E Check
+
+1. Source `tests/e2e/_lib.sh` for `assert_*` helpers, bearer-token extraction, and the cleanup preamble.
+2. When hitting an auth-gated route, always register the workspace first and thread the returned token through subsequent requests.
+3. Keep each check idempotent — the comprehensive script is expected to be re-runnable on the same DB.
+4. Run `shellcheck tests/e2e/your_script.sh` locally before pushing.
+
+## Related Docs
+
+- [Local Development](./local-development.md)
+- [Platform API](../api-protocol/platform-api.md) — route reference incl. auth requirements
diff --git a/docs/edit-history/2026-04-13.md b/docs/edit-history/2026-04-13.md
index e3d2707d..f17d37a5 100644
--- a/docs/edit-history/2026-04-13.md
+++ b/docs/edit-history/2026-04-13.md
@@ -1,5 +1,117 @@
# 2026-04-13 — edit history
+## Summary — Quality + Infra Pass (PRs #1–#8, all merged)
+
+Eight PRs landed today in a focused quality pass. No user-facing feature
+changes; the payoff is faster onboarding, lower merge friction, and
+stronger CI gates.
+
+### Brand + structural
+- **PR #1 `chore/branding-icons`** — replaced `molecule-icon.png` across
+ `canvas/public/`, `canvas/src/app/`, `docs/assets/branding/`; added
+ `HANDOFF.md` at the repo root; fixed a comment typo in
+ `.githooks/pre-commit`.
+- **PR #3 `chore/structural-cleanup`** — deleted empty
+ `platform/plugins/`; moved `examples/remote-agent/` →
+ `sdk/python/examples/remote-agent/` and `docs/superpowers/plans/` →
+ `plugins/superpowers/plans/`; added READMEs to `tests/` and `docs/`;
+ gitignored `.agents/`, `platform/workspace-configs-templates/`,
+ `backups/`, `logs/`, `test-results/`.
+- LICENSE: trailing brand-migration fix — "Agent Molecule" → "Molecule AI".
+
+### MCP server refactor (PRs #2, #4, #7)
+- `mcp-server/src/index.ts` shrank from **1697 → 89 lines**. Tool
+ handlers now live in per-domain modules under `mcp-server/src/tools/`:
+ `workspaces.ts`, `agents.ts`, `secrets.ts`, `files.ts`, `memory.ts`,
+ `plugins.ts`, `channels.ts`, `delegation.ts`, `schedules.ts`,
+ `approvals.ts`, `discovery.ts`, `remote_agents.ts`.
+- New shared HTTP layer `mcp-server/src/api.ts` exports `PLATFORM_URL`,
+ generic `apiCall`, `ApiError` type, `isApiError()` guard,
+ `toMcpResult()`, `toMcpText()`.
+- Each `tools/*.ts` exports handlers + a `registerXxxTools(srv)` function.
+ `createServer()` in `index.ts` wires them.
+- Fixed `handleGetRemoteAgentSetupCommand` — emits a valid
+ `python3 -c "from molecule_agent import RemoteAgentClient; …"` one-liner
+ (was an invalid `python3 -m examples.remote-agent.run`).
+- MCP now reports **87 tools** on startup (older logs / docs said "61" —
+ both updated).
+
+### Canvas (PRs, shipped across session)
+- Replaced native `window.confirm` / `alert` with `ConfirmDialog` in
+ seven sites: `ChannelsTab.tsx`, `ScheduleTab.tsx`, `ChatTab.tsx`,
+ `TemplatePalette.tsx` (×2), `ErrorBoundary.tsx` (×2 removed; buttons
+ are self-evident).
+- New `singleButton` prop on `ConfirmDialog` for info-toast usage, plus
+ 5 new vitest cases at
+ `canvas/src/components/__tests__/ConfirmDialog.test.tsx`.
+- `ErrorBoundary` clipboard write now catches rejections and logs to
+ `console.warn`.
+- Vitest count: **352 → 357**.
+
+### Platform — handler decomposition (pure refactor)
+Four oversize handler functions split into private helpers — behavior
+unchanged, but each extracted helper is now directly unit-tested.
+- `a2a_proxy.go::proxyA2ARequest` (257 → 56 lines). New helpers:
+ `resolveAgentURL`, `normalizeA2APayload`, `dispatchA2A`,
+ `handleA2ADispatchError`, `maybeMarkContainerDead`, `logA2AFailure`,
+ `logA2ASuccess`; sentinel `proxyDispatchBuildError`.
+- `delegation.go::Delegate` (127 → 60 lines). New helpers:
+ `bindDelegateRequest`, `lookupIdempotentDelegation`,
+ `insertDelegationRow`; typed `insertDelegationOutcome` enum
+ (zero value `insertOutcomeUnknown`) replaces a positional
+ `(bool, bool)` return.
+- `discovery.go::Discover` (125 → 40 lines). New helpers:
+ `discoverWorkspacePeer`, `writeExternalWorkspaceURL`,
+ `discoverHostPeer`.
+- `activity.go::SessionSearch` (109 → 24 lines). New helpers:
+ `parseSessionSearchParams`, `buildSessionSearchQuery`,
+ `scanSessionSearchRows`.
+
+**+47 Go unit tests**; `platform/internal/handlers` coverage
+**56.1 % → 57.6 %**.
+
+### Config / env documentation
+- `.env.example` gained **11 previously-undocumented env vars** across 6
+ new sections: `PLATFORM_URL`, `MOLECULE_URL`, `WORKSPACE_DIR`,
+ `MOLECULE_ENV`, `CORS_ORIGINS`, `RATE_LIMIT`, `ACTIVITY_RETENTION_DAYS`,
+ `ACTIVITY_CLEANUP_INTERVAL_HOURS`, `MOLECULE_IN_DOCKER`,
+ `AWARENESS_URL`, `GITHUB_WEBHOOK_SECRET`, `MOLECLI_URL`. All 21
+ distinct `os.Getenv` / `envx.*` keys (except HOME) are now documented.
+
+### E2E + CI (PRs #5, #7, #8)
+- New shared helpers `tests/e2e/_lib.sh` and
+ `tests/e2e/_extract_token.py`.
+- `tests/e2e/test_api.sh` updated for Phase 30.1 bearer-token auth and
+ Phase 30.6 `X-Workspace-ID` requirement on discover/peers; added a
+ pre-test workspace cleanup. **62/62 pass.**
+- `tests/e2e/test_comprehensive_e2e.sh` fixed the token race against
+ the provisioner by registering each workspace immediately after
+ creation. **67/67 pass.**
+- `tests/e2e/test_activity_e2e.sh` re-registers a detected agent to
+ capture its bearer token.
+- `tests/e2e/test_claude_code_e2e.sh` got shellcheck annotations only.
+- All five scripts are shellcheck-clean.
+- `.github/workflows/ci.yml` gained two new jobs:
+ - **`e2e-api`** — Postgres + Redis service containers, migrations
+ applied via `docker exec`, `test_api.sh` runs against a freshly-built
+ platform binary.
+ - **`shellcheck`** — marketplace action lints every
+ `tests/e2e/*.sh`.
+- Existing Go job got `cache: true` on `setup-go`.
+- Bundle round-trip and "status online" assertions now tolerate the
+ async provisioner flipping status, removing flaky false-negatives.
+
+### Test totals after today's sync
+| Stack | Before | After |
+|-------|--------|-------|
+| Go (platform) | 489 | 536 |
+| Python (workspace) | 1078 | 1084 |
+| Canvas (vitest) | 352 | 357 |
+| SDK (pytest) | 87 | 121 |
+| MCP server (Jest) | 96 | 97 |
+
+---
+
## Canvas — org template import (PLAN.md §20.3)
**What:** added `OrgTemplatesSection` to `canvas/src/components/TemplatePalette.tsx`.