molecule-core/docs/edit-history/2026-04-01.md
Hongming Wang d8026347e5 chore: open-source restructure — rename dirs, remove internal files, scrub secrets
Renames:
- platform/ → workspace-server/ (Go module path stays as "platform" for
  external dep compat — will update after plugin module republish)
- workspace-template/ → workspace/

Removed (moved to separate repos or deleted):
- PLAN.md — internal roadmap (move to private project board)
- HANDOFF.md, AGENTS.md — one-time internal session docs
- .claude/ — gitignored entirely (local agent config)
- infra/cloudflare-worker/ → Molecule-AI/molecule-tenant-proxy
- org-templates/molecule-dev/ → standalone template repo
- .mcp-eval/ → molecule-mcp-server repo
- test-results/ — ephemeral, gitignored

Security scrubbing:
- Cloudflare account/zone/KV IDs → placeholders
- Real EC2 IPs → <EC2_IP> in all docs
- CF token prefix, Neon project ID, Fly app names → redacted
- Langfuse dev credentials → parameterized
- Personal runner username/machine name → generic

Community files:
- CONTRIBUTING.md — build, test, branch conventions
- CODE_OF_CONDUCT.md — Contributor Covenant 2.1

All Dockerfiles, CI workflows, docker-compose, railway.toml, render.yaml,
README, CLAUDE.md updated for new directory names.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 00:24:44 -07:00

6.2 KiB

Edit History — 2026-04-01

Summary

Completed Phase 2 end-to-end validation (SEO agent template, Docker build fixes, A2A proxy endpoint) and comprehensive PLAN.md rewrite (10 → 15 phases). Two rounds of code review fixes on canvas and platform code.

Phase 2: End-to-End Validation

SEO Agent Template (8a)

  • Created workspace-configs-templates/seo-agent/config.yaml — Tier 1, two skills, web_search tool
  • Created workspace-configs-templates/seo-agent/system-prompt.md — SEO specialist identity
  • Created workspace-configs-templates/seo-agent/skills/generate-seo-page/SKILL.md — 4-step SEO page generation process
  • Created workspace-configs-templates/seo-agent/skills/generate-seo-page/tools/score_seo.py — @tool function scoring content for SEO factors (word count, keyword density, H1/H2 structure, meta description)
  • Created workspace-configs-templates/seo-agent/skills/audit-seo-page/SKILL.md — Comprehensive SEO audit checklist

Docker Build Fixes (8b)

  • Fixed workspace/requirements.txta2a-python>=0.2.0a2a-sdk[http-server]>=0.3.0 (correct PyPI package)
  • Fixed workspace/agent.py — Use ChatAnthropic directly instead of init_chat_model (not available in current langchain-core). Added provider-agnostic model loading with ImportError handling.
  • Fixed workspace/skills/loader.py — Detect tools via isinstance(BaseTool) instead of is_tool attribute (Pydantic v2 compatibility)
  • Fixed workspace/tools/delegation.py — Removed is_tool attribute set (Pydantic v2 rejects arbitrary attributes on StructuredTool)

End-to-End Deployment Verified (8c-8d)

  • Container starts, loads 2 skills, serves Agent Card at /.well-known/agent-card.json
  • Registers with platform → status online with full Agent Card (skills, capabilities)
  • A2A proxy forwards messages through platform to agent → agent calls Claude API
  • Blocked by 429 rate limit during testing (subscription quota contention)

POST /workspaces/:id/a2a Proxy Endpoint (Phase 11, 17s)

New files:

  • workspace-server/internal/handlers/workspace.go — Added ProxyA2A handler
  • workspace-server/internal/router/router.go — Added route

Behavior:

  1. Resolves workspace URL via Redis cache → DB fallback
  2. Wraps bare method+params in JSON-RPC 2.0 envelope if needed
  3. Forwards to agent with 120s timeout via shared http.Client
  4. Request body capped at 1MB, response at 10MB (io.LimitReader)
  5. Returns agent response directly

Code Review Fixes (Round 3)

  • workspace.go — Reuse package-level http.Client, add io.LimitReader for request (1MB) and response (10MB), handle json.Marshal error
  • delegation.py — Removed /a2a suffix from target URL (A2A SDK serves at root), read retry config from env vars (DELEGATION_RETRY_ATTEMPTS, DELEGATION_RETRY_DELAY, DELEGATION_TIMEOUT)
  • a2a_executor.py — Return error message on empty input instead of sending str(parts) to LLM, use tuple message format ("user", text)
  • loader.py — Move BaseTool import outside the per-file loop
  • score_seo.py — Use word-boundary regex (\b) for keyword density instead of substring count
  • agent.py — Catch ImportError for optional provider packages with clear install message

PLAN.md Comprehensive Rewrite

Expanded from 10 phases to 15 phases after cross-referencing all 29 docs files:

  • Added Phase 5 (Agent Management), Phase 9 (HMA Memory), Phase 12 (Code Sandbox), Phase 13 (Runtime Enhancements), Phase 15 (SaaS Preparation)
  • Tracked all PRD features: F1.13 connection breakage, F4.4 ClawHub, F6.5 configurable approval rules
  • Added event type annotations (AGENT_*, WORKSPACE_EXPANDED/COLLAPSED)
  • Final counts: 15 phases, 107 tracked items (25 done, 81 todo, 1 partial)

Canvas Drag-to-Nest (Phase 3, 9e)

  • canvas/src/store/canvas.ts — Added dragOverNodeId, setDragOverNode, nestNode(), isDescendant() to store
  • canvas/src/components/Canvas.tsx — Wrapped in ReactFlowProvider, uses getIntersectingNodes() during onNodeDrag for overlap detection, onNodeDragStop to finalize nesting or un-nesting
  • canvas/src/components/WorkspaceNode.tsx — Green ring highlight (border-green-500 ring-2 scale-105) when node is a valid drop target

Provisioner Package (Phase 4, 10a-10g)

  • Created workspace-server/internal/provisioner/provisioner.go — Docker SDK integration with Start(), Stop(), IsRunning()
  • Wired into workspace creation: POST /workspaces with template field triggers auto-provisioning
  • Added POST /workspaces/:id/retry endpoint for failed workspaces
  • Secret injection from workspace_secrets table
  • Lifecycle: provisioning → online (via heartbeat) or → failed (3min timeout)
  • Provisioner initialized in main.go with graceful degradation if Docker unavailable

Agent Management (Phase 5, 11a-11d)

  • Created workspace-server/internal/handlers/agent.go with 4 endpoints
  • POST /workspaces/:id/agent — assign (AGENT_ASSIGNED)
  • PATCH /workspaces/:id/agent — replace model (AGENT_REPLACED)
  • DELETE /workspaces/:id/agent — remove (AGENT_REMOVED)
  • POST /workspaces/:id/agent/move — move between workspaces (AGENT_MOVED on both)

Bundle Export/Import (Phase 6, 12a-12c)

  • Created workspace-server/internal/bundle/ package (types.go, exporter.go, importer.go)
  • GET /bundles/export/:id — serialize workspace → bundle JSON with recursive sub-workspaces
  • POST /bundles/import — create workspace records + trigger provisioner from bundle
  • Created workspace-server/internal/handlers/bundle.go

A2A Proxy Fix

  • Fixed POST /workspaces/:id/a2a — injects messageId into params.message (required by a2a-sdk v0.3+)
  • Fixed stale process on port 8080 serving old binary

Code Review Fixes (Round 4)

  • Removed debug log lines from ProxyA2A
  • Guard short ID slicing in provisioner and importer ([:12], [:8])
  • Fixed findConfigDir to match by workspace name in config.yaml
  • Handle os.WriteFile errors in bundle importer
  • Handle DB error in agent Move handler (not just ErrNoRows)
  • Handle json.Unmarshal error in bundle exporter
  • Use optional chaining in isDescendant store function

CLAUDE.md Updates

  • Added API routes: config, memory, a2a, retry, agent CRUD, bundles
  • Fixed migration count from 5 to 6
  • Added CONFIGS_DIR env var