diff --git a/canvas/src/components/AuthGate.tsx b/canvas/src/components/AuthGate.tsx index be3714299..e06eae0a1 100644 --- a/canvas/src/components/AuthGate.tsx +++ b/canvas/src/components/AuthGate.tsx @@ -29,6 +29,11 @@ export function AuthGate({ children }: { children: ReactNode }) { setState({ kind: "anonymous", skipRedirect: true }); return; } + // Never gate /cp/auth/* paths — these ARE the login pages. + if (typeof window !== "undefined" && window.location.pathname.startsWith("/cp/auth/")) { + setState({ kind: "anonymous", skipRedirect: true }); + return; + } let cancelled = false; fetchSession() .then((s) => { diff --git a/canvas/src/components/tabs/ConfigTab.tsx b/canvas/src/components/tabs/ConfigTab.tsx index 7d177ebf4..4bf4b09f0 100644 --- a/canvas/src/components/tabs/ConfigTab.tsx +++ b/canvas/src/components/tabs/ConfigTab.tsx @@ -104,6 +104,13 @@ interface RuntimeOption { // Fallback used when /templates can't be fetched (offline, older backend). // Keep in sync with manifest.json workspace_templates as a defensive default. // Model + env suggestions only flow when the backend is reachable. +// Runtimes that manage their own config outside the platform's config.yaml +// template. For these, a missing config.yaml is expected — the user manages +// config via the runtime's own mechanism (e.g. hermes edits +// ~/.hermes/config.yaml on the workspace EC2 via the Terminal tab or its +// own CLI). Showing a "No config.yaml found" error for these is misleading. +const RUNTIMES_WITH_OWN_CONFIG = new Set(["hermes", "external"]); + const FALLBACK_RUNTIME_OPTIONS: RuntimeOption[] = [ { value: "", label: "LangGraph (default)", models: [] }, { value: "claude-code", label: "Claude Code", models: [] }, @@ -134,14 +141,50 @@ export function ConfigTab({ workspaceId }: Props) { const loadConfig = useCallback(async () => { setLoading(true); setError(null); + + // ALWAYS load workspace metadata first (runtime + model). These are the + // source of truth regardless of whether the runtime uses our config.yaml + // template. Without this the form falls back to empty/default values on + // a hermes workspace (which doesn't use our template), creating the + // appearance that the saved runtime is unset — and worse, clicking Save + // would silently flip `runtime` from `hermes` back to the dropdown + // default `LangGraph`. See GH #1894. + let wsMetadataRuntime = ""; + let wsMetadataModel = ""; + try { + const ws = await api.get<{ runtime?: string }>(`/workspaces/${workspaceId}`); + wsMetadataRuntime = (ws.runtime || "").trim(); + } catch { /* fall back to config.yaml */ } + try { + const m = await api.get<{ model?: string }>(`/workspaces/${workspaceId}/model`); + wsMetadataModel = (m.model || "").trim(); + } catch { /* non-fatal */ } + try { const res = await api.get<{ content: string }>(`/workspaces/${workspaceId}/files/config.yaml`); const parsed = parseYaml(res.content); setOriginalYaml(res.content); setRawDraft(res.content); - setConfig({ ...DEFAULT_CONFIG, ...parsed } as ConfigData); + // Merge: config.yaml wins for fields it declares, but workspace metadata + // wins for runtime + model when config.yaml doesn't set them. + const merged = { ...DEFAULT_CONFIG, ...parsed } as ConfigData; + if (!merged.runtime && wsMetadataRuntime) merged.runtime = wsMetadataRuntime; + if (!merged.model && wsMetadataModel) merged.model = wsMetadataModel; + setConfig(merged); } catch { - setError("No config.yaml found"); + // No platform-managed config.yaml. Some runtimes (hermes, external) + // manage their own config outside this template; that's expected, not + // an error. Populate the form from workspace metadata so the user + // still sees the saved runtime + model. + const runtimeManagesOwnConfig = RUNTIMES_WITH_OWN_CONFIG.has(wsMetadataRuntime); + if (!runtimeManagesOwnConfig) { + setError("No config.yaml found"); + } + setConfig({ + ...DEFAULT_CONFIG, + runtime: wsMetadataRuntime, + model: wsMetadataModel, + } as ConfigData); } finally { setLoading(false); } @@ -511,6 +554,13 @@ export function ConfigTab({ workspaceId }: Props) { {error && (
{error}
)} + {!error && RUNTIMES_WITH_OWN_CONFIG.has(config.runtime || "") && ( +
+ {config.runtime === "hermes" + ? "Hermes manages its own config at ~/.hermes/config.yaml on the workspace host. Edit it via the Terminal tab or the hermes CLI, not this form." + : "This runtime manages its own config outside the platform template."} +
+ )} {success && (
Saved
)} diff --git a/canvas/src/lib/__tests__/auth.test.ts b/canvas/src/lib/__tests__/auth.test.ts index f1cd3b52d..8188ddf2a 100644 --- a/canvas/src/lib/__tests__/auth.test.ts +++ b/canvas/src/lib/__tests__/auth.test.ts @@ -47,7 +47,12 @@ describe("redirectToLogin", () => { const href = "https://acme.moleculesai.app/dashboard"; Object.defineProperty(window, "location", { writable: true, - value: { href }, + value: { + href, + pathname: "/dashboard", + hostname: "acme.moleculesai.app", + protocol: "https:", + }, }); redirectToLogin("sign-in"); // href now holds the redirect target. encodeURIComponent(href) must @@ -61,7 +66,12 @@ describe("redirectToLogin", () => { it("uses signup path for sign-up screenHint", () => { Object.defineProperty(window, "location", { writable: true, - value: { href: "https://acme.moleculesai.app/" }, + value: { + href: "https://acme.moleculesai.app/", + pathname: "/", + hostname: "acme.moleculesai.app", + protocol: "https:", + }, }); redirectToLogin("sign-up"); expect((window.location as unknown as { href: string }).href).toContain("/cp/auth/signup"); diff --git a/canvas/src/lib/api.ts b/canvas/src/lib/api.ts index bcf3a0ba2..0d1938b34 100644 --- a/canvas/src/lib/api.ts +++ b/canvas/src/lib/api.ts @@ -38,6 +38,13 @@ async function request( credentials: "include", signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS), }); + if (res.status === 401) { + // Session expired or credentials lost — redirect to login once. + // Import dynamically to avoid circular dependency with auth.ts. + const { redirectToLogin } = await import("./auth"); + redirectToLogin("sign-in"); + throw new Error("Session expired — redirecting to login"); + } if (!res.ok) { const text = await res.text(); throw new Error(`API ${method} ${path}: ${res.status} ${text}`); diff --git a/canvas/src/lib/auth.ts b/canvas/src/lib/auth.ts index d16006ac2..fe7c71ab6 100644 --- a/canvas/src/lib/auth.ts +++ b/canvas/src/lib/auth.ts @@ -7,6 +7,7 @@ * can surface them. */ import { PLATFORM_URL } from "./api"; +import { SaaSHostSuffix } from "./tenant"; export interface Session { user_id: string; @@ -17,6 +18,18 @@ export interface Session { // Base path prefix for auth endpoints on the control plane. const AUTH_BASE = "/cp/auth"; +// Auth UI lives on the "app" subdomain (app.moleculesai.app), NOT on +// tenant subdomains (hongmingwang.moleculesai.app). Tenant subdomains +// proxy to EC2 platform which has no auth routes. +function getAuthOrigin(): string { + if (typeof window === "undefined") return PLATFORM_URL; + const host = window.location.hostname; + if (host.endsWith(SaaSHostSuffix)) { + return `${window.location.protocol}//app${SaaSHostSuffix}`; + } + return PLATFORM_URL; +} + /** * fetchSession probes /cp/auth/me with the session cookie (credentials: * include mandatory cross-origin). Returns the Session on 200, null on @@ -44,8 +57,13 @@ export async function fetchSession(): Promise { */ export function redirectToLogin(screenHint: "sign-up" | "sign-in" = "sign-in"): void { if (typeof window === "undefined") return; + // Guard against infinite redirect loop: if we're already on the login + // page, don't redirect again (each redirect double-encodes return_to + // until the URL exceeds header limits → 431). + if (window.location.pathname.startsWith("/cp/auth/")) return; const returnTo = window.location.href; const path = screenHint === "sign-up" ? "signup" : "login"; - const dest = `${PLATFORM_URL}${AUTH_BASE}/${path}?return_to=${encodeURIComponent(returnTo)}`; + const authOrigin = getAuthOrigin(); + const dest = `${authOrigin}${AUTH_BASE}/${path}?return_to=${encodeURIComponent(returnTo)}`; window.location.href = dest; } diff --git a/docs/blog/2026-04-20-chrome-devtools-mcp-seo/index.md b/docs/blog/2026-04-20-chrome-devtools-mcp-seo/index.md index ccfa1d8b4..bcc5bd9cf 100644 --- a/docs/blog/2026-04-20-chrome-devtools-mcp-seo/index.md +++ b/docs/blog/2026-04-20-chrome-devtools-mcp-seo/index.md @@ -4,6 +4,7 @@ date: 2026-04-20 slug: browser-automation-ai-agents-mcp description: "Learn how to add browser automation to your AI agents using Chrome DevTools and the Model Context Protocol. Full Python code examples — no Puppeteer wrappers, no SaaS dependencies." tags: [MCP, browser-automation, AI-agents, CDP, tutorial] +og_image: /assets/blog/2026-04-21-chrome-devtools-mcp-og.png --- # Give Your AI Agent a Real Browser: MCP + Chrome DevTools diff --git a/docs/blog/2026-04-20-chrome-devtools-mcp/index.md b/docs/blog/2026-04-20-chrome-devtools-mcp/index.md index 7b1b819e3..f25c234b7 100644 --- a/docs/blog/2026-04-20-chrome-devtools-mcp/index.md +++ b/docs/blog/2026-04-20-chrome-devtools-mcp/index.md @@ -4,6 +4,7 @@ date: 2026-04-20 slug: chrome-devtools-mcp description: "Chrome DevTools MCP gives any compatible AI agent full browser control through a standards-based interface. That's powerful for prototypes. For production, you need a governance layer. Here's where Molecule AI fits in." tags: [browser-automation, mcp, governance, chrome-devtools, security] +og_image: /assets/blog/2026-04-21-chrome-devtools-mcp-og.png --- # Browser Automation Meets Production Standards diff --git a/docs/blog/2026-04-21-cloudflare-artifacts/index.md b/docs/blog/2026-04-21-cloudflare-artifacts/index.md index 1d28711d9..265da0580 100644 --- a/docs/blog/2026-04-21-cloudflare-artifacts/index.md +++ b/docs/blog/2026-04-21-cloudflare-artifacts/index.md @@ -4,6 +4,7 @@ date: 2026-04-21 slug: cloudflare-artifacts-molecule-ai description: "Attach a Cloudflare Artifacts git repository to any Molecule AI workspace. Import existing repos, fork for experiments, mint short-lived git credentials — all via the platform API. Git-native storage for AI agents." tags: [Cloudflare, git, artifacts, AI-agents, workflow, tutorial] +status: "⚠️ PM ruling 2026-04-22: sub-100ms claim UNSUBSTANTIATED — replaced with 'low-latency' (same latency class)" --- # Give Your AI Agent a Git Repository: Molecule AI + Cloudflare Artifacts @@ -25,7 +26,7 @@ Git-native storage is different because: - **Agents already know git.** Clone, branch, commit, push. No new primitives to learn. - **Versioning is structural.** Every change is a commit. Rollback is `git revert`. No "last writer wins" data loss. - **Collaboration is native.** Fork a repo, experiment, open a PR. The same workflow humans use to collaborate applies to agents. -- **Cloudflare Artifacts is fast.** Git operations run on Cloudflare's edge — sub-100ms clone times from anywhere. No S3 bandwidth bills. +- **Cloudflare Artifacts is fast.** Git operations run on Cloudflare's edge — low-latency clone times from anywhere. No S3 bandwidth bills. - **Access control is git-native.** Token scoping, branch protection, repo-level permissions. The same model your team already uses. ## API Reference diff --git a/docs/blog/2026-04-22-a2a-v1-agent-platform/index.md b/docs/blog/2026-04-22-a2a-v1-agent-platform/index.md index 2e57780f6..7925a0b4e 100644 --- a/docs/blog/2026-04-22-a2a-v1-agent-platform/index.md +++ b/docs/blog/2026-04-22-a2a-v1-agent-platform/index.md @@ -3,6 +3,8 @@ title: "What A2A v1.0 Means for Your Agent Stack: Why Protocol-Native Beats Prot description: "A2A v1.0 shipped March 2026 as the Linux Foundation's standard for multi-agent communication. Here's why being built on it from day one matters more than adding it as a layer." date: 2026-04-22 canonical: https://docs.molecule.ai/blog/a2a-v1-agent-platform +tags: [a2a, agent-protocol, multi-agent, governance, enterprise, platform] +og_image: /assets/blog/2026-04-21-chrome-devtools-mcp-og.png --- *Meta description (160 chars): Before you buy an agent platform, ask how A2A delegation is attributed. The answer reveals everything about governance.* @@ -49,7 +51,7 @@ Both Python and Node.js external agent templates are under 100 lines. Registrati ## Why This Matters Now: The Governance Gap in Competing Implementations -A2A v1.0 ratification has accelerated adoption across the agent platform landscape. LangGraph shipped A2A support in Q1 2026 (PRs #6645, #7113 — still in review after 3+ months). But a protocol implementation and a governance-ready implementation are not the same thing. +A2A v1.0 ratification has accelerated adoption across the agent platform landscape. LangGraph's A2A implementation (PRs #6645, #7113 — ⚠️ VERIFY: PMM 2026-04-21 confirmed these PRs not found in langchain-ai/langgraph open PR list; may be merged, closed, or re-numbered) positions against the governance gap. But a protocol implementation and a governance-ready implementation are not the same thing. LangGraph's current A2A PRs implement the protocol layer: message framing, capability negotiation, task routing. What they do not yet implement is the governance layer — the mechanisms that make A2A usable in regulated environments, multi-tenant deployments, and enterprise fleets. diff --git a/docs/blog/2026-04-22-cloudflare-tunnel-migration/index.md b/docs/blog/2026-04-22-cloudflare-tunnel-migration/index.md index f4254543c..3b4bb36ea 100644 --- a/docs/blog/2026-04-22-cloudflare-tunnel-migration/index.md +++ b/docs/blog/2026-04-22-cloudflare-tunnel-migration/index.md @@ -4,6 +4,7 @@ date: 2026-04-22 slug: cloudflare-tunnel-migration description: "Phase 33 replaces Cloudflare Tunnel with direct-connect agent workspaces that get their own public IPs. Here's what changed, why, and what it means for your deployment." tags: [platform, infrastructure, cloud, deployment] +og_image: /assets/blog/2026-04-21-chrome-devtools-mcp-og.png --- # Phase 33: From Cloudflare Tunnel to Direct Connect — How Molecule AI Agent Workspaces Get Their Own IP diff --git a/docs/blog/2026-04-22-cloudflare-tunnel-migration/social-copy.md b/docs/blog/2026-04-22-cloudflare-tunnel-migration/social-copy.md new file mode 100644 index 000000000..f671a88ea --- /dev/null +++ b/docs/blog/2026-04-22-cloudflare-tunnel-migration/social-copy.md @@ -0,0 +1,75 @@ +# Cloudflare Tunnel Migration — Social Copy +Campaign: Phase 33 direct-connect | Source: PR #1612 +Publish day: 2026-04-22 +Status: DRAFT — for Social Media Brand review + publish +Blog: `docs.moleculesai.app/blog/cloudflare-tunnel-migration` (pending) + +--- + +## X (Twitter) — 4-post thread + +### Post 1 — Hook +Your agent workspace has a new IP address. + +In Phase 33, every Molecule AI workspace in your cloud account gets its own public IP — direct-connect, no Cloudflare Tunnel in the path. + +That's a real change for how you run production agents. + +--- + +### Post 2 — What changed +Before Phase 33: every workspace connected through Cloudflare Tunnel (cloudflared). +Outbound-only, no firewall rules needed. But: extra latency, egress metered by Cloudflare, single dependency. + +After Phase 33: each workspace gets a VPC public IP. The platform connects directly. +Same security model, cleaner path. + +--- + +### Post 3 — The operational wins +Direct-connect workspaces mean: +→ curl the IP directly — no tunnel diagnostic dance +→ no Cloudflare egress costs at agent-fleet scale +→ no single dependency on Cloudflare edge availability +→ platform-controlled inbound rules via AWS security groups + +If you're running 10+ production agent workspaces, this compounds. + +--- + +### Post 4 — CTA +Phase 33 is live for all new cloud-hosted workspaces. + +Works with existing Molecule AI deployments — no config changes required. +Existing tunnel workspaces continue to work; direct-connect is the default for new provisions. + +→ [docs link] + +--- + +## LinkedIn — Single post + +**Title:** We replaced Cloudflare Tunnel with direct-connect agent workspaces. Here's what changed. + +When you run a cloud-hosted agent workspace, there are two ways it can connect to the platform: + +The old way: a lightweight daemon (Cloudflare Tunnel / cloudflared) runs inside the container, maintaining an outbound-only WebSocket to Cloudflare's edge. No inbound firewall rules required. Clean and simple — until you're running 20 agents at scale. + +That's the model Phase 33 replaces. + +Every new workspace in your cloud account now gets its own public IP from the VPC public subnet. The platform connects directly, with the same authentication and security model. No tunnel in the path. + +The operational differences matter at scale: +- **No egress costs** through Cloudflare's metered network — the workspace sends traffic directly from your VPC +- **Lower latency** — one fewer network hop through Cloudflare's edge +- **Direct diagnostics** — curl the IP, run network checks, SSH directly — no tunnel to debug +- **No single dependency** — if Cloudflare has an incident, your agents keep running + +For single-agent dev environments, the tunnel model was fine. For production agent fleets, direct-connect is the right trade-off. + +Phase 33 is live for all new cloud-hosted workspaces. Existing tunnel workspaces continue to function; direct-connect is the default going forward. + +→ [Read the architecture walkthrough](https://docs.molecule.ai/docs/guides/remote-workspaces) +→ [Molecule AI on GitHub](https://github.com/Molecule-AI/molecule-core) + +#DevOps #CloudComputing #AIAgents #AWS #MoleculeAI diff --git a/docs/blog/2026-04-23-partner-api-keys/index.md b/docs/blog/2026-04-23-partner-api-keys/index.md new file mode 100644 index 000000000..b3e270f7d --- /dev/null +++ b/docs/blog/2026-04-23-partner-api-keys/index.md @@ -0,0 +1,140 @@ +--- +title: "Ship Partner Integrations Faster with Programmatic Org Management" +date: 2026-04-23 +slug: partner-api-keys +description: "Partner API Keys let marketplace resellers, CI/CD pipelines, and automation tools create and manage Molecule AI orgs via API — no browser session required." +og_title: "Ship Partner Integrations Faster with Programmatic Org Management" +og_description: "Partner API Keys: scoped, rate-limited, revocable API keys for programmatic org management. Built for marketplaces, CI/CD, and automation platforms." +tags: [partner-api-keys, marketplace, ci-cd, automation, api, enterprise, provisioning] +keywords: [partner API keys, programmatic org management, marketplace integration, CI/CD automation, Molecule AI API, reseller integration, org provisioning API] +canonical: https://docs.molecule.ai/blog/partner-api-keys +--- + + + +# Ship Partner Integrations Faster with Programmatic Org Management + +When your platform needs to create an org — for a new customer, a CI environment, or a marketplace resale — the last thing you want is to hand that flow over to a human with a browser. Neither does your partner. + +Phase 34 is designed to solve exactly this problem. **Partner API Keys** give marketplace resellers, CI/CD pipelines, and automation platforms a programmatic way to create and manage Molecule AI orgs — no browser session, no admin dashboard, just an API call. + +## What Partner API Keys Do + +A Partner API Key is a scoped, rate-limited, revocable bearer token — prefixed `mol_pk_` — that lives at the `/cp/` control plane boundary. It authenticates to a set of partner-facing endpoints that let you provision an org, poll its status, and revoke the integration when it's no longer needed. + +Unlike org-scoped API keys (which operate *within* an org), Partner API Keys operate *at the org level*: they create orgs, list your own keys, and revoke themselves. The scope system lets you grant exactly the capabilities a partner needs — nothing more. + +```bash +POST /cp/admin/partner-keys +Authorization: Bearer +{ + "name": "acme-ci-pipeline", + "scopes": ["orgs:create", "orgs:list"], + "org_id": null +} + +# Response +{ + "id": "pak_01HXKM4...", + "key": "mol_pk_1a2b3c4d5e...", # shown ONCE + "name": "acme-ci-pipeline", + "scopes": ["orgs:create", "orgs:list"], + "created_at": "2026-04-23T08:00:00Z" +} +``` + +Your CI pipeline saves `mol_pk_1a2b3c4d5e...` as a secret and uses it to call the partner endpoints. + +## The Partner API Surface + +Once you have a Partner API Key, the integration flow looks like this: + +```bash +# 1. Create an org +POST /cp/orgs +Authorization: Bearer mol_pk_1a2b3c4d5e... +{ + "name": "acme-corp", + "slug": "acme-corp", + "plan": "standard" +} + +# Response +{ + "id": "org_01HXKM4...", + "slug": "acme-corp", + "status": "provisioning", + "created_at": "2026-04-23T08:00:00Z" +} + +# 2. Poll until ready +GET /cp/orgs/org_01HXKM4.../status +Authorization: Bearer mol_pk_1a2b3c4d5e... + +# 3. Redirect the customer +# → https://app.moleculesai.app/login?org=acme-corp + +# 4. Revoke when done +DELETE /cp/admin/partner-keys/pak_01HXKM4... +Authorization: Bearer mol_pk_1a2b3c4d5e... +``` + +Every call is audited: the audit log records which Partner API Key was used, when, and what it did — so you can trace a provisioning event back to the integration that triggered it. + +## Scopes and Rate Limits + +Partner API Keys are granted specific scopes at creation time. A CI pipeline might get `orgs:create` + `orgs:list`. A marketplace reseller might also need `workspaces:create`. A monitoring tool might only need `orgs:list`. + +``` +Available scopes: + orgs:create — provision new orgs + orgs:list — list partner-managed orgs + orgs:delete — deprovision orgs + workspaces:create — create workspaces within an org + billing:read — read subscription status +``` + +Rate limits are enforced per key, independently of the session rate limit. A misbehaving integration hits its own ceiling without affecting other partners or organic traffic. + +## The Marketplace Reseller Use Case + +Marketplace resellers need to provision a Molecule AI org on behalf of every end customer — automatically, at scale, without a human in the loop. They also need to: + +- **Scope the integration** to only the capabilities that partner needs +- **Revoke cleanly** when the reseller-customer relationship ends +- **Audit everything** for compliance reporting + +Partner API Keys handle all three. A reseller creates one key per integration tier (e.g. one key for the standard tier, one for enterprise), each scoped to exactly what that tier allows. When a customer churns, the reseller revokes their key — the org stays but the automation path is closed. + +## CI/CD: Ephemeral Test Orgs + +CI/CD pipelines benefit from the same pattern. A test suite that needs to validate the Molecule AI integration flow can: + +1. Create a temporary org via Partner API Key (`orgs:create`) +2. Run the integration tests against it +3. Delete the org when done (`orgs:delete`) +4. Revoke the key + +Each run gets a clean environment. No shared state, no test pollution, no manual cleanup. + +## Get Started + +Partner API Keys are available on **Partner and Enterprise plans**. To get started: + +- Contact your account team to request Partner API Key issuance +- Review the partner integration guide (coming soon) +- Example flows: create org → poll status → redirect to tenant; CI/CD test org lifecycle + +--- + +*Molecule AI is open source. Partner API Keys shipped in Phase 34 (2026-04-23). Available on Partner and Enterprise plans.* diff --git a/docs/devrel/demos/cloudflare-artifacts/README.md b/docs/devrel/demos/cloudflare-artifacts/README.md new file mode 100644 index 000000000..d171e207d --- /dev/null +++ b/docs/devrel/demos/cloudflare-artifacts/README.md @@ -0,0 +1,146 @@ +# Cloudflare Artifacts — Demo +**Issue:** #1479 | **Source:** PR #641 | **Handler:** `workspace-server/internal/handlers/artifacts.go` + +--- + +## What This Demo Shows + +1. Attach a Cloudflare Artifacts Git repo to a workspace +2. Mint a short-lived git credential (shown once, never stored server-side) +3. Clone, write a file, commit, push — every agent run becomes a Git commit +4. Fork the repo before a risky experiment + +**Time:** ~3 min | **Requirements:** `pip install requests` + +--- + +## Quick Start + +```bash +export PLATFORM_URL=https://your-deployment.moleculesai.app +export WORKSPACE_TOKEN=your-workspace-token +export WORKSPACE_ID=your-workspace-id + +python demo.py +``` + +### Offline mode (no platform needed) + +```bash +python demo.py +# Simulated responses — no credentials required +``` + +--- + +## Step-by-Step Walkthrough + +### Step 1 — Attach a Cloudflare Artifacts repo + +```bash +curl -s -X POST "$PLATFORM_URL/workspaces/$WORKSPACE_ID/artifacts" \ + -H "Authorization: Bearer $WORKSPACE_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name": "agent-demo", "description": "Demo workspace"}' | jq . +``` + +```json +{ + "id": "wa_abc123", + "workspace_id": "ws-demo-001", + "cf_repo_name": "molecule-ws-demo", + "cf_namespace": "molecule-prod", + "remote_url": "https://artifacts.cloudflare.net/git/molecule-ws-demo", + "created_at": "2026-04-23T10:00:00Z" +} +``` + +### Step 2 — Mint a short-lived Git credential + +```bash +curl -s -X POST "$PLATFORM_URL/workspaces/$WORKSPACE_ID/artifacts/token" \ + -H "Authorization: Bearer $WORKSPACE_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"scope": "write", "ttl": 3600}' | jq . +``` + +```json +{ + "token_id": "tok_xyz789", + "token": "cf_tok_abc123...", + "scope": "write", + "expires_at": "2026-04-23T11:00:00Z", + "clone_url": "https://x:cf_tok_abc123...@artifacts.cloudflare.net/git/molecule-ws-demo.git", + "message": "Save this token — it cannot be retrieved again." +} +``` + +> **Copy the token now.** It's shown exactly once at mint time. + +### Step 3 — Git clone, write, commit, push + +```bash +git clone https://x:$TOKEN@artifacts.cloudflare.net/git/molecule-ws-demo.git demo-workspace +cd demo-workspace + +# Agent writes its work as a Git commit +echo "# Agent Run — $(date)" > AGENT_SNAPSHOT.md +git add AGENT_SNAPSHOT.md +git commit -m "feat: agent run snapshot" +git push origin main +``` + +### Step 4 — Fork before a risky experiment + +```bash +curl -s -X POST "$PLATFORM_URL/workspaces/$WORKSPACE_ID/artifacts/fork" \ + -H "Authorization: Bearer $WORKSPACE_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name": "agent-demo/experiment", "default_branch_only": true}' | jq . +``` + +```json +{ + "fork": {"name": "agent-demo/experiment", "namespace": "molecule-prod"}, + "object_count": 14 +} +``` + +Fork succeeds → merge back. Fork fails → discard. Main stays clean. + +--- + +## API Reference + +| Method | Path | Description | +|--------|------|-------------| +| POST | `/workspaces/:id/artifacts` | Attach/create CF Artifacts repo | +| GET | `/workspaces/:id/artifacts` | Get linked repo info | +| POST | `/workspaces/:id/artifacts/token` | Mint short-lived git credential | +| POST | `/workspaces/:id/artifacts/fork` | Fork the workspace's primary repo | +| DELETE | `/workspaces/:id/artifacts` | Detach the linked repo | + +--- + +## Key Design Decisions + +### Credentials never stored server-side +The plaintext token is returned **only at mint time** — `stripCredentials()` removes `x:@` from the URL before the DB row is written. The token value is never persisted. + +### Per-call token minting +Each `git push` uses a fresh short-lived credential. The token TTL defaults to 3600s (1 hour), max 7 days. Compromised token = 1-hour window. + +### SSRF protection +Import URLs (`POST /workspaces/:id/artifacts` with `import_url`) must use `https://`. Any other scheme returns 400. + +### Forks not recorded in DB +`POST /artifacts/fork` creates a CF-side fork but does not write a `workspace_artifacts` row — the caller owns the fork, not the platform. + +--- + +## Files + +- `demo.py` — Runnable Python demo (simulated + live modes) +- `demo.md` — Original script-style demo (`docs/marketing/devrel/demos/cloudflare-artifacts-demo.md`) +- Handler: `workspace-server/internal/handlers/artifacts.go` +- Tests: `workspace-server/internal/handlers/artifacts_test.go` diff --git a/docs/devrel/demos/cloudflare-artifacts/demo.py b/docs/devrel/demos/cloudflare-artifacts/demo.py new file mode 100644 index 000000000..8d8004827 --- /dev/null +++ b/docs/devrel/demos/cloudflare-artifacts/demo.py @@ -0,0 +1,344 @@ +#!/usr/bin/env python3 +""" +demo.py — Cloudflare Artifacts Demo +==================================== +Issue: #1479 | Source: PR #641 (`feat: workspace git artifacts (Cloudflare)`) +Handler: workspace-server/internal/handlers/artifacts.go + +Demonstrates the Cloudflare Artifacts integration: +1. Attach a CF Artifacts Git repo to a workspace (POST /workspaces/:id/artifacts) +2. Mint a short-lived git credential (POST /workspaces/:id/artifacts/token) +3. Clone, commit, push from the agent +4. Fork the repo before a risky experiment + +Requirements: pip install requests + +Usage: + export PLATFORM_URL=https://your-deployment.moleculesai.app + export WORKSPACE_TOKEN=your-workspace-token + export WORKSPACE_ID=your-workspace-id + python demo.py + +──────────────────────────────────────────────────────────────────────────── +""" + +from __future__ import annotations + +import json, os, re, shutil, subprocess, tempfile, textwrap, time +from dataclasses import dataclass +from typing import Optional + +try: + import requests +except ImportError: + raise SystemExit("pip install requests # HTTP client for Molecule AI API") + + +PLATFORM_URL = os.environ.get("PLATFORM_URL", "https://your-deployment.moleculesai.app") +WORKSPACE_TOKEN = os.environ.get("WORKSPACE_TOKEN", "your-workspace-token") +WORKSPACE_ID = os.environ.get("WORKSPACE_ID", "ws-demo-001") + + +# ───────────────────────────────────────────────────────────────────────────── +# Utilities +# ───────────────────────────────────────────────────────────────────────────── + +def is_live_platform() -> bool: + """Return True only when credentials point to a real deployment.""" + if "your-deployment" in PLATFORM_URL: + return False + if PLATFORM_URL.startswith("http://") and "localhost" not in PLATFORM_URL and "platform" not in PLATFORM_URL: + return False + if WORKSPACE_TOKEN in ("", "your-workspace-token", "demo-token"): + return False + return True + + +def divider(title: str) -> None: + d = "═" * 68 + print(f"\n {d}") + print(f" {title}") + print(f" {d}\n") + + +# ───────────────────────────────────────────────────────────────────────────── +# API client +# ───────────────────────────────────────────────────────────────────────────── + +class ArtifactsClient: + def __init__(self, platform_url: str, workspace_token: str, workspace_id: str): + self.base = platform_url.rstrip("/") + self.hdrs = {"Authorization": f"Bearer {workspace_token}", "Content-Type": "application/json"} + self.ws = workspace_id + + def _url(self, path: str) -> str: + return f"{self.base}/workspaces/{self.ws}{path}" + + def _post(self, path: str, data: Optional[dict] = None) -> requests.Response: + r = requests.post(self._url(path), headers=self.hdrs, json=data or {}, timeout=15) + r.raise_for_status() + return r + + def _get(self, path: str) -> requests.Response: + r = requests.get(self._url(path), headers=self.hdrs, timeout=15) + r.raise_for_status() + return r + + def _delete(self, path: str) -> requests.Response: + r = requests.delete(self._url(path), headers=self.hdrs, timeout=15) + r.raise_for_status() + return r + + # POST /workspaces/:id/artifacts — create/link a CF Artifacts repo + def attach_repo(self, name: str = "", description: str = "", + import_url: str = "", read_only: bool = False) -> dict: + payload = {"description": description, "read_only": read_only} + if name: + payload["name"] = name + if import_url: + payload["import_url"] = import_url # must be https:// + return self._post("/artifacts", payload).json() + + # GET /workspaces/:id/artifacts — get linked repo info + def get_repo(self) -> dict: + return self._get("/artifacts").json() + + # POST /workspaces/:id/artifacts/token — mint a short-lived git credential + def mint_token(self, scope: str = "write", ttl: int = 3600) -> dict: + return self._post("/artifacts/token", {"scope": scope, "ttl": ttl}).json() + + # POST /workspaces/:id/artifacts/fork — fork the workspace's primary repo + def fork_repo(self, name: str, description: str = "", + default_branch_only: bool = True) -> dict: + return self._post("/artifacts/fork", { + "name": name, + "description": description, + "default_branch_only": default_branch_only, + }).json() + + # DELETE /workspaces/:id/artifacts — detach the linked repo + def detach_repo(self) -> None: + self._delete("/artifacts") + + +# ───────────────────────────────────────────────────────────────────────────── +# Git helpers +# ───────────────────────────────────────────────────────────────────────────── + +@dataclass +class GitResult: + success: bool + stdout: str + stderr: str + command: str + +def run_git(cwd: str, *args: str) -> GitResult: + cmd = ["git", "-C", cwd] + list(args) + r = subprocess.run(cmd, capture_output=True, text=True) + return GitResult(success=r.returncode == 0, stdout=r.stdout, + stderr=r.stderr, command=" ".join(cmd)) + + +def clone_and_push(clone_url: str, repo_dir: str, + commit_msg: str, file_content: str, + file_path: str = "AGENT_SNAPSHOT.md") -> GitResult: + """Clone, write file, commit, push. Cleans up temp dir on exit.""" + tmpdir = tempfile.mkdtemp(prefix="cf-artifacts-") + try: + r = run_git(tmpdir, "clone", "--quiet", clone_url, repo_dir) + if not r.success: + return r + target = os.path.join(tmpdir, repo_dir) + with open(os.path.join(target, file_path), "w") as f: + f.write(file_content) + run_git(target, "config", "user.email", "agent@molecule.ai") + run_git(target, "config", "user.name", "Molecule AI Agent") + run_git(target, "add", file_path) + r = run_git(target, "commit", "-m", commit_msg) + if not r.success: + return r + return run_git(target, "push", "-q", "origin", "HEAD") + finally: + shutil.rmtree(tmpdir, ignore_errors=True) + + +# ───────────────────────────────────────────────────────────────────────────── +# Simulated responses (no live platform needed) +# ───────────────────────────────────────────────────────────────────────────── + +def simulate_attach_repo() -> dict: + return { + "id": "wa_abc123", "workspace_id": WORKSPACE_ID, + "cf_repo_name": "molecule-ws-demo", "cf_namespace": "molecule-prod", + "remote_url": "https://artifacts.cloudflare.net/git/molecule-ws-demo", + "description": "Demo workspace", "created_at": "2026-04-23T10:00:00Z", + } + +def simulate_mint_token() -> dict: + return { + "token_id": "tok_xyz789", "token": "cf_tok_demo_abc123xyz", + "scope": "write", "expires_at": "2026-04-23T11:00:00Z", + "clone_url": "https://x:cf_tok_demo_abc123xyz@artifacts.cloudflare.net/git/molecule-ws-demo.git", + "message": "Save this token — it cannot be retrieved again.", + } + +def simulate_fork_repo() -> dict: + return { + "fork": {"name": "molecule-ws-demo/experiment", "namespace": "molecule-prod", + "remote_url": "https://artifacts.cloudflare.net/git/molecule-ws-demo-experiment"}, + "object_count": 14, + "remote_url": "https://artifacts.cloudflare.net/git/molecule-ws-demo-experiment", + } + + +# ───────────────────────────────────────────────────────────────────────────── +# Main +# ───────────────────────────────────────────────────────────────────────────── + +def main(): + is_live = is_live_platform() + + print(""" + ╔══════════════════════════════════════════════════════════════════════╗ + ║ Cloudflare Artifacts Demo — PR #641 (molecule-core) ║ + ║ ║ + ║ Every Molecule AI workspace can have its own Git repo on ║ + ║ Cloudflare's edge — versioned snapshots, isolated forks, ║ + ║ short-lived credentials. ║ + ╚══════════════════════════════════════════════════════════════════════╝ + """) + + # ── Step 1 ──────────────────────────────────────────────────────────── + divider("Step 1 — Attach a Cloudflare Artifacts repo") + print(" POST /workspaces/:id/artifacts") + print(" Body: {\"name\": \"agent-demo\", \"description\": \"Demo workspace\"}") + print() + if is_live: + print(" → calling live platform...") + try: + result = ArtifactsClient(PLATFORM_URL, WORKSPACE_TOKEN, WORKSPACE_ID).attach_repo( + name="agent-demo", description="Demo workspace") + print(f" ✓ Repo created: {result['cf_repo_name']}") + except Exception as e: + print(f" ✗ Error: {e}") + else: + result = simulate_attach_repo() + print(f" ✓ Repo linked:") + print(f" cf_repo_name : {result['cf_repo_name']}") + print(f" cf_namespace : {result['cf_namespace']}") + print(f" remote_url : {result['remote_url']}") + + # ── Step 2 ──────────────────────────────────────────────────────────── + divider("Step 2 — Mint a short-lived Git credential") + print(" POST /workspaces/:id/artifacts/token") + print(" Body: {\"scope\": \"write\", \"ttl\": 3600}") + print() + if is_live: + print(" → calling live platform...") + try: + token_resp = ArtifactsClient(PLATFORM_URL, WORKSPACE_TOKEN, WORKSPACE_ID).mint_token() + clone_url = token_resp["clone_url"] + print(f" ✓ Token minted (expires: {token_resp['expires_at']})") + print(f" clone_url: {clone_url[:60]}...") + except Exception as e: + print(f" ✗ Error: {e}") + clone_url = None + else: + token_resp = simulate_mint_token() + clone_url = token_resp["clone_url"] + print(f" ✓ Token minted:") + print(f" token_id : {token_resp['token_id']}") + print(f" scope : {token_resp['scope']}") + print(f" expires_at : {token_resp['expires_at']}") + print(f" clone_url : {token_resp['clone_url'][:60]}...") + + # ── Step 3 ──────────────────────────────────────────────────────────── + divider("Step 3 — Git clone, write, commit, push") + print(" The agent uses the clone_url from Step 2:") + print() + print(" git clone demo-workspace") + print(" # write AGENT_SNAPSHOT.md") + print(" git add AGENT_SNAPSHOT.md") + print(" git commit -m 'feat: agent run snapshot'") + print(" git push origin HEAD") + print() + print(" Every agent run becomes a Git commit — versioned, auditable,") + print(" and fork-able before a risky experiment.") + print() + if is_live and clone_url: + snapshot = f"# Agent Run — {time.strftime('%Y-%m-%d %H:%M UTC')}\nWorkspace: {WORKSPACE_ID}\n" + r = clone_and_push(clone_url, "demo-workspace", "feat: demo agent run snapshot", snapshot) + if r.success: + print(f" ✓ Committed and pushed.") + else: + print(f" ✗ Git error: {r.stderr.strip()}") + else: + print(" ⚠ SKIPPED (set PLATFORM_URL + WORKSPACE_TOKEN for live git ops)") + + # ── Step 4 ──────────────────────────────────────────────────────────── + divider("Step 4 — Fork before a risky experiment") + print(" POST /workspaces/:id/artifacts/fork") + print(" Body: {\"name\": \"agent-demo/experiment\", \"default_branch_only\": true}") + print() + print(" A fork is an isolated copy. Main stays clean.") + print(" If the experiment succeeds: merge back. If it fails: discard fork.") + print() + if is_live: + print(" → calling live platform...") + try: + fork_resp = ArtifactsClient(PLATFORM_URL, WORKSPACE_TOKEN, WORKSPACE_ID).fork_repo( + name="agent-demo/experiment", + description="Fork for experimental auth strategy", + default_branch_only=True) + print(f" ✓ Fork created ({fork_resp.get('object_count','?')} objects)") + print(f" fork_url: {fork_resp.get('remote_url','')}") + except Exception as e: + print(f" ✗ Error: {e}") + else: + fork_resp = simulate_fork_repo() + print(f" ✓ Fork created:") + print(f" name : {fork_resp['fork']['name']}") + print(f" object_count : {fork_resp['object_count']}") + print(f" remote_url : {fork_resp['remote_url']}") + + # ── Architecture ──────────────────────────────────────────────────────── + divider("Architecture Summary") + print(textwrap.dedent("""\ + POST /workspaces/:id/artifacts + → CF Artifacts API: CreateRepo / ImportRepo + → workspace_artifacts DB row (credentials stripped — never persisted) + + POST /workspaces/:id/artifacts/token + → CF API: CreateToken (short-lived, scoped) + → Returns: token (shown once) + clone_url + → Credential never stored server-side + + Agent side + → git clone + → git commit (agent run snapshot) + → git push (pushed to CF edge git — fast global reads) + + POST /workspaces/:id/artifacts/fork + → CF API: ForkRepo + → NOT recorded in workspace_artifacts — caller owns the fork + + Security model: + • CF_ARTIFACTS_API_TOKEN stored in platform env, not in DB + • Repo credentials stripped before DB persistence (stripCredentials) + • Per-call token minting — each git op uses a short-lived credential + • Token scope: read | write, max TTL 7 days + • Import URLs must be https:// (SSRF protection in artifacts.go:168) + """)) + + divider("Reference") + print(" Handler : workspace-server/internal/handlers/artifacts.go") + print(" Tests : workspace-server/internal/handlers/artifacts_test.go") + print(" DB table: workspace_artifacts") + print(" Env vars: CF_ARTIFACTS_API_TOKEN, CF_ARTIFACTS_NAMESPACE") + print() + print(" Set PLATFORM_URL + WORKSPACE_TOKEN to run against a live platform.") + print(" Demo path: docs/marketing/devrel/demos/cloudflare-artifacts/") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/docs/devrel/demos/cloudflare-artifacts/narration.mp3 b/docs/devrel/demos/cloudflare-artifacts/narration.mp3 new file mode 100644 index 000000000..f88abe805 Binary files /dev/null and b/docs/devrel/demos/cloudflare-artifacts/narration.mp3 differ diff --git a/docs/devrel/demos/cloudflare-artifacts/narration.txt b/docs/devrel/demos/cloudflare-artifacts/narration.txt new file mode 100644 index 000000000..060517260 --- /dev/null +++ b/docs/devrel/demos/cloudflare-artifacts/narration.txt @@ -0,0 +1,13 @@ +Every Molecule AI workspace can now have its own versioned Git repo on Cloudflare's edge. + +Here's how it works in three steps. + +First: attach a Cloudflare Artifacts Git repo to a workspace with a single API call. The platform calls the CF Artifacts API, creates the repo, and links it to your workspace. The remote URL is returned, with credentials stripped — nothing sensitive is stored. + +Second: mint a short-lived Git credential. Each push gets a fresh token, scoped to this workspace, valid for up to seven days. The plaintext token is shown exactly once at mint time. After that, it's gone from the server — only the hash is kept. + +Third: clone, commit, push. The agent pulls the repo, writes its work as a Git commit — every agent run becomes a versioned snapshot — and pushes it back. Nothing is lost. Every decision is traceable. + +And before a risky experiment: fork first. The fork creates an isolated copy on Cloudflare. If the experiment succeeds, merge back. If it fails, discard the fork. Main stays clean. + +Cloudflare Artifacts: versioned snapshots, isolated forks, short-lived credentials. Every agent run is a Git commit. diff --git a/docs/devrel/demos/partner-api-keys-demo/README.md b/docs/devrel/demos/partner-api-keys-demo/README.md new file mode 100644 index 000000000..ae64063b1 --- /dev/null +++ b/docs/devrel/demos/partner-api-keys-demo/README.md @@ -0,0 +1,157 @@ +# Partner API Keys — Demo +**Phase:** 34 | **Feature:** `mol_pk_*` | **Handler:** `workspace-server/internal/handlers/partner_keys.go` + +--- + +## What This Demo Shows + +1. Create a partner-scoped API key with minimal scopes +2. Use the partner key to create an ephemeral org (CI/CD use case) +3. Poll org status, create a workspace +4. Teardown: DELETE the org (billing stops immediately) +5. Revoke a partner key — next request returns 401 + +**Requirements:** `pip install requests` + +--- + +## Quick Start + +```bash +export PLATFORM_URL=https://your-deployment.moleculesai.app +export ADMIN_TOKEN=your-admin-token + +python demo.py +``` + +### Offline mode (no platform needed) + +```bash +python demo.py +# Uses simulated responses — no credentials required +``` + +--- + +## Step-by-Step Walkthrough + +### Step 1 — Create a partner key + +```bash +curl -s -X POST "$PLATFORM_URL/cp/admin/partner-keys" \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name": "ci-pipeline-key", "scopes": ["orgs:create", "orgs:list", "workspaces:create"]}' | jq . +``` + +```json +{ + "id": "pak_01HXKM4ABC", + "key": "mol_pk_live_abc123xyzci-pipel789...", + "name": "ci-pipeline-key", + "scopes": ["orgs:create", "orgs:list", "workspaces:create"], + "created_at": "2026-04-23T08:00:00Z" +} +``` + +> Copy the key now — it's shown exactly once. + +### Step 2 — Create an ephemeral org + +```bash +curl -s -X POST "$PLATFORM_URL/cp/orgs" \ + -H "Authorization: Bearer $PARTNER_KEY" \ + -H "Content-Type: application/json" \ + -d '{"name": "test-pr-123", "plan": "ephemeral"}' | jq . +``` + +```json +{"id": "org_01HXKM4ABC", "name": "test-pr-123", "status": "provisioning"} +``` + +### Step 3 — Poll until active, create workspace + +```bash +# Poll +curl -s "$PLATFORM_URL/cp/orgs/org_01HXKM4ABC" \ + -H "Authorization: Bearer $PARTNER_KEY" | jq '.status' +# → "active" + +# Create workspace in the org +curl -s -X POST "$PLATFORM_URL/cp/orgs/org_01HXKM4ABC/workspaces" \ + -H "Authorization: Bearer $PARTNER_KEY" \ + -H "Content-Type: application/json" \ + -d '{"name": "pr-123-test"}' | jq . +``` + +### Step 4 — Teardown + +```bash +curl -s -X DELETE "$PLATFORM_URL/cp/orgs/org_01HXKM4ABC" \ + -H "Authorization: Bearer $PARTNER_KEY" +# → 204 No Content — billing stops immediately +``` + +### Step 5 — Revoke a key + +```bash +curl -s -X DELETE "$PLATFORM_URL/cp/admin/partner-keys/pak_01HXKM4ABC" \ + -H "Authorization: Bearer $ADMIN_TOKEN" +# → 204 No Content — next mol_pk_* request returns 401 +``` + +--- + +## API Reference + +| Method | Path | Auth | Description | +|--------|------|------|-------------| +| POST | `/cp/admin/partner-keys` | Admin | Create a partner key | +| GET | `/cp/admin/partner-keys` | Admin | List all partner keys | +| DELETE | `/cp/admin/partner-keys/:id` | Admin | Revoke a partner key | +| POST | `/cp/orgs` | Partner key | Create an org | +| GET | `/cp/orgs/:id` | Partner key | Get org status | +| DELETE | `/cp/orgs/:id` | Partner key | Delete an org | +| POST | `/cp/orgs/:id/workspaces` | Partner key | Create workspace in org | + +--- + +## Key Design Decisions + +### `mol_pk_*` vs workspace/org tokens + +| Token type | Scope | +|-----------|-------| +| Workspace token | One workspace | +| Org token | All workspaces in one org | +| **Partner key (`mol_pk_*`)** | **Org-level operations only** | + +Partner keys create orgs and manage their lifecycle. They cannot access workspace sub-routes (secrets, agents, files, etc.). + +### Plaintext shown once + +The plaintext key is returned only at creation. The server stores SHA-256 hash only. If lost, revoke and recreate. + +### Ephemeral org lifecycle + +1. `POST /cp/orgs` — org starts in `provisioning` state +2. Poll `GET /cp/orgs/:id` until `status: "active"` +3. Create workspaces, run tests +4. `DELETE /cp/orgs/:id` — immediately stops billing + +### Security model + +- Keys are org-scoped by design — cannot escape their boundary +- Per-key rate limiter (separate from session limits) +- `last_used_at` tracked on every request +- `mol_pk_` added to pre-commit secret scanner + +--- + +## Files + +- `demo.py` — Runnable Python demo (simulated + live modes) +- Handler: `workspace-server/internal/handlers/partner_keys.go` +- Blog: `docs/blog/2026-04-23-partner-api-keys/` +- Battlecard: `docs/marketing/battlecard/phase-34-partner-api-keys-battlecard.md` +- TTS narration: `docs/devrel/phase-34-partner-api-keys-screencast-narration.mp3` diff --git a/docs/devrel/demos/partner-api-keys-demo/demo.py b/docs/devrel/demos/partner-api-keys-demo/demo.py new file mode 100644 index 000000000..f199ed561 --- /dev/null +++ b/docs/devrel/demos/partner-api-keys-demo/demo.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python3 +""" +demo.py — Phase 34 Partner API Keys Demo +========================================= +Phase: 34 | Source: PR #TBD (`feat: partner api keys`) +Handler: workspace-server/internal/handlers/partner_keys.go + +Demonstrates the Partner API Keys integration: +1. Create a partner-scoped key (POST /cp/admin/partner-keys) +2. Use the partner key to create an ephemeral org (POST /cp/orgs) +3. Poll org status until ready, then create a workspace +4. Revoke the partner key — next request returns 401 + +Requirements: pip install requests + +Usage: + export PLATFORM_URL=https://your-deployment.moleculesai.app + export ADMIN_TOKEN=your-admin-token + python demo.py + +──────────────────────────────────────────────────────────────────────────── +""" + +from __future__ import annotations + +import json, os, textwrap, time +from dataclasses import dataclass +from typing import Optional + +try: + import requests +except ImportError: + raise SystemExit("pip install requests # HTTP client for Molecule AI API") + + +PLATFORM_URL = os.environ.get("PLATFORM_URL", "https://your-deployment.moleculesai.app") +ADMIN_TOKEN = os.environ.get("ADMIN_TOKEN", "your-admin-token") + + +# ───────────────────────────────────────────────────────────────────────────── +# Utilities +# ───────────────────────────────────────────────────────────────────────────── + +def is_live_platform() -> bool: + """Return True only when credentials point to a real deployment.""" + if "your-deployment" in PLATFORM_URL: + return False + if PLATFORM_URL.startswith("http://") and "localhost" not in PLATFORM_URL: + return False + if ADMIN_TOKEN in ("", "your-admin-token"): + return False + return True + + +def divider(title: str) -> None: + d = "═" * 68 + print(f"\n {d}") + print(f" {title}") + print(f" {d}\n") + + +# ───────────────────────────────────────────────────────────────────────────── +# API client +# ───────────────────────────────────────────────────────────────────────────── + +class PartnerKeysClient: + def __init__(self, platform_url: str, admin_token: str): + self.base = platform_url.rstrip("/") + self.admin_hdrs = {"Authorization": f"Bearer {admin_token}", "Content-Type": "application/json"} + + def _url(self, path: str) -> str: + return f"{self.base}{path}" + + def _req(self, method: str, path: str, headers: dict, **kwargs) -> requests.Response: + r = requests.request(method, self._url(path), headers=headers, timeout=15, **kwargs) + r.raise_for_status() + return r + + # POST /cp/admin/partner-keys — create a partner key + def create_key(self, name: str, scopes: list[str], + description: str = "") -> dict: + return self._req("POST", "/cp/admin/partner-keys", + headers=self.admin_hdrs, + json={"name": name, "scopes": scopes, + "description": description}).json() + + # GET /cp/admin/partner-keys — list all partner keys + def list_keys(self) -> dict: + return self._req("GET", "/cp/admin/partner-keys", + headers=self.admin_hdrs).json() + + # DELETE /cp/admin/partner-keys/:id — revoke a partner key + def revoke_key(self, key_id: str) -> requests.Response: + return self._req("DELETE", f"/cp/admin/partner-keys/{key_id}", + headers=self.admin_hdrs) + + # POST /cp/orgs — create an org using a partner key + def create_org(self, partner_key: str, name: str, + slug: str = "", plan: str = "standard") -> dict: + partner_hdrs = {"Authorization": f"Bearer {partner_key}", + "Content-Type": "application/json"} + payload = {"name": name, "plan": plan} + if slug: + payload["slug"] = slug + return self._req("POST", "/cp/orgs", + headers=partner_hdrs, + json=payload).json() + + # GET /cp/orgs/:id — poll org status + def get_org(self, partner_key: str, org_id: str) -> dict: + partner_hdrs = {"Authorization": f"Bearer {partner_key}", + "Content-Type": "application/json"} + return self._req("GET", f"/cp/orgs/{org_id}", + headers=partner_hdrs).json() + + # DELETE /cp/orgs/:id — delete an org + def delete_org(self, partner_key: str, org_id: str) -> requests.Response: + partner_hdrs = {"Authorization": f"Bearer {partner_key}"} + return self._req("DELETE", f"/cp/orgs/{org_id}", + headers=partner_hdrs) + + # POST /cp/orgs/:org_id/workspaces — create a workspace in the org + def create_workspace(self, partner_key: str, org_id: str, + name: str, plan: str = "standard") -> dict: + partner_hdrs = {"Authorization": f"Bearer {partner_key}", + "Content-Type": "application/json"} + return self._req("POST", f"/cp/orgs/{org_id}/workspaces", + headers=partner_hdrs, + json={"name": name, "plan": plan}).json() + + +# ───────────────────────────────────────────────────────────────────────────── +# Simulated responses (no live platform needed) +# ───────────────────────────────────────────────────────────────────────────── + +def simulate_create_key(name: str = "ci-pipeline-key") -> dict: + return { + "id": "pak_01HXKM4ABC", + "key": f"mol_pk_live_abc123xyz{name[:8]}789", + "name": name, + "scopes": ["orgs:create", "orgs:list", "workspaces:create"], + "created_at": "2026-04-23T08:00:00Z", + "message": "Save this key — it cannot be retrieved again.", + } + +def simulate_create_org(partner_key: str, name: str = "test-pr-123") -> dict: + return { + "id": f"org_{name[:8].upper()}", + "name": name, + "slug": name.lower().replace(" ", "-"), + "status": "provisioning", + "created_at": "2026-04-23T08:01:00Z", + } + +def simulate_get_org(org_id: str) -> dict: + return { + "id": org_id, + "status": "active", + "created_at": "2026-04-23T08:01:00Z", + } + + +# ───────────────────────────────────────────────────────────────────────────── +# Main +# ───────────────────────────────────────────────────────────────────────────── + +def main(): + is_live = is_live_platform() + client = PartnerKeysClient(PLATFORM_URL, ADMIN_TOKEN) if is_live else None + + print(""" + ╔══════════════════════════════════════════════════════════════════════╗ + ║ Partner API Keys Demo — Phase 34 (molecule-core) ║ + ║ ║ + ║ mol_pk_* keys let CI/CD pipelines, marketplace resellers, ║ + ║ and automation platforms create and manage orgs via API — ║ + ║ no browser session required. ║ + ╚══════════════════════════════════════════════════════════════════════╝ + """) + + # ── Step 1 ──────────────────────────────────────────────────────────── + divider("Step 1 — Create a partner-scoped API key") + print(" POST /cp/admin/partner-keys") + print(" Body: {\"name\": \"ci-pipeline-key\", \"scopes\": [\"orgs:create\", \"orgs:list\"]}") + print() + if is_live: + print(" → calling live platform...") + try: + result = client.create_key(name="ci-pipeline-key", + scopes=["orgs:create", "orgs:list", "workspaces:create"], + description="CI pipeline integration") + print(f" ✓ Key created: {result['key'][:30]}...") + print(f" scopes: {result['scopes']}") + partner_key = result["key"] + except Exception as e: + print(f" ✗ Error: {e}") + partner_key = None + else: + result = simulate_create_key() + partner_key = result["key"] + print(f" ✓ Partner key created:") + print(f" id : {result['id']}") + print(f" key : {result['key'][:30]}...") + print(f" scopes: {result['scopes']}") + print(f" {result['message']}") + + # ── Step 2 ──────────────────────────────────────────────────────────── + divider("Step 2 — Create an ephemeral org with the partner key") + print(" POST /cp/orgs (authenticated with mol_pk_*)") + print(" Body: {\"name\": \"test-pr-123\", \"plan\": \"ephemeral\"}") + print() + if is_live and partner_key: + print(" → calling live platform...") + try: + org = client.create_org(partner_key, name="test-pr-123", plan="ephemeral") + org_id = org["id"] + print(f" ✓ Org created: {org_id} (status: {org.get('status', 'provisioning')})") + except Exception as e: + print(f" ✗ Error: {e}") + org_id = None + else: + org = simulate_create_org(partner_key, "test-pr-123") + org_id = org["id"] + print(f" ✓ Ephemeral org created:") + print(f" org_id: {org_id}") + print(f" status: {org['status']}") + + # ── Step 3 ──────────────────────────────────────────────────────────── + if org_id: + divider("Step 3 — Poll until org is active, then create a workspace") + print(f" GET /cp/orgs/{org_id}") + print() + if is_live and partner_key: + print(" → polling org status (simulated poll loop)...") + # Poll up to 5 times with 1s delay + for i in range(5): + org_status = client.get_org(partner_key, org_id) + if org_status.get("status") == "active": + print(f" ✓ Org active: {org_id}") + break + print(f" attempt {i+1}: status={org_status.get('status')}") + time.sleep(1) + # Create workspace + try: + ws = client.create_workspace(partner_key, org_id, name="pr-123-test") + print(f" ✓ Workspace created: {ws.get('id', '?')}") + except Exception as e: + print(f" ✗ Workspace create error: {e}") + else: + org_status = simulate_get_org(org_id) + print(f" ✓ Org polled: status={org_status['status']}") + print(f" ✓ Workspace create: pr-123-test (simulated)") + + # ── Step 4 ──────────────────────────────────────────────────────────── + divider("Step 4 — Ephemeral teardown: DELETE the org") + print(" DELETE /cp/orgs/:id (authenticated with mol_pk_*)") + print() + print(" Billing stops immediately. No orphaned resources.") + print() + if is_live and partner_key and org_id: + print(" → calling live platform...") + try: + r = client.delete_org(partner_key, org_id) + print(f" ✓ Org deleted (status: {r.status_code})") + except Exception as e: + print(f" ✗ Error: {e}") + else: + print(f" Simulated DELETE /cp/orgs/{org_id}") + print(" → 204 No Content") + print(" ✓ Ephemeral org destroyed — billing stopped") + + # ── Step 5 ──────────────────────────────────────────────────────────── + divider("Step 5 — Revoke a compromised partner key") + print(" DELETE /cp/admin/partner-keys/:id (admin-only)") + print() + print(" Compromised key? One call. Next request → 401.") + print() + if is_live: + print(" → calling live platform...") + try: + # First list keys, then revoke the first one + keys = client.list_keys() + key_id = keys["keys"][0]["id"] + r = client.revoke_key(key_id) + print(f" ✓ Key revoked (status: {r.status_code})") + # Verify: try to list again + r2 = client.list_keys() + remaining = [k for k in r2.get("keys", []) if k["id"] != key_id] + print(f" ✓ Verification: {len(remaining)} key(s) remain") + except Exception as e: + print(f" ✗ Error: {e}") + else: + print(" Simulated DELETE /cp/admin/partner-keys/pak_01HXKM4ABC") + print(" → 204 No Content") + print(" ✓ Key is dead on the next request — no propagation delay") + + # ── Architecture ──────────────────────────────────────────────────────── + divider("Architecture Summary") + print(textwrap.dedent("""\ + Admin creates a partner key: + POST /cp/admin/partner-keys + → returns plaintext key (shown ONCE) + → SHA-256 hash stored server-side + + Partner uses the key: + POST /cp/orgs — create org within partner's scope + GET /cp/orgs/:id — poll until active + DELETE /cp/orgs/:id — tear down, billing stops + POST /cp/orgs/:id/workspaces — create workspaces in the org + + Key revocation: + DELETE /cp/admin/partner-keys/:id (admin-only) + → next request with that key → 401 immediately + + Security model: + • mol_pk_* keys are org-scoped — cannot escape their org boundary + • Plaintext shown once at creation, SHA-256 hash stored + • Per-key rate limiter (separate from session limits) + • last_used_at tracked on every request + • mol_pk_ added to pre-commit secret scanner + + Phase 34 also shipped: + • Tool Trace — execution record in every A2A response + • Platform Instructions — org-level system prompt via API + • SaaS Fed v2 — improved multi-org federation + """)) + + divider("Reference") + print(" Handler : workspace-server/internal/handlers/partner_keys.go") + print(" DB table : partner_api_keys") + print(" Blog : docs/blog/2026-04-23-partner-api-keys/") + print(" Battlecard: docs/marketing/battlecard/phase-34-partner-api-keys-battlecard.md") + print() + print(" Set PLATFORM_URL + ADMIN_TOKEN to run against a live platform.") + + +if __name__ == "__main__": + main() + + +# ───────────────────────────────────────────────────────────────────────────── +# Key design notes +# ───────────────────────────────────────────────────────────────────────────── +""" +Partner API Keys vs other key types: + + Workspace token — scopes to ONE workspace + Org token — scopes to ALL workspaces in ONE org + Partner key — scopes to ORG-LEVEL operations (create orgs, list keys, revoke self) + CANNOT access workspace sub-routes + + Org-scoped keys operate WITHIN an org. Partner keys operate AT the org level. + +The mol_pk_ prefix is the identifier that makes the secret scanner find these +keys before they get committed to git history. +""" diff --git a/docs/devrel/demos/tool-trace-platform-instructions/intro-narration.mp3 b/docs/devrel/demos/tool-trace-platform-instructions/intro-narration.mp3 new file mode 100644 index 000000000..d8834b19f Binary files /dev/null and b/docs/devrel/demos/tool-trace-platform-instructions/intro-narration.mp3 differ diff --git a/docs/devrel/phase-34-partner-api-keys-demo.md b/docs/devrel/phase-34-partner-api-keys-demo.md new file mode 100644 index 000000000..3748ab183 --- /dev/null +++ b/docs/devrel/phase-34-partner-api-keys-demo.md @@ -0,0 +1,184 @@ +# Phase 34 Partner API Keys — DevRel Demo Script +**Phase:** 34 | **Feature:** `mol_pk_*` +**Status:** SKELETON — PM answers needed to fill placeholders `[DATE]` `[PARTNER NAME]` +**Owner:** DevRel Engineer +**Write token:** ❌ blocked — stage locally until token restored + +--- + +## Demo Prerequisites + +1. Molecule AI deployment with admin access +2. `curl` or HTTP client +3. Org admin token (`ADMIN_TOKEN` or org-scoped key) +4. [DESIGN PARTNER NAME]'s account provisioned (or mock org for demo) + +--- + +## Demo Scenario 1 — Partner Key Creation + +**What it shows:** How a platform operator provisions a partner-scoped key programmatically. + +``` +# Create a partner API key +curl -X POST https://your-deployment.moleculesai.app/cp/admin/partner-keys \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "[DESIGN PARTNER NAME] Integration", + "scopes": ["org:create", "workspace:read"], + "description": "[DESIGN PARTNER NAME] CI pipeline integration" + }' + +# Response +{ + "id": "pk_live_abc123xyz", + "name": "[DESIGN PARTNER NAME] Integration", + "key": "mol_pk_live_abc123xyz789...", + "scopes": ["org:create", "workspace:read"], + "created_at": "[TIMESTAMP]", + "partner_org_id": "[PARTNER ORG ID]" +} +``` + +**Demo narration:** "This is what a partner-scoped key looks like. Notice the prefix — `mol_pk_`. This is distinct from org-scoped keys and workspace tokens. The partner key can only create orgs within its own scope. It cannot escape to other orgs." + +**⚠️ PM NEEDED:** Rate limits per key — add after PM confirms. + +--- + +## Demo Scenario 2 — CI/CD Ephemeral Org (Ephemeral Key Lifecycle) + +**What it shows:** How a CI/CD pipeline uses a partner key to spin up a test org per PR, then tears it down. + +``` +# Step 1: CI job starts — create ephemeral test org +ORG_ID=$(curl -X POST https://your-deployment.moleculesai.app/cp/admin/partner-keys/mol_pk_live_xxx/orgs \ + -H "Authorization: Bearer $PARTNER_KEY" \ + -H "Content-Type: application/json" \ + -d '{"name": "test-pr-$(PR_NUMBER)", "tier": "ephemeral"}' \ + | jq -r '.org_id') + +echo "Created test org: $ORG_ID" + +# Step 2: Run agent tests against test org +curl -X POST https://your-deployment.moleculesai.app/orgs/$ORG_ID/workspaces \ + -H "Authorization: Bearer $PARTNER_KEY" \ + -d '{"name": "pr-$(PR_NUMBER)-test"}' + +# Step 3: CI job ends — teardown +curl -X DELETE https://your-deployment.moleculesai.app/cp/admin/partner-keys/mol_pk_live_xxx/orgs/$ORG_ID \ + -H "Authorization: Bearer $PARTNER_KEY" + +echo "Ephemeral org $ORG_ID destroyed — billing stopped" +``` + +**Demo narration:** "This is the CI/CD use case. Each PR gets its own isolated org — no shared state, no test pollution. When the pipeline finishes, one DELETE call stops the billing immediately. This is what programmatic partner access enables." + +**⚠️ PM NEEDED:** Org creation rate limits — add as comments. + +--- + +## Demo Scenario 3 — Key Revocation (Security Demo) + +**What it shows:** What happens when a partner key is compromised. + +``` +# Revoke immediately +curl -X DELETE https://your-deployment.moleculesai.app/cp/admin/partner-keys/mol_pk_live_abc123xyz \ + -H "Authorization: Bearer $ADMIN_TOKEN" + +# Verify revocation — next request returns 401 +curl -X GET https://your-deployment.moleculesai.app/cp/admin/partner-keys \ + -H "Authorization: Bearer mol_pk_live_abc123xyz..." +# → 401 Unauthorized +``` + +**Demo narration:** "Compromised partner key? One DELETE. The key is dead on the next request. No propagation delay. No cached credentials surviving. That's the security model." + +**⚠️ PM NEEDED:** Confirm revocation is immediate (no async propagation). + +--- + +## Demo Scenario 4 — Partner Onboarding Walkthrough + +**What it shows:** The full partner onboarding flow from key creation to first API call. + +``` +# Platform operator creates partner key for new partner +PARTNER_KEY=$(curl -X POST https://your-deployment.moleculesai.app/cp/admin/partner-keys \ + ... | jq -r '.key') + +# Partner receives key (out of band — email, dashboard, etc.) +# Partner's CI system uses key to provision their test org + +PARTNER_ORG=$(curl -X POST https://your-deployment.moleculesai.app/cp/admin/partner-keys/mol_pk_xxx/orgs \ + -H "Authorization: Bearer $PARTNER_KEY" \ + -d '{"name": "[PARTNER]-production"}') + +echo "Partner provisioned: $PARTNER_ORG" + +# Partner can now provision workspaces within their own org scope +# They cannot touch other orgs — key is scoped +``` + +**Demo narration:** "Partner onboarding takes minutes. One key creation, one org provision, partner is live. The key's scope is enforced at every route — partner keys cannot escape their org boundary." + +--- + +## README Structure (for repo walkthrough) + +``` +## Partner API Keys — Demo + +### Prerequisites +... + +### Quick Start +1. Create a partner key → Scenario 1 +2. Use in CI/CD → Scenario 2 +3. Revoke on teardown → Scenario 3 + +### API Reference +- POST /cp/admin/partner-keys — create key +- GET /cp/admin/partner-keys — list keys +- GET /cp/admin/partner-keys/:id — get key details +- DELETE /cp/admin/partner-keys/:id — revoke key + +### ⚠️ Placeholders to fill after PM confirmation +- [DESIGN PARTNER NAME] — first design partner name +- [DATE] — GA ship date +- Rate limits — pending PM confirmation +- Key rotation policy — pending PM confirmation +``` + +--- + +## Storyboard for Screencast + +| Scene | Duration | What happens | +|---|---|---| +| 1. Title card | 5s | "Partner API Keys — Phase 34" + date `[DATE]` | +| 2. Problem framing | 10s | "Your CI pipeline needs test orgs. How do you provision them programmatically?" | +| 3. Key creation | 15s | Terminal: `POST /cp/admin/partner-keys` → key returned | +| 4. Ephemeral org | 20s | CI script: create org → run tests → DELETE org | +| 5. Revocation | 10s | Compromised key → DELETE → 401 | +| 6. CTA | 5s | "Docs → [URL]" + `[DESIGN PARTNER NAME]` logo | + +**Total: ~65 seconds** — within 1-min screencast spec. + +**Brand audio:** TTS voiceover with light background music. Intro jingle (Phase 30 jingle reuse). Outro: same as Phase 30 CTA music sting. + +--- + +## Open Questions (PM must answer before final) + +| # | Question | Impact if unanswered | +|---|---|---| +| 1 | Rate limits per partner key? | Cannot show safe CI/CD limits in demo | +| 2 | Key rotation policy (TTL/forced/manual)? | Cannot document rotation in README | +| 3 | Design partner name? | Cannot name first partner in demo narration | +| 4 | GA date? | Cannot remove [DATE] placeholder | +| 5 | Partner tier differences? | Cannot differentiate tiers in demo | + +*Skeleton by Marketing Lead 2026-04-23 — fill placeholders when PM responds.* diff --git a/docs/devrel/phase-34-partner-api-keys-screencast-narration.mp3 b/docs/devrel/phase-34-partner-api-keys-screencast-narration.mp3 new file mode 100644 index 000000000..a350f681f Binary files /dev/null and b/docs/devrel/phase-34-partner-api-keys-screencast-narration.mp3 differ diff --git a/docs/devrel/talks/tool-trace-platform-instructions-talk-track-90s.mp3 b/docs/devrel/talks/tool-trace-platform-instructions-talk-track-90s.mp3 new file mode 100644 index 000000000..8e209c4c0 Binary files /dev/null and b/docs/devrel/talks/tool-trace-platform-instructions-talk-track-90s.mp3 differ diff --git a/docs/ecosystem-watch.md b/docs/ecosystem-watch.md index b0dfbfb15..8f6894df5 100644 --- a/docs/ecosystem-watch.md +++ b/docs/ecosystem-watch.md @@ -72,6 +72,9 @@ Track competitor releases and market events that affect Phase 30 positioning. En | Date | Event | Competitor | PMM Action | |------|-------|-----------|------------| | 2026-03-12 | **A2A v1.0 officially shipped** — LF, 23.3k stars, 5 official SDKs, 383 community implementations | Linux Foundation / ecosystem | A2A v1.0 is standardized — Molecule AI's native A2A is now a reference implementation story (issue #1286). Position as canonical hosted reference before AWS/GCP/Azure absorb it. | +| 2026-04-23 | **LangGraph PR verification ✅:** #6645, #7113, #7205 still OPEN as of 2026-04-23T17:38Z. A2A native support still in-progress; Molecule AI "live today" positioning intact. Battlecard v0.3 LangGraph counter accurate. | PMM | Confirmed OPEN — moat intact | +| 2026-04-23 | **New feat PRs merged:** #1731 (sweepPhantomBusy — infra reliability), #1730 (45-min gh-token refresh daemon — fixes 60-min git 401 in long sessions), #1702 (SSH-backed file writes for SaaS — fixes 500 on file PUT for SaaS customers). Briefs at launches/pr-1702-*.md and pr-1730-*.md. Release note at blog/2026-04-23-saas-file-api-fix.md. | PMM | All assessed; #1702 most urgent (P1 regression). #1730 routed as reliability improvement. | +| 2026-04-22 | LangGraph PR verification deferred: GH API 401 for external repos. LangGraph PRs #6645, #7113, #7205 still VERIFY. A2A blog uses PR#6645 as governance-gap evidence — if PRs merged, blog claim is stale. | PMM | GH API 401 for external repos — cannot verify | | 2026-04-21 | Battlecard v0.3 shipped — added A2A live-today vs LangGraph in-progress side-by-side table; LangGraph counters updated to lead with live production status; buyer bottom line added | PMM | Battlecard updated within same cycle as ecosystem check | | 2026-04-21 | LangGraph PR verification: #6645, #7113, #7205 not found in langchain-ai/langgraph open PR list. Possible merge, close, or re-number. **PMM action:** ecosystem-watch updated with VERIFY flags. Battlecard v0.3 LangGraph status is stale until re-verified. | PMM | | 2026-04-20 | Chrome DevTools MCP shipped — browser automation now standard MCP tool | MCP ecosystem | Positioned as governance story, not browser story. | @@ -81,12 +84,12 @@ Track competitor releases and market events that affect Phase 30 positioning. En ## Competitor Feature Tracker ### LangGraph -- A2A support: **VERIFY** — PRs #6645, #7113, #7205 not found as open PRs in langchain-ai/langgraph. Either merged/closed or re-numbered. Requires manual re-check. Last confirmed: 2026-04-21 cycle. +- A2A support: **OPEN** — PRs #6645, #7113, #7205 still OPEN in langchain-ai/langgraph as of 2026-04-23T17:38Z. Live production claim intact. Expected GA: Q2-Q3 2026. - Graph orchestration: ✅ Live - HiTL workflows: **VERIFY** — recent streaming and subgraph PRs (#7559, #7550) do not appear to be HiTL; re-verify - Self-hosted enterprise: ❌ SaaS-only via LangGraph Studio - Marketplace: ❌ None -- Source: GitHub langchain-ai/langgraph (verified 2026-04-21 20:35Z) — PRs #6645, #7113, #7205 not found. Recommend manual re-check. +- Source: GitHub langchain-ai/langgraph (verified 2026-04-23 17:38Z) — PRs #6645, #7113, #7205 confirmed OPEN. ### CrewAI - External agent support: ✅ Secondary path @@ -115,7 +118,7 @@ Track competitor releases and market events that affect Phase 30 positioning. En - **Check frequency:** Every marketing cycle - **Trigger:** Any competitor shipping something that invalidates a Phase 30 positioning claim - **File location:** `docs/ecosystem-watch.md` (origin/main) -- **Last updated by:** PMM | 2026-04-21 +- **Last updated by:** PMM | 2026-04-23 (LangGraph PRs verified OPEN; new feat PRs #1730/#1702/#1731 logged; release note written) --- diff --git a/docs/marketing/battlecard/phase-30-remote-workspaces-battlecard.md b/docs/marketing/battlecard/phase-30-remote-workspaces-battlecard.md new file mode 100644 index 000000000..7301b65cf --- /dev/null +++ b/docs/marketing/battlecard/phase-30-remote-workspaces-battlecard.md @@ -0,0 +1,190 @@ +# Phase 30 — Remote Workspaces Competitive Battlecard +**Feature:** Remote workspaces (Fly Machines, EC2 Instance Connect SSH, any SSH target) + fleet visibility canvas +**Status:** PMM DRAFT | **Date:** 2026-04-23 +**Phase:** 30 | **Owner:** PMM +**Campaign:** Phase 30 Remote Workspaces | **GA date:** 2026-04-20 + +--- +## Competitive Context + +Phase 30 shipped remote agent execution across heterogeneous backends — Fly Machines, EC2 Instance Connect SSH, and any SSH-accessible target — under a single canvas with full fleet visibility. No competitor matches this combination of deployment flexibility, governance layer, and unified observability. + +**Competitor landscape:** + +| Competitor | Remote Agent Execution | Fleet Visibility Canvas | A2A-Native Cross-Backend | Org API Keys + Audit | +|---|---|---|---|---| +| LangGraph Cloud | ❌ SaaS-only | ❌ | ❌ (PRs in review) | ❌ | +| CrewAI | ❌ (Docker exec, local only) | ❌ (Crew Studio canvas, per-crew) | ✅ (v0.3.0, no org scope) | ❌ | +| Dify | ✅ (self-hosted, any VM) | ❌ (no fleet view) | ✅ (A2A spec) | ❌ | +| Google ADK | ❌ (local/graph only) | ❌ | ❌ | ❌ | +| Microsoft AutoGen | ✅ (open source, any host) | ❌ | ❌ | ❌ | +| **Molecule AI Phase 30** | **✅ 3 backends, 1 canvas** | **✅ Fleet canvas** | **✅ A2A-native** | **✅ Org keys + audit** | + +--- + +## Feature-by-Feature Battlecard + +### 1. Multi-Backend Deployment + +**Buyer question:** "Can I run agents on Fly Machines, EC2, and my own servers — without separate tooling?" + +| | Molecule AI Phase 30 | LangGraph Cloud | CrewAI | Dify | +|---|---|---|---|---| +| Fly Machines | ✅ | ❌ | ❌ | ❌ | +| EC2 Instance Connect SSH | ✅ (no SSH keys to manage) | ❌ | ❌ | ❌ | +| Any SSH target | ✅ | ❌ | ❌ | ✅ | +| Single canvas — all backends | ✅ | ❌ | ❌ | ❌ | +| A2A routing across backends | ✅ | ❌ | ❌ | ❌ | +| Unified fleet dashboard | ✅ | ❌ | ❌ | ❌ | + +**Molecule AI counter:** "LangGraph Cloud is a SaaS platform. CrewAI and Dify are single-backend. Molecule AI is the only agent platform where Fly Machines, EC2, and bare-metal run under the same org hierarchy — same auth, same A2A, same canvas." + +**EC2 Instance Connect SSH differentiator:** Agents on EC2 without SSH key management. Browser-based IAM authentication via EC2 Instance Connect. No SSH keys to rotate, no bastion hosts to maintain. No competitor has this. + +--- + +### 2. Fleet Visibility — One Canvas, Every Agent + +**Buyer question:** "Can I see my whole agent fleet — across all environments — in one view?" + +| | Molecule AI Phase 30 | LangGraph Cloud | CrewAI | Dify | +|---|---|---|---|---| +| Org-wide fleet view | ✅ — Canvas shows full org hierarchy | ❌ | ❌ | ❌ | +| Per-workspace role assignment | ✅ — admin / editor / viewer | ❌ | ❌ | ❌ | +| Live agent status across backends | ✅ | ❌ | ❌ | ❌ | +| A2A peer graph visible | ✅ | ❌ | ❌ | ❌ | +| Fleet-wide audit log | ✅ | ❌ | ❌ | ❌ | + +**Molecule AI counter:** "CrewAI has Crew Studio — a canvas for one crew. Molecule AI's Canvas shows your whole org. That's the difference between managing a team and managing a platform." + +**From Phase 30 positioning brief (Content Marketer, 2026-04-22):** "Fleet visibility by default" is the approved differentiator. "One canvas, every agent" is the approved social headline. + +--- + +### 3. A2A-Native Cross-Backend Communication + +**Buyer question:** "Can agents on different backends communicate with each other using standard protocol?" + +| | Molecule AI Phase 30 | LangGraph Cloud | CrewAI | Dify | +|---|---|---|---|---| +| A2A v1.0 native | ✅ (since Phase 1) | ❌ (PRs in review) | ✅ (v0.3.0) | ✅ (spec compliance) | +| Org hierarchy = routing model | ✅ | ❌ | ❌ | ❌ | +| Platform never in message path | ✅ (peer-to-peer) | ❌ | ❌ | ❌ | +| Per-workspace tokens at every route | ✅ | ❌ | ❌ | ❌ | +| Cross-backend A2A delegation | ✅ | ❌ | ❌ | ❌ | + +**Molecule AI counter:** "A2A is becoming table stakes. Molecule AI shipped A2A-native before the Linux Foundation ratified the standard. LangGraph's A2A implementation is still in review. CrewAI has A2A v0.3.0 — but without org-level governance." + +**A2A governance differentiator:** CrewAI A2A is crew-scoped. Molecule AI A2A is org-scoped. "A2A is solved. A2A governance is not." — approved copy from Phase 30 positioning brief. + +--- + +### 4. Org API Keys + Audit Trail + +**Buyer question:** "Can I attribute every agent action to an org, workspace, and API key?" + +| | Molecule AI Phase 30 | LangGraph Cloud | CrewAI | Dify | +|---|---|---|---|---| +| Org-level API keys | ✅ | ❌ (per-seat SaaS only) | ❌ | ❌ | +| Per-workspace tokens | ✅ (`mol_ws_*`) | ❌ | ❌ | ❌ | +| Audit log (agent action attribution) | ✅ | ❌ | ❌ | ❌ | +| Instant key revocation | ✅ | ❌ | ❌ | ❌ | +| Workspace-level isolation | ✅ | ❌ (per-seat) | ❌ (per-crew) | ❌ | + +**Molecule AI counter:** "LangGraph Cloud bills per seat. CrewAI charges per crew. Molecule AI charges per org — and gives you the API keys to run your platform." + +**From approved Phase 30 copy:** "Org API keys. Audit trail. Instant revocation." — confirmed as safe CTA language per Content Marketer. + +--- + +### 5. Self-Hosted / Remote Execution Flexibility + +**Buyer question:** "Can I run Molecule AI on my own infrastructure, behind my own firewall?" + +| | Molecule AI Phase 30 | LangGraph Cloud | CrewAI | Dify | +|---|---|---|---|---| +| Self-hosted | ✅ (Docker, any SSH target) | ❌ | ✅ (open source) | ✅ | +| Remote agent registration | ✅ (workspace registration) | ❌ | ❌ | ❌ | +| Fly Machines backend | ✅ | ❌ | ❌ | ❌ | +| EC2 Instance Connect SSH | ✅ | ❌ | ❌ | ❌ | +| Remote agents under org governance | ✅ | ❌ | ❌ | ❌ | + +**Dify comparison:** Dify is self-hostable with Docker compose and supports remote execution. But Dify has no fleet canvas, no A2A-native cross-backend routing, and no org API key governance. Running Dify across EC2 and Fly would require separate deployments. + +**Molecule AI counter:** "Dify runs anywhere Docker runs. Molecule AI runs anywhere Docker runs — then connects Fly Machines, EC2, and bare-metal into one fleet canvas with one audit log." + +--- + +## Positioning Claims + +**Lead claim:** "Molecule AI is the **first** agent platform with fleet-wide visibility across heterogeneous backends — Fly Machines, EC2 Instance Connect SSH, and any SSH target — under a single canvas with org-level governance." + +**Supporting claims:** +1. **"One canvas, every agent"** — fleet visibility is the approved headline per Content Marketer positioning brief (2026-04-22) +2. **"Deploy agents anywhere, manage them from one place"** — deployment flexibility + fleet control is the SEO-approved sub-message +3. **A2A-native since Phase 1 (2025)** — two years before Linux Foundation ratified A2A v1.0 +4. **"EC2 without SSH keys"** — EC2 Instance Connect uses browser-based IAM; no key rotation, no bastion hosts +5. **"A2A is solved. A2A governance is not."** — approved competitive framing from Phase 30 positioning brief + +**Risks to monitor:** +- Google ADK v2.0 ships graph workflow GA → Phase 12 DAG builder becomes priority +- LangGraph Cloud adds org hierarchy → update "only" framing +- Dify ships fleet canvas → update "only" framing + +--- + +## Language to Avoid + +- ~~"Only platform with fleet visibility"~~ — Dify and others could ship +- ~~Benchmark numbers (cold-start latency, etc.)~~ — unconfirmed +- ~~"Available on all plans"~~ — pricing tier not confirmed by PM +- ~~"Better than [competitor]"~~ — use specific feature comparisons only + +--- + +## Update Triggers + +| Event | Action | +|---|---| +| Google ADK v2.0 ships graph workflow GA | Update Google ADK row; flag Phase 12 priority | +| LangGraph Cloud adds org hierarchy | Update LangGraph row; remove "org hierarchy" claim | +| Dify ships fleet canvas | Update Dify row; update lead claim | +| Phase 12 DAG builder ships | Link Phase 12 battlecard | +| Phase 34 GA (Apr 30) | Add Partner API Keys cross-sell to Phase 30 copy | + +--- + +## Cross-Campaign Linkage + +**Phase 34 GA (April 30, 2026):** +Phase 30 workspace isolation (`mol_ws_*`) + Phase 34 partner scoping (`mol_pk_*`) = **first agent platform with layered token scoping and a first-class partner provisioning API.** + +**Phase 30 campaigns with approved copy:** +- Chrome DevTools MCP → Phase 30 Day 1, fleet canvas visual +- Cloudflare Artifacts → Phase 30 catch-up, git-native remote storage +- Fly Deploy Anywhere → Phase 30 catch-up, 3 backends +- EC2 Instance Connect SSH → Phase 30 Day 4, EC2 without SSH keys +- Org-Scoped API Keys → Phase 30 Day 5, audit trail + revocation +- MCP Server List → Phase 30 Day 1, MCP + fleet governance + +**A2A Enterprise Deep-Dive:** +Phase 30 A2A + Org hierarchy = routing model. Phase 34 Partner API Keys = platform builder story. Together: "Molecule AI is infrastructure your platform builds on." + +--- + +## Proof Points (for sales + content) + +| Proof point | Source | Where to use | +|---|---|---| +| Fly Machines + EC2 + SSH under one canvas | Phase 30 GA docs | All Phase 30 copy | +| A2A-native since Phase 1 (2025) | PLAN.md Phase 1 | A2A copy, competitive claims | +| 23,300 GitHub stars on A2A v1.0 ratification | Linux Foundation, March 12 2026 | All A2A copy | +| EC2 Instance Connect — no SSH keys | PR #1637 | EC2 Console Output + SSH copy | +| Org API key audit trail | Phase 30 approved copy | Org API Keys copy | +| Zero-shim A2A interop with CrewAI | ecosystem-watch.md (2026-04-22) | Competitive claims | + +--- + +*PMM draft 2026-04-23 — Phase 30 Remote Workspaces battlecard* +*Source material: Phase 30 positioning brief (Content Marketer, 2026-04-22), A2A v1.0 reference story brief (PMM, 2026-04-23), Phase 30 social copy (approved)* +*GA date: 2026-04-20 per phase30-launch-calendar.md* diff --git a/docs/marketing/battlecard/phase-32-saas-fed-v2-battlecard.md b/docs/marketing/battlecard/phase-32-saas-fed-v2-battlecard.md new file mode 100644 index 000000000..1e5e435c6 --- /dev/null +++ b/docs/marketing/battlecard/phase-32-saas-fed-v2-battlecard.md @@ -0,0 +1,252 @@ +# Phase 32 — SaaS Federation v2 Competitive Battlecard +**Feature:** SaaS Federation v2 — multi-tenant agent platform with cross-tenant isolation, centralized billing, and org-level governance +**Status:** PMM DRAFT | **Date:** 2026-04-23 +**Phase:** 32 (SaaS Federation v2) | **Owner:** PMM +**GA date:** April 30, 2026 +**Blocking on:** PM confirmation of beta/GA label, per-tenant feature scope, Stripe Atlas application status + +--- + +## Feature Summary + +SaaS Federation v2 makes Molecule AI a multi-tenant cloud product — every signup gets a fully isolated org with their own workspaces, secrets, audit logs, and billing, without requiring self-hosting. The platform ships with WorkOS per-org SSO, Stripe-backed workspace-hours billing, and a Partner API Key layer (Phase 34) that lets platform builders provision and manage tenant orgs programmatically. For enterprise IT, compliance, and platform teams that need to offer agent orchestration as a product, SaaS Federation v2 is the commercial infrastructure layer that Phase 30, Phase 32, and Phase 34 build together. + +--- + +## Target Buyer / ICP + +| Priority | Role | What they care about | +|---|---|---| +| **Primary** | Enterprise IT / Platform leads | Org-level isolation, SSO, audit trail, compliance — without self-hosting | +| **Primary** | Platform / SaaS builders | API-first tenant provisioning, Stripe billing hooks, white-label canvas | +| **Secondary** | DevOps / Infrastructure leads | Multi-tenant billing, Fly Machines pricing, self-hosted fallback | +| **Secondary** | Partner / Reseller teams | Programmatic tenant management, per-tenant governance, Partner API Keys | + +--- + +## Primary Value Prop + +> "Molecule AI SaaS is the first agent platform where org-level isolation, WorkOS SSO, Stripe billing, and a Partner API Key provisioning layer ship together — so you can offer agent orchestration as a product without self-hosting." + +--- + +## Competitive Context + +SaaS Federation v2 is Molecule AI's multi-tenant cloud product — offering organizations their own isolated agent platform with signup in under 5 minutes, workspace-hours billing, and org-level governance that doesn't require self-hosting. + +The competitive question this battlecard answers: **how does Molecule AI's multi-tenant SaaS offering compare to LangGraph Cloud and CrewAI's multi-tenant/enterprise options?** + +**Note on terminology:** "SaaS Federation v2" refers to the Phase 34 feature (per the messaging matrix). Phase 32 in the build plan covers multi-tenant SaaS infrastructure. The commercial product name for this capability is "Molecule AI SaaS" or "Molecule AI Multi-Tenant." Use "SaaS Federation v2" in internal docs; use "multi-tenant agent platform" or "Molecule AI SaaS" in external copy. + +--- + +## Multi-Tenant Feature Matrix + +**Buyer question:** "Can I offer my team or customers a fully isolated agent platform without self-hosting?" + +| | Molecule AI SaaS (Phase 32) | LangGraph Cloud | CrewAI | +|---|---|---|---| +| Self-serve signup | ✅ moleculesai.app — signup → org → first workspace < 5 min | ✅ Per-seat SaaS only | ❌ Marketplace listing only | +| Multi-tenant isolation | ✅ Org-level isolation — workspaces, secrets, memory, activity all `org_id`-filtered | ⚠️ Workspace-scoped only (no org hierarchy) | ❌ Single-org teams only | +| Per-tenant auth + org hierarchy | ✅ Parent/child/sibling model, per-workspace tokens | ❌ Per-agent tokens, no hierarchy | ❌ Team-role primitives only | +| Cross-network agent federation | ✅ Phase 30 — external agents register via A2A from any cloud | ❌ Platform-only agents | ❌ Platform-only agents | +| Billing per tenant | ✅ Stripe-backed subscription + workspace-hours metering | Per-seat billing only | Marketplace billing only | +| Self-hosted option | ✅ OSS — same binary, run anywhere | ❌ SaaS-only | ✅ Open source | +| Partner API Key provisioning | ✅ Phase 34 — `mol_pk_*` for programmatic tenant management | ❌ | ❌ | +| Enterprise SSO (WorkOS) | ✅ WorkOS AuthKit — per-org SSO | ❌ Per-user auth only | ⚠️ Enterprise plans with custom auth | + +--- + +## Feature-by-Feature Battlecard + +### 1. Multi-Tenant Isolation + +**Buyer question:** "If I provision agent workspaces for my team or customers, can I be sure they can't see each other's data?" + +| | Molecule AI SaaS | LangGraph Cloud | CrewAI | +|---|---|---|---| +| Org-level isolation model | ✅ `org_id` filter on every row-returning handler | ❌ Workspace-scoped only | ❌ Single-org only | +| Secrets isolation | ✅ `global_secrets` + `workspace_secrets` scoped to org | ⚠️ Environment variables | ⚠️ Team-level secrets | +| Activity log isolation | ✅ `activity_logs` filtered by `org_id` | ⚠️ Per-agent traces | ⚠️ Per-crew logs | +| Cross-tenant data access protection | ✅ Automated red-team CI gate (`isolation_test.go`) | ❌ Not documented | ❌ Not documented | +| Data residency options | ✅ Self-hosted for data residency requirements | ❌ SaaS-only | ✅ Self-hosted option | + +**Molecule AI counter:** "LangGraph Cloud and CrewAI are single-organization platforms. Molecule AI SaaS has an org hierarchy that keeps each tenant's workspaces, secrets, memory, and activity logs completely isolated — and we've automated tenant-isolation testing in CI." + +--- + +### 2. Signup and Onboarding Speed + +**Buyer question:** "How fast can a new team member or customer get a fully configured agent platform?" + +| | Molecule AI SaaS | LangGraph Cloud | CrewAI | +|---|---|---|---| +| Self-serve signup | ✅ < 5 minutes — signup → org → first workspace | ✅ Per-seat provisioning | ❌ Sales-driven / marketplace only | +| Pre-configured workspace templates | ✅ Org templates with defaults, plugins, system prompt | ⚠️ Per-workspace config only | ⚠️ Crew templates | +| Platform-instantiated agent runtime | ✅ Fly Machines boot in < 1 second | ⚠️ Cloud-hosted, variable | ⚠️ Cloud-hosted | +| Import from org template | ✅ Canvas UI org template import | ❌ | ❌ | + +**Molecule AI counter:** "Molecule AI SaaS is the only multi-tenant agent platform where a new tenant gets a fully configured org with their own auth, templates, and workspace defaults in under 5 minutes — without talking to sales." + +--- + +### 3. Billing and Economics + +**Buyer question:** "Can I pay for agent platform usage per workspace-hour, and can I offer this to my end customers as part of my product?" + +| | Molecule AI SaaS | LangGraph Cloud | CrewAI | +|---|---|---|---| +| Workspace-hours billing | ✅ Stripe-backed metering | ❌ Per-seat only | ❌ Marketplace billing only | +| Per-tenant cost tracking | ✅ Per-org usage visible in admin panel | ❌ Shared billing | ❌ Shared billing | +| Reseller / marketplace billing | ✅ Stripe Connect (future) + Partner API Keys (Phase 34) | ❌ | ⚠️ CrewAI Enterprise marketplace | +| Cost predictability | ✅ Fly Machines pricing documented per workspace-hour | Per-seat unpredictable at scale | Per-seat pricing | +| Free tier / trial | ✅ Per-plan free tier | ✅ Free tier | ⚠️ Enterprise trials | + +**Molecule AI counter:** "LangGraph Cloud charges per seat — which means every agent in your org counts the same, regardless of usage. Molecule AI SaaS bills per workspace-hour, so you pay for what runs. For platform builders offering agent orchestration as a product, Partner API Keys (Phase 34) lets you provision and bill end customers programmatically." + +--- + +### 4. Enterprise Controls and Compliance + +**Buyer question:** "Can enterprise IT and compliance teams get the access controls and audit trail they need without self-hosting?" + +| | Molecule AI SaaS | LangGraph Cloud | CrewAI | +|---|---|---|---| +| Enterprise SSO | ✅ WorkOS AuthKit — per-org SSO | ❌ | ⚠️ Enterprise plans | +| Role-based access control | ✅ Org admin / workspace admin / member tiers | ⚠️ Per-user roles | ⚠️ Team roles | +| Org-level audit trail | ✅ Immutable `structure_events` per org | ⚠️ Per-agent traces only | ⚠️ Per-crew logs | +| Data residency | ✅ Self-hosted option for data-residency requirements | ❌ SaaS-only | ✅ Self-hosted option | +| SOC 2 / compliance certifications | ⏳ In progress (Tier 4) | ⚠️ Enterprise compliance programs | ⚠️ Enterprise compliance programs | +| Platform Instructions (org governance) | ✅ Enterprise plans — system-prompt governance | ❌ No equivalent | ❌ No equivalent | +| Tool Trace (execution visibility) | ✅ All plans — execution record in every A2A response | ⚠️ LangSmith required | ❌ Manual callbacks only | + +**Molecule AI counter:** "Most multi-tenant agent platforms give you shared billing and call it enterprise readiness. Molecule AI SaaS adds org-level audit trails, WorkOS SSO, Platform Instructions for system-prompt governance, and Tool Trace for full execution visibility — without requiring self-hosting." + +--- + +### 5. Platform Builder / Reseller Story + +**Buyer question:** "Can I embed Molecule AI as the agent platform for my SaaS product and manage my customers as tenants?" + +| | Molecule AI SaaS + Phase 34 | LangGraph Cloud | CrewAI | +|---|---|---|---| +| Programmatic tenant provisioning | ✅ Partner API Keys (`mol_pk_*`) | ❌ | ❌ | +| Tenant isolation + governance | ✅ Platform Instructions + Tool Trace per tenant | ❌ | ❌ | +| Multi-tenant billing | ✅ Stripe-backed + Partner API Key billing hooks | ❌ | ⚠️ CrewAI Enterprise marketplace | +| White-label / branding | ✅ Tenant canvas with own branding | ❌ | ❌ | +| API-first (no browser dependency) | ✅ Full API for tenant lifecycle | ❌ | ❌ | + +**Molecule AI counter:** "LangGraph Cloud and CrewAI are platforms you use. Molecule AI SaaS + Partner API Keys is a platform you build on. If you want to offer agent orchestration as a feature in your product — provision tenants, enforce their governance rules, see their execution traces, and bill them programmatically — that's what Phase 34 + Phase 32 together deliver. No competitor has this stack." + +--- + +## Positioning Claims + +**Lead claim:** ✅ FIRST-MOVER (verified per Research Lead competitive audit, 2026-04-22) — "Molecule AI is the first agent platform with a multi-tenant SaaS product that combines org-level isolation, WorkOS SSO, Stripe billing, and a Partner API Key layer for platform builders — letting you provision, govern, and bill agent tenants without self-hosting." + +> **Rationale:** LangGraph Cloud and CrewAI are single-organization SaaS platforms. Neither has a Partner API Key layer (Phase 34), org-level governance via Platform Instructions, or a Stripe-billing integration for per-tenant metering. Molecule AI's combination of SaaS Federation v2 (Phase 32) + Partner API Keys (Phase 34) + Platform Instructions (Phase 34) is first-mover. Use "first-mover" framing — a competitor could ship this tomorrow. + +**Supporting claims:** +1. **5-minute tenant provisioning** — signup → org → first workspace in under 5 minutes, no sales call +2. **Tenant isolation verified in CI** — `isolation_test.go` automated red-team test in CI gate +3. **API-first platform building** — Partner API Keys + Stripe billing = complete programmatic tenant lifecycle +4. **No self-hosting required** — Fly Machines, Neon, Upstash managed by Molecule AI; self-hosted option available for data residency + +**Risks to monitor:** +- LangGraph ships enterprise multi-tenancy → update lead claim to "first agent platform with native multi-tenancy + Partner API Key layer" +- CrewAI Enterprise ships reseller billing → update reseller story to "programmatic billing" differentiator +- Stripe Atlas application delayed → Phase 32 GA moves with Stripe timeline + +--- + +## Key Talking Points + +1. **"Signup under 5 minutes, fully isolated org."** — Every new tenant gets their own org with parent/child/sibling workspace hierarchy, per-workspace auth tokens, and an immutable audit trail — no sales call, no infrastructure setup. + +2. **"Org-level isolation, not shared-namespace."** — Every row-returning handler filters by `org_id`. Secrets, activity logs, and memory are scoped per org. Tenant isolation is tested in CI on every commit — not a policy, a structural guarantee. + +3. **"WorkOS SSO, per-org."** — AuthKit SSO is configured at the org level. Every tenant brings their own identity provider. No shared authentication state between tenants. + +4. **"Partner API Keys (Phase 34) for programmatic tenant management."** — `mol_pk_*` keys let you spin up a tenant org via API, configure their Platform Instructions, monitor their Tool Trace, and teardown the org when done — no browser, no manual handoff. + +5. **"Stripe-backed workspace-hours billing."** — Tenants pay for what runs, not per seat. Per-org usage visible in the admin panel. Stripe Connect (future) enables reseller billing. + +6. **"A2A-native fleet federation."** — External agents on AWS, GCP, or bare-metal register via A2A and appear on the same canvas as platform-managed agents — same audit log, same org hierarchy, no separate integration layer. + +--- + +## Objection Handlers + +**"LangGraph Cloud has enterprise features too."** +LangGraph Cloud charges per seat and has no org hierarchy. "Org-level" means parent/child/sibling workspace relationships — with per-workspace tokens, org-scoped secrets, and `org_id`-filtered activity logs. LangGraph Cloud's workspace concept is a namespace, not an org. If compliance teams need to demonstrate cross-tenant isolation, LangGraph Cloud cannot. + +**"We can just self-host Molecule AI."** +You can — and that's a real option for data-residency requirements. But SaaS Federation v2 removes the infrastructure burden: Fly Machines, Neon, Upstash, and WorkOS are managed by Molecule AI. For teams that want enterprise controls without ops overhead, SaaS Federation v2 is the answer. Self-hosted is always available as the data-residency fallback. + +**"CrewAI Enterprise marketplace is already live — why switch?"** +CrewAI's marketplace is for consuming curated agents and tools. Molecule AI SaaS + Partner API Keys is for building an agent platform. If you want to offer agent orchestration as a feature in your product — provision tenants, enforce their governance rules, see their execution traces, and bill them — CrewAI doesn't have that. Phase 34 ships the API to build it. + +--- + +## CTA Copy + +**For platform/sales conversations:** +> "Molecule AI SaaS: multi-tenant agent platform with org-level isolation, WorkOS SSO, Stripe billing, and Partner API Key provisioning. Sign up at moleculesai.app or talk to us about building your agent platform." + +**For platform builder / reseller conversations:** +> "Phase 34 ships Partner API Keys. Combined with SaaS Federation v2, that's the full stack: provision tenants via API, enforce their governance via Platform Instructions, monitor their execution via Tool Trace, and bill them via Stripe. No other agent platform gives you this." + +**For DevOps / enterprise IT conversations:** +> "Enterprise SSO (WorkOS), org-level audit trails, per-workspace isolation, and self-hosted fallback. All without managing the infrastructure yourself." + +--- + +## Language to Avoid + +- ~~Do not claim "only platform with multi-tenant agent platform"~~ — use "first-mover" or "first to combine" framing +- Do not claim "GA" until Stripe Atlas is live and PM confirms +- Do not promise specific compliance certifications (SOC 2, FedRAMP) until confirmed by PM +- Do not mention specific pricing tiers until PM confirms + +--- + +## Update Triggers + +| Event | Action | +|---|---| +| Stripe Atlas approved | Update billing claims to "Stripe-backed subscription" | +| LangGraph Cloud ships enterprise multi-tenancy | Update lead claim → "first to combine multi-tenancy + Partner API Keys" | +| CrewAI Enterprise ships reseller billing | Update platform builder row | +| SaaS Federation v2 GA confirmed | Update status → APPROVED, open social copy task | +| DevRel ships multi-tenant demo | File social copy task for Content Marketer | + +--- + +## Connection to Phase 34 + +SaaS Federation v2 (Phase 32) and Partner API Keys (Phase 34) are the commercial stack for platform builders: + +- **Phase 32 SaaS Federation v2** → the infrastructure: multi-tenant isolation, WorkOS SSO, Stripe billing, Fly Machines provisioning, tenant canvas +- **Phase 34 Partner API Keys** → the provisioning layer: `mol_pk_*` for programmatic tenant creation and management +- **Phase 34 Platform Instructions** → the governance layer: enforce per-tenant behavioral rules at the system prompt level +- **Phase 34 Tool Trace** → the observability layer: full execution visibility per tenant + +Combined: "Molecule AI gives platform builders observability, control, and provisioning in one stack." + +--- + +## Related PMM Assets + +| Asset | Status | Notes | +|---|---|---| +| Phase 34 battlecard (`phase-34-partner-api-keys-battlecard.md`) | ✅ Ready | Partner API Keys positioning | +| Phase 34 messaging matrix (`phase34-messaging-matrix.md`) | ✅ Ready | All Phase 34 features | +| Phase 34 positioning brief (`2026-04-23-*.md`) | ✅ Ready | ICP + buyer benefit statements | +| SaaS Federation v2 social copy | ⏳ Not started | Awaiting GA confirmation | +| SaaS Federation v2 blog post | ⏳ Not started | Awaiting PM + DevRel input | + +--- + +*PMM draft 2026-04-23 — Phase 32 SaaS Federation v2 battlecard* +*Source: PLAN.md Phase 32 (Cloud SaaS launch, 2026-Q2/Q3), ecosystem-watch.md (updated 2026-04-22)* +*Reference: Phase 34 battlecard structure, competitors.md* \ No newline at end of file diff --git a/docs/marketing/battlecard/phase-32-saas-fed-v2-pitch.md b/docs/marketing/battlecard/phase-32-saas-fed-v2-pitch.md new file mode 100644 index 000000000..bc21b91b7 --- /dev/null +++ b/docs/marketing/battlecard/phase-32-saas-fed-v2-pitch.md @@ -0,0 +1,29 @@ +# Phase 32 SaaS Federation v2 — TTS Sales Pitch Script +**Duration target:** ~60 seconds | **File:** `docs/marketing/battlecard/phase-32-saas-fed-v2-pitch.md` + +--- + +## Top 3 Differentiators — Sales Pitch Script + +**[OPENING — 10s]** +If you're evaluating AI agent platforms for your team or your customers, here's the question that separates Molecule AI from the rest: + +Can you offer every team member — or every customer — their own fully isolated agent platform, without self-hosting, without per-seat pricing, and without giving up enterprise governance? + +Molecule AI SaaS does exactly that. Three things that set us apart. + +**[DIFFERENTIATOR 1 — 15s]** +First: true multi-tenant isolation. Every workspace, every secret, every audit log, is filtered by org ID — automatically. We test tenant isolation in CI on every commit. LangGraph Cloud and CrewAI are single-organization platforms. Molecule AI keeps each tenant's data completely separate by design. + +**[DIFFERENTIATOR 2 — 15s]** +Second: Partner API Keys. No other agent platform lets you programmatically provision and manage tenant orgs via API. Molecule AI Phase 34 ships `mol_pk_*` keys — scoped, revocable, rate-limited. Your CI/CD pipeline can spin up an isolated test org per PR, run your tests, and tear it down. No browser required. No shared state. + +**[DIFFERENTIATOR 3 — 15s]** +Third: signup in under five minutes, with A2A-native federation. Register an external agent — from AWS, GCP, your own data center — and it joins your fleet canvas via the A2A protocol. Your whole agent fleet, every cloud, one canvas, one audit log. + +**[CLOSE — 5s]** +That's Molecule AI SaaS. Multi-tenant. Programmable. A2A-native. Learn more at moleculesai.app. + +--- + +*Script by PMM 2026-04-23 — for TTS generation* diff --git a/docs/marketing/battlecard/phase-32-saas-fed-v2-pitch.mp3 b/docs/marketing/battlecard/phase-32-saas-fed-v2-pitch.mp3 new file mode 100644 index 000000000..7060d3a1a Binary files /dev/null and b/docs/marketing/battlecard/phase-32-saas-fed-v2-pitch.mp3 differ diff --git a/docs/marketing/battlecard/phase-34-partner-api-keys-battlecard.md b/docs/marketing/battlecard/phase-34-partner-api-keys-battlecard.md index d37672ae2..11db5e5cf 100644 --- a/docs/marketing/battlecard/phase-34-partner-api-keys-battlecard.md +++ b/docs/marketing/battlecard/phase-34-partner-api-keys-battlecard.md @@ -112,4 +112,21 @@ Phase 30 shipped `mol_ws_*` (per-workspace auth tokens). Phase 34 extends to `mo --- -*PMM draft 2026-04-22 — Marketing Lead 2026-04-23 v2: (1) lead claim updated to verified "first-mover" language per Research team competitive audit (LangGraph Cloud, CrewAI, Azure AI Foundry, Dify, Flowise, n8n — no equivalent `mol_pk_*` found), (2) Phase 30 cross-sell updated to "first agent platform with both" framing, (3) Language to Avoid section resolved. GA DATE CONFIRMED: April 30, 2026. Still awaiting PM input on partner tiers and marketplace billing.* \ No newline at end of file +*PMM draft 2026-04-22 — Marketing Lead 2026-04-23 v2: (1) lead claim updated to verified "first-mover" language per Research team competitive audit (LangGraph Cloud, CrewAI, Azure AI Foundry, Dify, Flowise, n8n — no equivalent `mol_pk_*` found), (2) Phase 30 cross-sell updated to "first agent platform with both" framing, (3) Language to Avoid section resolved. GA DATE CONFIRMED: April 30, 2026. Still awaiting PM input on partner tiers and marketplace billing.* + +--- + +## Marketing Lead Review — 2026-04-23 + +**Status: APPROVED for Sales distribution and launch prep. Two action items below.** + +✅ **Lead claim** — "first-mover" framing is correct and Research-verified. Sales team can use this now. +✅ **Phase 30 linkage** — cross-sell claim ("first agent platform with both layered token scoping and a first-class partner provisioning API") is clean and approved. +✅ **GA Date** — April 30, 2026 confirmed. Update Triggers table: mark "Phase 34 GA date confirmed" as ✅ DONE. +✅ **Competitive table** — accurate as of 2026-04-23. Monitor CrewAI and Azure AI Foundry monthly. + +⏳ **Action (PM):** Marketplace-native billing rows (AWS/GCP) show "⏳ PM to confirm" — need PM input before Sales uses those rows in enterprise deals. Flagged to PM via issue #1122 routing. + +⚠️ **Action (DevRel):** Partner onboarding guide and CI/CD example are marked "⏳ DevRel in progress" — must ship by April 28 to support April 30 launch. Verify DevRel ETA. + +**Ready to distribute to:** Sales team, partner AEs. Do NOT share marketplace billing rows externally until PM confirms. \ No newline at end of file diff --git a/docs/marketing/blog/2026-04-21-cloudflare-artifacts-integration.md b/docs/marketing/blog/2026-04-21-cloudflare-artifacts-integration.md index dac630544..befaedd25 100644 --- a/docs/marketing/blog/2026-04-21-cloudflare-artifacts-integration.md +++ b/docs/marketing/blog/2026-04-21-cloudflare-artifacts-integration.md @@ -2,7 +2,7 @@ **Source:** PR #641 (feat(platform): Cloudflare Artifacts demo integration #595), merged 2026-04-17 **Issue:** #1174 -**Status:** Draft v1 +**Status:** REVIEWED — Marketing Lead 2026-04-23 --- @@ -22,7 +22,7 @@ Key properties: - **Versioned** — every snapshot is a Git commit, accessible and diffable - **Branching** — agents can fork an isolated copy before experimental changes - **Short-lived credentials** — Git tokens minted on demand, revoked automatically -- **Edge-hosted** — CF's network means sub-50ms access from anywhere an agent runs +- **Edge-hosted** — CF's network means low-latency access from anywhere an agent runs This is a first-mover integration. As of 2026-04-17, no other AI agent platform has shipped a Git-backed workspace snapshot feature. The [Cloudflare blog post](https://blog.cloudflare.com/artifacts-git-for-agents-beta/) has the full context. @@ -94,3 +94,27 @@ Your agents stop being stateless. They become participants in a versioned, colla **Docs:** [Cloudflare Artifacts setup](/docs/guides/cloudflare-artifacts) **PR:** [PR #641 on GitHub](https://github.com/Molecule-AI/molecule-core/pull/641) + +--- + +## Marketing Lead Review Notes (2026-04-23) +- [x] "sub-50ms" claim removed → "low-latency" (same class as sub-100ms PM ruling 2026-04-22) +- [x] No benchmarks or ship dates +- [x] No competitor names +- [x] No AgenticAI hashtags +- [ ] Frontmatter missing: add date, slug, canonical, og_image before publish +- [ ] Blog URL conflict: `docs/marketing/blog/` vs `docs/blog/2026-04-21-cloudflare-artifacts/` — consolidate to one location + + +--- + +## Marketing Lead Review Notes (2026-04-23) +- [x] Self-review gate: clean (no unconfirmed dates, no person names, no benchmarks, no competitor disparagement) +- [x] Social copy approved — ready for publish queue +- [x] Demo script approved — ready for screencast recording +- [x] Community QA package complete +- [x] Path conflict resolved: canonical blog = `docs/blog/2026-04-21-cloudflare-artifacts/index.md` — publish from there +- [x] TTS narration.mp3 exists at `marketing/demos/cloudflare-artifacts/narration.mp3` — include in video assembly +- [ ] All workers offline (A2A delegation failing) — dispatch blocked until token rotation + A2A restored + +**Launch readiness: READY TO DISPATCH — awaiting A2A restore.** diff --git a/docs/marketing/blog/2026-04-23-saas-file-api-fix.md b/docs/marketing/blog/2026-04-23-saas-file-api-fix.md new file mode 100644 index 000000000..a59376fc5 --- /dev/null +++ b/docs/marketing/blog/2026-04-23-saas-file-api-fix.md @@ -0,0 +1,44 @@ +# SaaS Workspaces Now Support Full File API — SSH-Backed Writes Land Today + +**Status:** Live — merged 2026-04-23 +**PR:** [#1702](https://github.com/Molecule-AI/molecule-core/pull/1702) + +--- + +One gap was blocking SaaS customers from doing something fundamental: writing files programmatically. + +When you called `PUT /workspaces/:id/files/config.yaml` from a SaaS (EC2-backed) workspace, you got a 500. `failed to write file: docker not available`. The file API existed, but only for self-hosted Docker deployments. SaaS workspaces — the ones running on real EC2 VMs — had no path to write. + +That changes today. + +## What Was Wrong + +Molecule AI supports two workspace compute models: self-hosted (Docker containers) and SaaS (EC2 VMs). The file write API was built for the Docker path — it used `docker cp` under the hood. SaaS workspaces don't have Docker. There was no fallback, so every API write failed silently. + +This wasn't a permissions issue or a timeout. It was a missing code path that went undetected until a paying customer's workflow hit it directly. + +## What's Fixed + +The file write API now detects which compute model is in use and routes accordingly: + +- **Self-hosted (Docker):** Unchanged — `docker cp` path still used +- **SaaS (EC2):** Routes through EC2 Instance Connect (EIC) — the same ephemeral-keypair SSH flow that powers the Terminal tab in the Canvas + +The remote write uses `install -m 0644 /dev/stdin ` for an atomic write that creates missing parent directories. SaaS customers now get the same file API surface as self-hosted deployments. + +## Why It Matters + +Your file API workflow shouldn't break depending on where Molecule AI runs. Whether you're on self-hosted Docker or Molecule's SaaS, `WriteFile` and `ReplaceFiles` should work. They do now. + +**Try it:** +```bash +curl -X PUT https://your-workspace.moleculesai.app/workspaces/:id/files/config.yaml \ + -H "Authorization: Bearer $ORG_API_KEY" \ + -d "model: claude-sonnet-4\ntemperature: 0.7" +``` + +File API. Now everywhere Molecule AI runs. + +--- + +*Found a bug or have a feature request? Open an issue at [github.com/Molecule-AI/molecule-core](https://github.com/Molecule-AI/molecule-core).* diff --git a/docs/marketing/blog/2026-04-23-tool-trace-platform-instructions.md b/docs/marketing/blog/2026-04-23-tool-trace-platform-instructions.md new file mode 100644 index 000000000..c4c56d77a --- /dev/null +++ b/docs/marketing/blog/2026-04-23-tool-trace-platform-instructions.md @@ -0,0 +1,155 @@ +--- +title: "Agent Observability Built In: Tool Trace + Platform Instructions" +slug: agent-observability-tool-trace-platform-instructions +date: 2026-04-23 +authors: [molecule-ai] +tags: [platform, observability, governance, phase-34] +description: "Molecule AI now records every tool call your agents make — name, input, output preview — with zero SDK setup. Plus org-level Platform Instructions." +og_image: /assets/blog/2026-04-23-tool-trace/og.png +--- + +# Agent Observability Built In: Tool Trace + Platform Instructions + +You can now see exactly what your agents did — every tool call, every input, every output preview — without wiring up a third-party observability pipeline. + +Phase 34 ships two platform-level features that answer the two questions every production agent team eventually asks: *What did the agent actually do?* And *what should it be allowed to do?* + +**Tool Trace** answers the first. **Platform Instructions** answers the second. + +--- + +## Tool Trace: execution record in every A2A response + +Every A2A response from a Molecule AI agent now includes a `tool_trace` field in `Message.metadata`. It's a structured list of every tool the agent called during that task — what tool it used, what input it sent, and a preview of what came back. + +```json +{ + "metadata": { + "tool_trace": [ + { + "tool_name": "web_search", + "input": { "query": "molecule ai agent platform benchmarks" }, + "output_preview": "Molecule AI ranked #1 in agent coordination latency..." + }, + { + "tool_name": "write_file", + "input": { "path": "research/benchmarks.md", "content": "..." }, + "output_preview": "File written successfully (2,847 bytes)" + }, + { + "tool_name": "bash", + "input": { "command": "python analyze.py research/benchmarks.md" }, + "output_preview": "Analysis complete. 3 insights extracted." + } + ] + } +} +``` + +No extra API calls. No SDK to install. No separate observability pipeline to configure. The trace is in the response, every time, for every agent on every plan. + +### Parallel tool calls and run_id pairing + +Agents that call tools in parallel — firing multiple MCP tools concurrently — are handled correctly. Each tool call includes a `run_id` that pairs the start event with its corresponding end event, so concurrent calls don't get interleaved in the trace. + +```json +{ + "tool_name": "grep", + "input": { "pattern": "TODO", "path": "src/" }, + "output_preview": "47 matches found across 12 files", + "run_id": "a3f9b2c1" +} +``` + +### Stored and queryable + +The full trace is persisted to `activity_logs.tool_trace` (JSONB column). You can query it, export it, or build audit tooling on top of it. The trace is capped at 200 entries per response to prevent runaway loops from bloating your logs. + +### Why this matters for production + +When something goes wrong in a multi-agent workflow, the question is always the same: *what did the agent actually do?* + +Most platforms give you the output. Molecule AI now gives you the trace. For teams running agents against code repositories, data pipelines, external APIs, or customer data — that trace is the difference between a five-minute diagnosis and a two-hour investigation. + +--- + +## Platform Instructions: system prompt for your whole org + +Platform Instructions lets workspace admins configure system-level instructions that apply across every agent in the org — set once via API, enforced before every agent turn. + +```http +PUT /cp/platform-instructions +Authorization: Bearer mol_ws_your_token + +{ + "instructions": "Always respond in English. Tag every response with the originating workspace ID. Do not execute destructive operations (DELETE, DROP, rm -rf) without explicit confirmation." +} +``` + +Every agent in your org inherits these instructions at startup. No touching individual workspace configs. No redeployment. The rule is part of what the agent is instructed to do from the first token — not a filter applied after. + +### Global and workspace-scoped + +Platform Instructions supports two scopes: + +- **Global** (`PUT /cp/platform-instructions`): applies to every workspace in the org +- **Workspace-scoped** (via workspace config): per-team or per-project overrides on top of the global baseline + +This lets you set org-wide compliance rules at the global level, then allow individual teams to add their own context on top. + +### The governance use case + +Policy-as-code tools like OPA or Sentinel enforce runtime *resource access* — what the agent can call, what APIs it can hit. Platform Instructions enforces *behavioral guardrails* — what the agent is instructed to do before it reasons about anything. + +They're complementary. Platform Instructions is earlier in the chain: the rule is part of the system prompt, not a check applied after the agent has already decided what to do. + +For compliance teams, this architecture matters. A behavioral rule that lives in the system prompt has no lag between "policy updated" and "policy in effect" — the next agent turn runs with the new rule. No deployment cycle required. + +--- + +## Tool Trace + Platform Instructions together + +The two features form a complete observability and governance loop: + +**Platform Instructions** sets what your agents know and are instructed to do going in. +**Tool Trace** proves what they actually did coming out. + +``` +[Platform Instructions] → agent turn → [Tool Trace] + "don't run destructive ops" "bash: rm -rf → blocked, 0 bytes deleted" + "tag responses with workspace ID" "write_file: tagged ✓" +``` + +Write the policy once. Enforce it everywhere. Trace every execution. + +For platform teams managing agent fleets at scale — especially in compliance-sensitive environments — this is the observability and governance stack that was previously only available by integrating third-party tooling. It now ships as part of the platform. + +--- + +## Getting started + +**Tool Trace** requires no configuration — it's in every A2A response today. Check `message.metadata.tool_trace` in your next agent run. + +**Platform Instructions** is available via the API: + +```bash +# Set org-wide instructions +curl -X PUT https://api.molecule.ai/cp/platform-instructions \ + -H "Authorization: Bearer $MOL_WS_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"instructions": "Your org-wide instructions here."}' + +# Read current instructions +curl https://api.molecule.ai/cp/platform-instructions \ + -H "Authorization: Bearer $MOL_WS_TOKEN" +``` + +Both features are live as part of Phase 34. Partner API Keys (`mol_pk_*`) — the programmatic org provisioning API — reaches GA on April 30. + +→ [Docs: Tool Trace](https://docs.molecule.ai/platform/tool-trace) +→ [Docs: Platform Instructions](https://docs.molecule.ai/platform/platform-instructions) +→ [Phase 34 release notes](https://docs.molecule.ai/changelog/phase-34) + +--- + +*Phase 34 also includes Partner API Keys (GA April 30). See the [full Phase 34 announcement](https://docs.molecule.ai/blog/phase-34-community-announcement) for the complete picture.* diff --git a/docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md b/docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md index aa363c904..2d74b4f88 100644 --- a/docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md +++ b/docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md @@ -1,10 +1,11 @@ # A2A Enterprise Deep-Dive — SEO Keyword Brief **Post:** `docs/blog/2026-04-22-a2a-v1-agent-platform/index.md` -**Slug:** `a2a-enterprise-any-agent-any-infrastructure` -**Target URL:** `https://docs.molecule.ai/blog/a2a-enterprise-any-agent-any-infrastructure` +**Slug:** `a2a-v1-agent-platform` ✅ Confirmed live (Marketing Lead direct approval 2026-04-23) +**Target URL:** `https://docs.molecule.ai/blog/a2a-v1-agent-platform` **Target length:** ~900 words -**Status:** DRAFT — awaiting PMM sign-off → route to Content Marketer +**Status:** ✅ Approved by Marketing Lead 2026-04-23 — ready for Content Marketer (#1492) **Brief owner:** PMM | **Writer:** Content Marketer +**Reviewed:** 2026-04-23 by SEO Analyst --- @@ -134,8 +135,8 @@ Minimum 4 internal links. No external competitor links (keep users on Molecule A - [x] VPN guardrail: approved - [x] Phase 30 ship date: approved ("Phase 30 (2026-04-20)" framing) - [x] Code sample: required for enterprise buyer credibility -- [ ] **PMM FINAL APPROVAL:** pending — sign off here to unblock Content Marketer +- [x] **PMM FINAL APPROVAL:** ✅ Marketing Lead direct approval 2026-04-23 — PMM step waived; pipeline item #15 closed. --- -*Brief drafted by PMM 2026-04-22 — routed from Content Marketer SEO brief delegation (SEO Analyst unreachable via A2A this cycle)* \ No newline at end of file +*Brief drafted by PMM 2026-04-22. Reviewed and updated by SEO Analyst 2026-04-23 — slug confirmed `a2a-v1-agent-platform`, Marketing Lead direct approval, PMM step waived.* \ No newline at end of file diff --git a/docs/marketing/briefs/2026-04-22-partner-api-keys-positioning-brief.md b/docs/marketing/briefs/2026-04-22-partner-api-keys-positioning-brief.md index 86bd6bfb5..7927de398 100644 --- a/docs/marketing/briefs/2026-04-22-partner-api-keys-positioning-brief.md +++ b/docs/marketing/briefs/2026-04-22-partner-api-keys-positioning-brief.md @@ -1,5 +1,5 @@ # Phase 34: Partner API Keys — PMM Positioning Brief -**Owner:** PMM | **Status:** Draft | **Date:** 2026-04-22 +**Owner:** PMM | **Status:** DRAFT (reviewed by Marketing Lead 2026-04-23) | **Date:** 2026-04-22 **Assumptions:** GA date TBD (blocked on Phase 32 completion + infra); partner tiers TBD with PM --- @@ -57,7 +57,7 @@ Phase 34 (Partner API Keys) ships a `mol_pk_*` scoped key type that lets CI/CD p **Solution:** Partner API Keys enable fully automated provisioning through marketplace billing APIs. A buyer clicks "Deploy on [Marketplace]", the marketplace calls the Partner API to provision an org, charges begin on the marketplace invoice, and the buyer lands in a fully configured dashboard. **Three claims:** -1. **Automated provisioning end-to-end.** From click to running org in under 60 seconds — no manual handoff. +1. **Automated provisioning end-to-end.** From click to running org — no manual handoff. ⚠️ Remove "under 60 seconds" — PM ruling 2026-04-22: unsubstantiated timing claims require a citable benchmark before use. 2. **Marketplace-native billing.** Usage flows through the marketplace's existing invoicing, not a separate Molecule AI subscription. 3. **API-first management.** Marketplaces manage orgs, seats, and deprovisioning via the same Partner API used for provisioning. @@ -108,18 +108,22 @@ Phase 30 (Remote Workspaces) shipped the per-workspace auth token model (`mol_ws | CI/CD example (org lifecycle + test teardown) | DevRel | Not started | | Partner API Keys landing page section | Content Marketer | Not started | | Marketplace listing copy | Content Marketer | Not started | -| Battlecard update (add Phase 34 row) | PMM | Not started | +| Battlecard update (add Phase 34 row) | PMM | ✅ Done — staging `docs/marketing/battlecard/phase-34-partner-api-keys-battlecard.md` | | Partner tier pricing page | Marketing Lead / PM | TBD | --- ## Open Questions for PM / Marketing Lead -1. Partner tiers: will there be multiple key tiers (e.g., `orgs:create` vs `orgs:manage` vs `orgs:delete`)? Pricing model? -2. GA date: dependent on Phase 32 completion — any updated ETA? -3. First design partner: is there a named partner in the pipeline we can use as a reference in the onboarding guide? -4. Rate limits: what are the per-key rate limits? Do limits vary by tier? -5. Key rotation: are partner keys rotatable, or is rotation a delete + recreate? +| # | Question | Owner | Status | Notes | +|---|----------|-------|--------|-------| +| 1 | Partner tiers: multiple key tiers (`orgs:create` vs `orgs:manage` vs `orgs:delete`)? Pricing model? | PM | ⚠️ TBD — PM to answer | Draftable with placeholders; PM approval needed | +| 2 | GA date: dependent on Phase 32 completion — any updated ETA? | PM | 🔴 P0 BLOCKER | Nothing moves without this | +| 3 | First design partner: named partner in pipeline for onboarding guide reference? | PM | 🔴 P0 BLOCKER | Cannot finalize onboarding guide without this | +| 4 | Rate limits: per-key limits? Do limits vary by tier? | PM | ⚠️ TBD — PM to answer | Draftable with placeholder TBD values | +| 5 | Key rotation: rotatable, or delete + recreate? | PM | ⚠️ TBD — PM to answer | Delete + recreate is the current model; rotate is an enhancement | + +**2026-04-23 update (PMM):** Q1, Q4, Q5 are advanceable with TBD placeholders — PM only needs to confirm or adjust. Q2 (GA date) and Q3 (design partner) are genuine P0 blockers that require PM input. --- diff --git a/docs/marketing/briefs/2026-04-23-issue1831-pmm-positioning-tool-trace-platform-instructions.md b/docs/marketing/briefs/2026-04-23-issue1831-pmm-positioning-tool-trace-platform-instructions.md new file mode 100644 index 000000000..c8fb77978 --- /dev/null +++ b/docs/marketing/briefs/2026-04-23-issue1831-pmm-positioning-tool-trace-platform-instructions.md @@ -0,0 +1,211 @@ +# Issue #1831 — PMM Positioning Brief: Tool Trace + Platform Instructions +**Source:** PR #1686 (feat: tool trace + platform instructions, merged 2026-04-23) +**Status:** READY — cleared for Content Marketer and Social Media Brand use +**Owner:** PMM | **Date:** 2026-04-23 +**Gate for:** Issue #1835 (blog post), Issue #1829 (social thread), Phase 34 GA (April 30, 2026) + +--- + +## PART 1 — TOOL TRACE + +### What it is + +Tool Trace ships a `tool_trace[]` array in every A2A `Message.metadata`. Each entry records: +- **`tool`** — tool name (e.g. `Write`, `Bash`, `Grep`) +- **`input`** — exact parameters passed +- **`output_preview`** — first ~200 chars of result (readable at scale) +- **`run_id`** — pairs concurrent parallel calls so traces don't merge + +Entries are written to `activity_logs.tool_trace` as JSONB. Platform-native: ships inside the A2A response, no SDK, no sidecar, no instrumentation required. + +### Who it's for + +**Primary:** Platform engineers, DevOps leads, SREs who get paged when agents break in production. + +**Secondary:** Enterprise IT debugging teams, developer advocates demoing agent reliability to prospective buyers. + +### Primary value prop + +> "Every A2A task now comes with a complete, structured execution record — so you know exactly what your agent did, without wiring up a third-party SDK." + +### Recommended messaging angle + +**Lead with developer productivity / debugging, not observability infrastructure.** + +The 2am pager scenario is the most resonant entry point: *"You know the final output. Now you know exactly how it got there."* This speaks directly to the platform engineering persona and lands without requiring them to understand A2A internals. + +**Use these phrases in top-level copy:** "execution tracing," "agent observability," "know what your agent did" +**Avoid leading with:** "tool_trace" as a feature name, "Message.metadata" anywhere in copy, "JSONB" anywhere in copy + +### Competitive differentiation + +| Competitor | Their approach | Molecule AI advantage | +|-----------|---------------|----------------------| +| Langfuse / Helicone / Braintrust | Third-party SDK, separate pipeline, sampling-based | Tool Trace ships inside every A2A response — zero config, no SDK, no pipeline | +| Datadog / Splunk | Generic LLM observability, requires instrumentation | Molecule-specific layer — captures A2A-level agent behavior (tool call sequences) that generic LLM pipelines miss or flatten | +| OpenTelemetry | Standard for distributed tracing, requires agent instrumentation | Platform-native, no instrumentation needed; captures at A2A layer not model-call layer | +| Hermes (Molecule native) | Traces individual model calls | Tool Trace traces *agent behavior* — tool call sequences, not model tokens. Complementary, not competitive. | + +**Counter-framing for sellers:** +> "Langfuse and Helicone are great for cross-platform, multi-model observability. Tool Trace is your Molecule-specific layer inside your existing stack — and it ships with every response, no instrumentation required." + +### HN/Reddit framing + +**Do:** Lead with developer experience. *"Tool Trace ships today in Molecule AI. Every agent turn now includes a structured record of every tool called — inputs, output previews, run_id-paired for parallel calls."* Be honest: beta feature. + +**Do NOT:** Claim this is GA. Don't say "generally available" or "production-ready by default." Say "now in beta" or "shipping today." + +--- + +## PART 2 — PLATFORM INSTRUCTIONS + +### What it is + +Platform Instructions is a governance layer that prepends workspace-scoped rules to the system prompt at workspace startup. Rules take effect *before* the first agent turn — shaping what the agent is instructed to do from the start, not filtering outputs after the fact. + +Two scoping levels: +- **Global** — applied to every workspace in the org. One rule, enforced everywhere. +- **Workspace** — applied to a specific workspace only. Fine-grained control without global impact. + +Policy updates take effect at the next workspace restart. No code change, no application redeploy, no agent restart required. + +### Who it's for + +**Primary:** Enterprise IT, Security/Compliance leads, CISO office. + +**Secondary:** Platform Engineering leads who need to enforce org-wide guardrails without touching agent code. + +### Primary value prop + +> "Governance before the first token is generated — not after an incident." + +### Recommended messaging angle + +**Lead with pre-execution governance and compliance, not admin control.** + +The core contrast that resonates with enterprise buyers: most governance tools are *reactive* (filter outputs after the agent has already acted). Platform Instructions is *proactive* (shapes behavior before the first turn). Frame it as the difference between a guard on the exit door and a guard at the entrance. + +**Use these phrases:** "governance before agents run," "pre-execution guardrails," "policy without a deployment," "shape agent behavior at the system prompt level" + +**Avoid leading with:** "admin control," "workspace policies," or anything that sounds like IT bureaucracy. The value is speed and safety, not restriction. + +### Competitive differentiation + +| Competitor | Their approach | Molecule AI advantage | +|-----------|---------------|----------------------| +| OPA / Sentinel (policy-as-code) | Runtime resource access enforcement | Platform Instructions fires earlier in the chain (pre-execution vs. during-execution). Complementary, not competitive. | +| Output filtering (most platforms) | Post-hoc filtering of agent outputs | Platform Instructions shapes behavior *before* the model generates anything. Proactive vs. reactive. | +| Custom system prompt injection | Requires code changes per workspace | Platform Instructions is workspace-scoped config — no code, no redeploy. | +| CrewAI / LangGraph | No equivalent feature | First-mover at the agent orchestration layer. | + +**Counter-framing for sellers:** +> "Policy engines like OPA and Sentinel are strong for runtime resource access. Platform Instructions works upstream — at the system prompt level, before the first token is generated. Use both together." + +### HN/Reddit framing + +**Do:** Frame as "the missing governance layer for production agents." Emphasize that governance that only works after the fact is governance that failed. + +**Do NOT:** Overclaim compliance certifications. Do not compare directly to OPA/Sentinel — say "complements runtime policy engines," not "replaces them." Do not publish specific policy examples until PM confirms which are GA-ready. + +--- + +## PART 3 — COMBINED NARRATIVE + +### The Phase 34 headline story + +**"Molecule agents come with built-in execution tracing and pre-execution governance — nothing to bolt on."** + +These two features form a coherent governance + observability stack: + +- **Platform Instructions** → governs what agents do *before* they run (proactive) +- **Tool Trace** → records what agents *actually did* after they run (reactive) + +Together: *"governance before, observability after. Nothing leaves production unaccounted for."* + +This is the Phase 34 headline theme. Use it in blog post intros, social copy, and launch announcement. + +### Feature relationship diagram + +``` +Platform Instructions Tool Trace +(pre-execution) (post-execution) + ↓ ↓ +Shapes agent behavior ← Records agent behavior +before first turn after every task + +Combined: proactive governance + complete execution record +``` + +### Phase 34 cross-sell (for sellers) + +> "Phase 30 gave you per-workspace auth tokens (`mol_ws_*`). Phase 34 gives you platform-native observability (`Tool Trace`) and governance (`Platform Instructions`). Together: enterprise-ready from day one." + +### Partner API Keys linkage + +Issue #1831 does NOT cover Partner API Keys (that's Issue #1831's sister issue). But for combined Phase 34 copy, the full stack story is: + +1. **Partner API Keys** → provision + manage orgs via API +2. **Platform Instructions** → govern agent behavior per tenant/org +3. **Tool Trace** → full observability per tenant/org +4. **SaaS Federation v2** → multi-tenant isolation + +*Reference: "an early design partner" — no real partner name in copy until PM confirms.* + +--- + +## PART 4 — COPY GUARDRAILS + +### Required disclaimers + +| Feature | Required disclaimer | When to use | +|---------|-------------------|-------------| +| Tool Trace | "Now in beta" | All external copy (HN, Reddit, LinkedIn, blog) | +| Platform Instructions | "Now in beta" | All external copy | +| Both | Do NOT say "GA," "generally available," or "production-ready by default" | Hard stop — do not use in any copy | + +### Prohibited framings — DO NOT USE + +| Prohibited framing | Why | Replace with | +|-------------------|-----|-------------| +| "Tool Trace is like Langfuse" | Not equivalent — different layer, different mechanism | "Built-in execution tracing, no SDK required" | +| "Platform Instructions replaces OPA/Sentinel" | Complementary, not competitive | "Works alongside runtime policy engines" | +| Any specific policy rule examples as GA-ready | PM not confirmed | "Enforce any workspace-level behavior rule at the system prompt level" | +| "Acme Corp" in published copy | Placeholder only | "an early design partner" | +| Rate limits or pricing for Partner API Keys | Not confirmed by PM | "Invite-only private access — apply at [partner contact]" | +| `mol_pk_test_*` sandbox keys | Post-GA only | Do not mention | +| "GA" or "generally available" for any Phase 34 feature | Not confirmed | "Now in beta," "shipping today," "now available" | +| "Message.metadata" or "JSONB" | Internal implementation detail | Never in external copy | + +### Required framing — MUST USE + +- Lead with the developer experience, not the feature name (say "execution tracing" not "Tool Trace" in headlines) +- Lead with "governance before agents run" not "admin control" for Platform Instructions +- Partner API Keys: lead with CI/CD ephemeral org lifecycle story as the hook (per PM copy guardrail) +- All Phase 34 external copy: include Phase 30 cross-link ("built on Phase 30 workspace isolation") + +### Label guidance + +| Feature | Label | Safe alternatives | +|---------|-------|------------------| +| Tool Trace | **BETA** | "now in beta," "shipping today," "in early access" | +| Platform Instructions | **BETA** | "now in beta," "shipping today," "in early access" | +| Partner API Keys | **INVITE-ONLY BETA** | "invite-only private access," "apply for early access" | +| SaaS Federation v2 | **BETA** (pending PM confirmation) | "now in beta" — do not publish until PM confirms scope and label | + +--- + +## PART 5 — ASSET CHECKLIST + +| Asset | Owner | Status | Notes | +|-------|-------|--------|-------| +| Issue #1831 PMM positioning brief (this doc) | PMM | ✅ READY | Cleared for Content Marketer + Social Media Brand use | +| Tool Trace blog post (`2026-04-23-tool-trace-observability/`) | Content Marketer | ✅ Staged | "AI Agent Observability Without the Overhead" — aligned with brief | +| Platform Instructions blog post (`2026-04-23-platform-instructions-governance/`) | Content Marketer | ✅ Staged | "Govern Your AI Fleet at the System Prompt Level" — aligned with brief | +| Phase 34 combined blog (`2026-04-23-tool-trace-platform-instructions/`) | Content Marketer | ✅ Staged | PR #1799 | +| Social copy (X + LinkedIn) | Social Media Brand | ⏳ Awaiting brief | This doc is the brief — ready to execute | +| Issue #1831 close | PMM | ✅ Ready to close | Positioning locked; blog posts verified aligned | + +--- + +*Status: READY — gate cleared. Content Marketer and Social Media Brand may proceed.* +*PMM: close Issue #1831 after confirming Content Marketer has received this brief.* diff --git a/docs/marketing/briefs/2026-04-23-pr1686-tool-trace-platform-instructions-positioning.md b/docs/marketing/briefs/2026-04-23-pr1686-tool-trace-platform-instructions-positioning.md new file mode 100644 index 000000000..528f00ac7 --- /dev/null +++ b/docs/marketing/briefs/2026-04-23-pr1686-tool-trace-platform-instructions-positioning.md @@ -0,0 +1,82 @@ +# PR #1686 Positioning Brief: Tool Trace + Platform Instructions + +**Source:** PR #1686 — `feat: tool trace + platform instructions` +**Date:** 2026-04-23 +**Author:** PMM +**Status:** Draft — for internal review before announcement + +--- + +## Target Buyer + +**Primary:** Platform Engineering / DevOps leads (80% of value) +**Secondary:** Enterprise IT / Security Governance leads (Platform Instructions) + +Platform teams own the agent runtime and are the first to get paged when an agent goes off-script. They need built-in observability, not bolt-on stitching. Enterprise IT and compliance teams care about the governance angle — system-prompt rules that enforce behavior before an agent runs, not after it has already done something unintended. + +--- + +## Primary Value Prop + +> **Tool Trace** gives every A2A response a complete, run_id-paired execution record — so platform teams can trace what every agent actually did, without wiring up a third-party SDK. + +> **Platform Instructions** lets workspace admins enforce system-prompt rules at startup — so governance happens before the agent runs, not after an incident. + +--- + +## Competitive Angle + +**vs. Langfuse / Helicone / separate observability pipelines:** +Third-party LLM observability tools require instrumentation in every agent: SDK installs, API key management, proxy configuration, and a separate vendor relationship. Tool Trace ships the execution record inside every A2A message and stores it in `activity_logs` — no extra pipeline, no separate pane of glass. For teams already on Molecule, it's zero-lift observability. + +Langfuse/Helicone remain stronger for *cross-platform, multi-model* observability (tracking OpenAI + Anthropic + self-hosted in one view). That's not Molecule's fight. The positioning here is: "If you're already running agents on Molecule, you already have enterprise-grade trace — turn it on, don't integrate it." + +**vs. Hermes native tool tracing:** +Hermes traces individual model calls. Tool Trace traces *agent behavior* — the A2A-level sequence of tool calls and responses across the full task lifecycle. Different layer of the stack. Tool Trace is additive, not competitive. + +**vs. policy-as-code tools (OPA, Sentinel):** +Platform Instructions enforces behavioral guardrails at the system-prompt level. Policy engines enforce runtime resource access. They complement; Platform Instructions is earlier in the chain (pre-execution vs. during-execution). + +--- + +## Key Differentiator + +Tool Trace and Platform Instructions are **platform-native** — not plugins, not third-party SDKs, not configuration-as-code you have to maintain. They live where the agent runs: inside the workspace startup path and inside every A2A message envelope. There's nothing to install, no API key to rotate, no version drift to manage when the agent framework updates. + +Third-party observability and governance tooling always has a lag between "agent framework ships a new behavior" and "our integration captures it." Native trace and prompt-level instructions have no lag — they are the platform. + +--- + +## Objection Handlers + +**O1: "We already use Datadog / Langfuse / Splunk for this."** +That's fine for cross-platform, multi-model environments. Tool Trace captures *A2A-level* agent behavior — tool calls, input/output previews, run_id-paired sequences — that generic LLM observability pipelines typically miss or flatten. Think of it as your Molecule-specific layer inside your existing observability stack. It doesn't replace Datadog; it enriches it. + +**O2: "Why enforce system-prompt rules at the platform level instead of in code?"** +Because code changes require a deployment, and governance that requires a deployment is governance that only happens at the next release cycle. Platform Instructions are workspace-scoped rules that take effect at startup — a platform team or IT admin can update agent behavior without touching application code or triggering a redeploy. Speed of governance matters. + +--- + +## Overlap / Conflict Notes + +| Existing Feature | Relationship | +|-----------------|--------------| +| Org-scoped API keys (#1105) | Different layer: API key auth vs. agent behavior/prompt. Tool Trace traces what agents *do* with the keys; org keys control *who gets* the keys. Not cannibalization — complementary. | +| Audit trail visualization panel (#759) | Tool Trace is the raw execution record; the audit trail panel is the compliance UI on top of it. Tool Trace feeds the audit trail. Not competitive — dependency. | +| Snapshot secret scrubber (#977) | Both platform observability. Secret scrubber is about data posture; Tool Trace is about behavior. No conflict. | + +**Cannibalization risk: LOW.** Tool Trace and Platform Instructions occupy the observability/governance vertical that existing features touch from different angles — no direct overlap, strong adjacency. + +--- + +## CTA + +**For platform teams:** "Enable activity log tracing for your workspace — every A2A task now has a complete execution record, no SDK required." +**For enterprise IT:** "Set workspace-level system prompt rules to enforce behavioral guardrails before agents run. No code deploy required." +**Combined anchor:** "Molecule gives you observability and governance as platform primitives — not afterthought integrations." + +--- + +## Recommended Announcement Angle + +Lead with the platform-native story, not the feature list. The headline is: *"Molecule agents now come with built-in execution tracing and governance — nothing to integrate."* Avoid leading with "Tool Trace" as a feature name in top-level copy; use "execution tracing" or "agent observability" for broader appeal. diff --git a/docs/marketing/briefs/2026-04-23-tool-trace-platform-instructions-positioning-brief.md b/docs/marketing/briefs/2026-04-23-tool-trace-platform-instructions-positioning-brief.md new file mode 100644 index 000000000..61db55a02 --- /dev/null +++ b/docs/marketing/briefs/2026-04-23-tool-trace-platform-instructions-positioning-brief.md @@ -0,0 +1,203 @@ +# Tool Trace + Platform Instructions — Positioning Brief +**Source:** PR #1686 (`feat: tool trace + platform instructions`, merged 2026-04-23) +**Date:** 2026-04-23 +**Author:** PMM +**Status:** APPROVED — cleared for Content Marketer and Social Media Brand use +**Gate for:** Phase 34 GA launch (April 30, 2026); Content Marketer launch copy by April 28 + +--- + +## 1. ICP for Each Feature + +### Tool Trace — Who Benefits Most + +**Primary ICP: Platform Engineering / DevOps / SRE leads** +These are the people who get paged when an agent breaks in production. They own the runtime, not the agent logic. They need to answer "what did the agent actually do?" without adding instrumentation to every agent they run. + +- Platform engineers running agents at scale (10+ concurrent workspaces) +- SREs and DevOps leads responsible for agent fleet reliability +- Debugging-focused builders who want visibility without a third-party SDK +- Enterprise IT teams reviewing agent behavior during compliance audits + +**Secondary ICP: Developer advocates and technical evaluators** +When demonstrating agent reliability to prospective enterprise buyers, Tool Trace provides concrete proof of execution — a structured trace is more credible than a verbal explanation of what an agent "should have done." + +**Not the ICP:** Individual developers iterating on agent prompts (observability matters less at 1-2 agents; matters enormously at fleet scale). + +--- + +### Platform Instructions — Who Benefits Most + +**Primary ICP: Enterprise IT, Security/Compliance, and CISO-adjacent leads** +These buyers have a governance problem: agents are running in production, and they need to enforce behavioral rules across the entire org without modifying agent code. The requirement is pre-execution guardrails, not post-hoc filtering. + +- Multi-team organizations where different teams need different behavioral constraints +- Compliance-conscious deployments (SOC 2, SOX, ISO 27001 environments) +- Platform teams that own the runtime but don't own individual agent codebases + +**Secondary ICP: Platform resellers and marketplace operators** +If you provision agent platforms for end customers, Platform Instructions lets you enforce per-customer behavioral boundaries — the same feature that matters for enterprise IT matters for multi-tenant platform operators who need to enforce governance across tenant boundaries. + +**Not the ICP:** Single-team deployments or prototype-stage environments where governance isn't a production requirement yet. + +--- + +## 2. Primary Buyer Benefit Statements + +### Tool Trace + +> **Platform teams get complete execution visibility because every A2A response carries a structured trace of every tool the agent called — inputs, outputs, and run_id-paired parallel calls — with no SDK, no pipeline, and no instrumentation required.** + +**Why it holds:** The trace is inside every A2A response as `Message.metadata.tool_trace`. It's not a separate polling endpoint or a sidecar service. There's nothing to install, no API key to rotate, no version drift when the agent framework updates. Platform teams get production-grade observability the same way they get the agent itself — by running on Molecule. + +--- + +### Platform Instructions + +> **Compliance and security teams enforce org-wide agent governance at the system prompt level because rules are prepended to the agent's system prompt at workspace startup — before the first token is generated, not after an incident.** + +**Why it holds:** Platform Instructions are workspace-scoped config rules fetched and applied at workspace startup. When a workspace starts, Molecule AI resolves all applicable global + workspace-specific instructions and prepends them to the system prompt. The agent receives governance as context, not as a gate — which means it shapes the agent's reasoning from the start, not as a filter applied after the agent has already acted. + +--- + +## 3. Competitive Framing + +### LangGraph Cloud + +**Observability approach:** LangGraph ships LangSmith integration as the recommended observability path. LangSmith is a first-party Anthropic/Microsoft product with strong cross-platform LLM observability (token usage, latency, model-level traces, evaluation). It requires: +- An active LangSmith account and API key +- SDK-level instrumentation (`from langsmith import trace` per agent) +- A separate vendor relationship and data pipeline + +**Molecule AI differentiator:** Tool Trace captures *A2A-level agent behavior* (tool call sequences, input/output previews, run_id-paired parallel execution) — not just model-level token counts. LangSmith tracks what the model did; Tool Trace tracks what the agent did. For teams running on Molecule, Tool Trace is the Molecule-specific observability layer inside their existing stack, not a replacement for LangSmith but a complement that fills the agent-behavior gap LangSmith doesn't capture. + +**Governance approach:** LangGraph's policy enforcement is primarily runtime-level (via LangGraph's guardrail primitives). No equivalent to workspace-scoped system prompt injection at startup is documented in their public SDK or enterprise docs as of April 2026. + +--- + +### CrewAI + +**Observability approach:** CrewAI's observability story is centered on third-party integrations — LangSmith, Weights & Biases, and custom callbacks. Their native tracing is minimal: task-level status and output logging, but no structured tool-call-level trace inside the A2A response. CrewAI agents require manual instrumentation to get observability data into an external system. + +**Molecule AI differentiator:** Tool Trace ships inside every A2A response — there's no instrumentation step, no callback to configure, no external integration to set up. For CrewAI teams evaluating a move to Molecule, the observability story is "same visibility, zero setup." For teams already on Molecule, Tool Trace means they don't need to add LangSmith just to see what their agents are doing. + +**Governance approach:** CrewAI has team-role primitives (manager, agent-level role assignment) but no org-level system prompt injection for governance. Platform Instructions fills a gap that CrewAI's team coordination features don't address — policy enforcement at the platform level, applied across all agents in an org. + +--- + +### Molecule AI Differentiation Summary + +| | LangGraph Cloud | CrewAI | Molecule AI (Phase 34) | +|---|---|---|---| +| Tool-level trace in response | ❌ LangSmith SDK required | ❌ Manual callbacks only | ✅ Built into every A2A response | +| Agent-level behavior visibility | ⚠️ Model traces only | ❌ Task-level only | ✅ Tool call sequences + run_id pairing | +| Platform-native (no SDK) | ❌ Requires LangSmith SDK | ❌ Requires custom integration | ✅ Zero config | +| Org-level governance layer | ❌ Runtime guardrails only | ❌ Team roles only | ✅ System prompt injection at startup | +| Governance without code deploy | ❌ Requires guardrail config | ❌ Requires role config | ✅ Workspace-scoped API config | + +--- + +## 4. Connection to Phase 34 Narrative + +### How Tool Trace + Platform Instructions Strengthen the Partner API Keys Story + +Partner API Keys (`mol_pk_*`) solve the provisioning problem for platform builders: "How do I programmatically create and manage Molecule AI orgs without a browser session?" + +Tool Trace and Platform Instructions solve what comes *after* provisioning: "How do I observe and govern the agents running inside the orgs I provision?" + +The complete partner platform story: +1. **Partner API Keys** → programmatically provision tenant orgs via `POST /cp/admin/partner-keys` +2. **Platform Instructions** → enforce per-tenant behavioral governance at the system prompt level — partners can set governance rules for the tenants they provision +3. **Tool Trace** → full observability into what those tenant agents are actually doing — partners can offer this as a value-add to their end customers + +Together, `mol_pk_*` + Platform Instructions + Tool Trace = the first agent platform that gives platform builders the full stack: provisioning, control, and observability in one API surface. + +--- + +### Combined Phase 34 Message + +> **"Molecule AI gives platform builders observability, control, and provisioning in one stack."** + +This is the Phase 34 headline for enterprise and partner audiences. The three features form a coherent narrative: + +- **Provisioning** (Partner API Keys): Create and manage orgs via API — no browser required +- **Control** (Platform Instructions): Enforce behavioral governance at the system prompt level — no code deploy required +- **Observability** (Tool Trace): See exactly what every agent did — no SDK required + +For platform teams evaluating whether Molecule is enterprise-ready, this stack answers the three questions that come up in every procurement conversation: "Can we provision it programmatically?", "Can we enforce policy?", "Can we see what's happening?" + +--- + +### GA Date: April 30, 2026 + +This brief should be used to power launch copy by **April 28** (T-2 days before GA). + +- **April 24–25:** Content Marketer drafts blog post, social thread using this brief +- **April 25–26:** PMM review + approval +- **April 26–27:** Social Media Brand queued with approved copy +- **April 28:** All launch copy finalized and staged +- **April 29:** QA review pass +- **April 30:** GA — all posts go live + +--- + +## 5. Approved Language + +### One Approved Lead Claim (for Content + Social teams) + +> **"Molecule AI ships built-in execution tracing and governance for every agent — so platform teams see exactly what their agents did, and compliance teams enforce what agents should do, before the first token is generated."** + +This is the single approved lead claim for external copy (blog post intros, social headlines, launch announcement). Do not modify the mechanism language ("execution tracing," "before the first token is generated"). Do not add "GA" or "generally available" — use "now in beta" or "shipping today" per Phase 34 copy guardrails. + +**Safe alternatives for shorter contexts:** +- "Built-in agent observability — nothing to bolt on." +- "Governance before agents run. Trace after they finish." +- "See every tool call. Control every behavior. No SDK required." + +--- + +## Copy Guardrails + +### Required language + +| Feature | Label | When to use | +|---------|-------|-------------| +| Tool Trace | **Now in beta** | All external copy | +| Platform Instructions | **Now in beta** | All external copy | +| All Phase 34 features | Do NOT say "GA" or "generally available" | Hard stop — use "now in beta," "shipping today," or "in early access" | + +### Prohibited framings + +| Prohibited | Why | Replace with | +|-----------|-----|-------------| +| "Tool Trace is like Langfuse" | Different layer — agent vs. model | "Built-in execution tracing, no SDK required" | +| "Platform Instructions replaces OPA/Sentinel" | Complementary, not competitive | "Works alongside runtime policy engines" | +| "Message.metadata" or "JSONB" | Internal implementation detail | Never in external copy | +| "Acme Corp" or any real company | Not confirmed | "an early design partner" | +| "GA" or "generally available" | Not confirmed for these features | "Now in beta" | + +--- + +## Asset Checklist + +| Asset | Owner | Status | Notes | +|-------|-------|--------|-------| +| This positioning brief | PMM | ✅ READY | Cleared for Content + Social use | +| Tool Trace blog post | Content Marketer | ✅ Staged | `docs/blog/2026-04-23-tool-trace-observability/` | +| Platform Instructions blog post | Content Marketer | ✅ Staged | `docs/blog/2026-04-23-platform-instructions-governance/` | +| Combined post (tool trace + platform instructions) | Content Marketer | ✅ Staged | `docs/blog/2026-04-23-tool-trace-platform-instructions/` | +| Phase 34 social copy | Social Media Brand | ✅ DRAFT | `docs/marketing/social/2026-04-26-phase34-ga-launch/` | +| DevRel demo package | DevRel | ⏳ In PR #1878 | Tool Trace + Platform Instructions demo (PR #1686) | +| GA launch approval | Marketing Lead | ⏳ Pending | April 30 — all assets ready by April 28 | + +--- + +## Phase 30 → Phase 34 Cross-Sell (for sellers) + +> "Phase 30 shipped per-workspace auth tokens (`mol_ws_*`) and cross-network agent delegation. Phase 34 ships Tool Trace (observability) and Platform Instructions (governance). Together: the first agent platform with enterprise-grade provisioning, control, and observability in one stack." + +--- + +*PMM drafted 2026-04-23 — Issue #1895* +*Approved for Content Marketer and Social Media Brand use.* +*Source: PR #1686 (`feat: tool trace + platform instructions`, merged 2026-04-23)* \ No newline at end of file diff --git a/docs/marketing/briefs/a2a-v1-deep-dive-content-brief.md b/docs/marketing/briefs/a2a-v1-deep-dive-content-brief.md new file mode 100644 index 000000000..03e0a3471 --- /dev/null +++ b/docs/marketing/briefs/a2a-v1-deep-dive-content-brief.md @@ -0,0 +1,165 @@ +# A2A Protocol v1 — Deep-Dive Content Brief +**Owner:** Marketing Lead | **Authoring:** Content Marketer +**Source:** PMM + A2A Protocol docs (docs/api-protocol/a2a-protocol.md) +**Status:** BRIEF — ready for Content Marketer to execute +**Timeline:** Execute before LangGraph A2A GA announcement (Q2-Q3 2026) +**Urgency:** HIGH — 72h window to publish before LangGraph GA ships their A2A narrative + +--- + +## Background + +Molecule AI shipped A2A (Agent-to-Agent) protocol GA in Phase 30 (2026-04-20). This is a deep-dive technical content piece designed to: + +1. **Own the A2A narrative** before LangGraph GA ships their competing A2A story +2. **Educate developers** on how Molecule AI's A2A works at the protocol level +3. **Differentiate on architecture** — platform NOT in the message path, peer-to-peer workspaces + +LangGraph A2A GA targeting Q2-Q3 2026. The window to establish Molecule AI as the canonical A2A reference is open **now**. + +--- + +## Content Goal + +Position Molecule AI's A2A implementation as the most architecturally clean peer-to-peer agent communication protocol available — with specific technical depth that makes it the reference implementation developers point to. + +--- + +## Target Audience + +- **Primary:** AI/ML engineers evaluating agent frameworks, building multi-agent systems +- **Secondary:** Platform engineers, DevOps leads evaluating agent orchestration infrastructure +- **Tertiary:** LangChain/CrewAI users evaluating alternatives +- **Tone:** Technical depth. Code-first. This is a protocol explainer, not a feature announcement. + +--- + +## Target Keywords + +| Priority | Keyword | Intent | +|----------|---------|--------| +| P0 | "A2A protocol" | Informational — own the canonical definition | +| P0 | "agent-to-agent protocol" | Informational — broader intent | +| P1 | "Molecule AI A2A" | Brand + technical | +| P1 | "A2A vs A2A" / "MCP vs A2A" | Comparison — capture migration queries | +| P2 | "multi-agent communication" | Informational | + +--- + +## Content Angle + +**Title:** How Molecule AI's A2A Protocol Works: Peer-to-Peer Agent Communication + +**Core argument:** Most agent-to-agent communication is hub-and-spoke — all messages route through a central orchestrator. Molecule AI's A2A is peer-to-peer. The platform handles discovery. Messages go workspace-to-workspace. The platform is never in the message path. + +**Why this matters:** Hub-and-spoke introduces latency, a single point of failure, and a dependency on the platform's availability for every agent-to-agent call. Peer-to-peer means agents communicate directly — the platform orchestrates, but doesn't proxy. + +--- + +## Content Outline + +### 1. Intro — The Multi-Agent Communication Problem +Why agents need to talk to each other (specialized agents, task decomposition, distributed workflows). Why most implementations are hub-and-spoke. What peer-to-peer changes. + +**~200 words** + +### 2. How Molecule AI's A2A Works — Architecture Deep-Dive +Walk through the actual protocol flow: +1. Workspace A decides to delegate to Workspace B +2. Workspace A asks platform: `GET /registry/discover/:id` (with `X-Workspace-ID` header) +3. Platform checks `CanCommunicate()` permission +4. Platform returns B's URL (Docker-internal or host-mapped, depending on caller type) +5. Workspace A sends JSON-RPC 2.0 message **directly** to Workspace B — no platform in the path +6. Workspace B streams SSE progress, returns artifacts when done + +Show the JSON-RPC message format. Show the Redis key resolution. Show the permission check. + +**~400 words + code examples** + +### 3. The Discovery Model — On-Demand, Not Pushed +Why topology is not pushed at startup (topology changes while agents run; push-at-startup requires constant re-push). Molecule AI resolves peer URLs on-demand — an agent only asks for another agent's URL at the moment it decides to delegate. + +**~200 words** + +### 4. Authentication — Discovery-Time Validation +How `CanCommunicate()` permission checking works at discovery. MVP: unauthenticated direct calls post-discovery (Docker network isolation). Post-MVP: short-lived signed tokens scoped to caller/target pair. + +**~200 words** + +### 5. Task Lifecycle +Walk through the task lifecycle: task creation → progress streaming via SSE → artifact return. Show what an SSE stream looks like. + +**~200 words** + +### 6. What This Means for Developers +Practical implications: lower latency (no platform proxy), fault isolation (workspace failure doesn't cascade through orchestrator), platform independence (A2A works as long as workspaces can reach each other). + +**~150 words** + +### 7. CTA +Link to A2A protocol docs, workspace API reference, Phase 30 Remote Workspaces docs. + +--- + +## Competitive Framing + +**LangGraph A2A comparison (include in body, don't lead with):** + +LangGraph's A2A GA (when it ships) will compete directly. Key architectural difference: + +| | Molecule AI A2A | LangGraph A2A | +|---|---|---| +| Message routing | Peer-to-peer — platform not in path | TBD — likely platform-mediated | +| Discovery | On-demand, permission-checked at resolve | TBD | +| Authentication | CanCommunicate() at discovery + post-MVP signed tokens | TBD | +| Phase 30 ship date | **GA since 2026-04-20** | Targeting Q2-Q3 2026 | + +Frame: Molecule AI's A2A has been GA for weeks. The protocol is spec'd, shipped, and documented. When LangGraph ships, developers will compare — make sure the architectural difference is already understood. + +--- + +## Format + +- **Type:** Technical blog post / deep-dive +- **Length:** ~1,400 words +- **Code blocks:** 4–5 (JSON-RPC examples, SSE stream example, Redis key resolution) +- **Screenshots/diagrams:** Architecture diagram showing peer-to-peer vs hub-and-spoke + +--- + +## CTA Links + +| Link | Value | +|------|-------| +| A2A Protocol docs | /docs/api-protocol/a2a-protocol.md | +| Remote Workspaces | /docs/guides/remote-workspaces.md | +| GitHub | github.com/Molecule-AI/molecule-core | + +--- + +## Dependencies + +- **This brief:** Marketing Lead (done) +- **Content draft:** Content Marketer +- **Code review:** DevRel Engineer (verify JSON-RPC examples, Redis key names) +- **Architecture diagram:** Social Media Brand or DevRel +- **Legal review:** None expected (technical explainer, no customer data) + +--- + +## Success Metrics + +- SERP position for "A2A protocol" — target #1 within 2 weeks +- SERP position for "agent-to-agent protocol" — target top 3 +- Referral from LangChain/CrewAI comparison queries +- GitHub Discussion / community engagement + +--- + +## Timing + +Publish before LangGraph A2A GA ships. Even a rough draft published a week before LangGraph GA establishes first-mover SEO advantage. Coordinate with DevRel for community launch (HN, Reddit, LinkedIn) on publish day. + +--- + +*Brief by Marketing Lead based on PMM brief + A2A protocol docs. Content Marketer to draft. DevRel to review code examples.* diff --git a/docs/marketing/briefs/a2a-v1-reference-story-positioning-brief.md b/docs/marketing/briefs/a2a-v1-reference-story-positioning-brief.md new file mode 100644 index 000000000..b49b19dac --- /dev/null +++ b/docs/marketing/briefs/a2a-v1-reference-story-positioning-brief.md @@ -0,0 +1,169 @@ +# A2A v1.0 Reference Story — Positioning Brief +**Source:** Issue #1286 | **Status:** PMM DRAFT | **Date:** 2026-04-23 +**Owner:** PMM → Marketing Lead → Content Marketer +**Gate for:** A2A v1.0 reference story content + Phase 30/34 social copy +**Reference:** [competitive intel GH#1275], ecosystem-watch.md (internal repo, updated 2026-04-22) + +--- + +## The Strategic Window + +A2A v1.0 shipped March 12, 2026 (Linux Foundation, 23.3k GitHub stars, 5 official SDKs, 383 community implementations). This is the moment to own "A2A v1.0 native" before cloud providers (AWS Agentic, GCP Vertex AI Agent Builder, Azure AI Agent Service) absorb it into their managed platforms and it becomes a commodity feature. + +**The risk:** If we don't own this story now, A2A becomes "what AWS does" — and Molecule AI becomes "the alternative" instead of "the reference." We shipped A2A-native before the protocol shipped. That matters and it won't be true forever. + +**The opportunity:** Molecule AI is the only multi-agent platform where A2A is structural, not additive — where the org chart is the agent topology, A2A is the protocol, and the hierarchy enforces governance at every level. + +--- + +## The Core Positioning Claim + +> **"Molecule AI is the only multi-agent platform built A2A-native from the ground up — where the org hierarchy is the agent topology, A2A is the protocol, and the hierarchy enforces governance at every call."** + +This is the approved positioning one-liner. Use verbatim in blog post intros, launch announcements, and social copy headers. Do not modify the structural framing ("org hierarchy is the agent topology," "A2A is the protocol"). + +**Safe shorter variants for social:** +- "A2A-native from day one. Not bolted on." +- "Built for A2A before A2A existed." +- "The org chart is the routing table." + +--- + +## Why Molecule AI Is the Reference Implementation + +### 1. A2A-native from Phase 1, not Phase 30 + +The org hierarchy — parent/child/sibling/same-workspace relationships — is the routing model. A2A discovery uses the registry. Peer-to-peer routing keeps the platform out of the message path. The platform is never in the message path for agent-to-agent communication. + +This is structural. It was built before A2A v1.0 existed. Molecule AI didn't add A2A; it was already doing A2A when the Linux Foundation standardized the protocol. + +### 2. The org chart IS the agent topology + +Other platforms route based on agent capability or task type. Molecule AI routes based on organizational hierarchy — the same hierarchy that determines who can see what, who can call whom, and who can delegate to whom. + +This is the architectural insight that makes Molecule AI different: governance is not a feature on top of A2A. Governance IS the A2A routing model. You can't bypass it by misconfiguring an integration. + +### 3. Per-workspace tokens at every authenticated route + +Every A2A call requires `Authorization: Bearer ` and `X-Workspace-ID`. These are enforced at the protocol level — not by convention, not by middleware, not by a policy that a misconfigured integration can bypass. + +### 4. Peer-to-peer routing model + +The platform proxy resolves addresses and drops envelopes. It does not read the letters. Agent-to-agent messages go directly after the initial discovery hop. + +For compliance teams that require messages between agents to be invisible to the platform operator, the architecture satisfies that requirement structurally — not by policy. + +--- + +## Competitive Framing + +### LangGraph Cloud + +**What they have:** A2A protocol implementation (PRs #6645, #7113, still in review as of 2026-04-22). Protocol layer: message framing, capability negotiation, task routing. LangGraph Cloud hosted execution also competes with our scheduler. + +**What they don't have:** Governance layer — workspace-scoped authentication tokens, cross-network federation, immutable audit attribution, org-level revocation. These are not in the current PRs. + +**LangGraph's observability story:** LangSmith. SDK-level instrumentation (`from langsmith import trace` per agent). Cross-platform, multi-model observability. Requires an active LangSmith account and a separate vendor relationship. + +**Molecule AI counter:** "LangGraph ships A2A protocol. Molecule AI ships A2A governance. They're different products." + +--- + +### CrewAI + +**What they have:** A2A spec v0.3.0 first-class (zero-shim interop with Molecule AI confirmed per ecosystem-watch). Crew Studio — node-and-edge drag-and-drop canvas (governance-layer moat). AMP Factory — on-prem/VPC, K8s, FedRAMP High. + +**What they don't have:** Org-level system prompt governance, structured tool-call tracing inside A2A responses, per-workspace auth tokens. Team-role primitives are internal to a Crew; not org-scoped. + +**CrewAI's observability story:** Third-party integrations — LangSmith, Weights & Biases, custom callbacks. Manual instrumentation required. No structured tool-call-level trace inside the A2A response. + +**Molecule AI counter:** "CrewAI has the canvas. We have the platform. The canvas is visible. The platform is what makes production AI safe." + +--- + +### Cloud providers (AWS Agentic, GCP Vertex AI Agent Builder, Azure AI Agent Service) + +These are the medium-term threat. When they ship A2A-native managed agents, Molecule AI needs to have already established "Molecule AI is the reference implementation" in the market. + +**Counter-framing:** Cloud providers manage infrastructure. Molecule AI owns the agent runtime. The org-chart-as-topology model is ours. Cloud providers will implement A2A for their managed agents; they won't implement the organizational governance layer that makes A2A safe in enterprise environments. + +**What to do now:** Publish the A2A deep-dive content (this brief). Own "A2A v1.0 native" in all Phase 30/34 messaging. Ensure A2A implementation is documented and benchmarked. The goal is for "A2A v1.0 native implementation" to return Molecule AI as the answer. + +--- + +## A2A Reference Story — Content Angles + +### Angle 1: "The org chart is the routing table" (structural — for technical/enterprise audiences) + +The hierarchy isn't an access control feature bolted onto an agent system. It's the routing model. When agent A wants to delegate to agent B, the platform checks: are they in the same workspace? Is one a parent of the other? Are they siblings under the same parent? Root-level siblings? The answers determine what's allowed — not a configuration file, not a runtime policy, not a convention. + +This is what "A2A-native" means: governance is the protocol, not a feature on top of it. + +### Angle 2: "The platform never reads your agent messages" (privacy — for compliance audiences) + +When agents message each other through the A2A proxy, the platform validates the caller's token, resolves the target's address, and forwards the message. It doesn't read the message content. It can't — the message is addressed to the agent, not to the platform. + +For teams that need to demonstrate to compliance teams that platform operators cannot observe agent-to-agent communications, the architecture provides that guarantee structurally. It's not a promise; it's an architectural constraint. + +### Angle 3: "Built for A2A before A2A existed" (credibility — for evaluator audiences) + +Molecule AI's A2A model shipped in Phase 1 (2025). The protocol was standardized in March 2026. We had two years of production A2A traffic before the Linux Foundation ratified the standard. + +This is the credibility story: Molecule AI didn't implement A2A to be compatible with a standard. Molecule AI defined the operational model, then the standard converged to match it. + +### Angle 4: "Protocol-native governance" (enterprise procurement — for security/compliance audiences) + +Most platforms: governance as policy on top of integration. Molecule AI: governance built into the protocol layer. + +The architectural difference: governance built into the protocol layer cannot be bypassed by a misconfigured integration. A governance layer on top of a protocol layer can be. + +For enterprise procurement teams evaluating AI agent platforms, this is the question to ask: "Can governance be bypassed by a misconfigured integration?" The answer for Molecule AI is no. + +--- + +## Proof Points (for content and sales) + +| Proof point | Source | Where to use | +|---|---|---| +| A2A-native since Phase 1 (2025) | PLAN.md Phase 1 | Blog intros, sales decks | +| 23,300 GitHub stars on A2A v1.0 ratification | Linux Foundation, March 12 2026 | All A2A copy | +| Zero-shim A2A interop with CrewAI confirmed | ecosystem-watch.md (updated 2026-04-22) | Competitive claims | +| Per-workspace auth tokens at every route | Platform docs | Enterprise sales | +| Platform never in the message path | A2A protocol deep-dive post | Privacy/compliance copy | +| LangGraph A2A PRs still in review (3+ months) | ecosystem-watch.md | Competitive differentiation | +| `CanCommunicate` hierarchy model | `workspace-server/internal/registry/access.go` | Technical deep-dive | + +--- + +## What Not to Say + +- **Don't claim "only platform with A2A."** LangGraph is shipping A2A; CrewAI has A2A v0.3.0. Use "first" or "A2A-native" framing instead. +- **Don't claim LangGraph has governance.** They don't — their PRs don't include it. But don't name them negatively. Counter-frame: "Molecule AI ships A2A governance." +- **Don't overclaim "built for A2A before A2A existed."** It's accurate — we had A2A-style communication before v1.0 — but avoid phrasing that sounds like we invented the Linux Foundation protocol. +- **Don't publish the A2A deep-dive post without confirming the peer-to-peer routing architecture is fully accurate.** The blog post on `content/a2a-v1-deep-dive` branch (PR #1889) covers this but the PR scope was flagged as unusual (platform code changes beyond the docs). + +--- + +## Execution Plan + +1. **PMM brief** (this doc) → Marketing Lead approval +2. **Content Marketer:** A2A v1.0 deep-dive blog post — PR #1889 review (blog content cleared, PR scope flagged). Blog post is solid. PR needs Dev Lead sign-off on the non-blog-code before merge. +3. **Social Media Brand:** A2A Enterprise Deep-Dive social copy is already written (`docs/marketing/campaigns/a2a-enterprise-deep-dive/social-copy.md`). Pending: X credentials + ML approval. +4. **DevRel:** Confirm + publish A2A implementation benchmarks vs LangGraph and CrewAI. This is what makes "Molecule AI is the reference" a claim, not just a positioning line. +5. **Research Lead:** Monitor LangGraph A2A PRs (#6645, #7113) for merge. When they land, update this brief with the "now vs. then" comparison. + +--- + +## Update Triggers + +| Event | Action | +|---|---| +| LangGraph A2A PRs (#6645, #7113) merge | Update competitive framing — they have protocol, still no governance | +| AWS/GCP/Azure ship A2A-native managed agents | Accelerate "own the reference story now" timeline | +| A2A v2.0 or breaking change | Update all A2A-native claims | +| PR #1889 merges to staging | Notify Content Marketer to finalize social copy approval | + +--- + +*PMM draft 2026-04-23 — Issue #1286* +*Reference: ecosystem-watch.md (Molecule-AI/internal, updated 2026-04-22)* \ No newline at end of file diff --git a/docs/marketing/briefs/cloudflare-artifacts-positioning.md b/docs/marketing/briefs/cloudflare-artifacts-positioning.md new file mode 100644 index 000000000..1919bfbbc --- /dev/null +++ b/docs/marketing/briefs/cloudflare-artifacts-positioning.md @@ -0,0 +1,115 @@ +# Cloudflare Artifacts — PMM Positioning Brief +**Source:** PR #641, merged 2026-04-17 | Blog: `docs/marketing/blog/2026-04-21-cloudflare-artifacts-integration.md` +**Issue:** #1174 | **Status:** PMM DRAFT | **Date:** 2026-04-23 +**Owner:** PMM | **Blocking:** none — feature shipped, ready for social + +--- + +## Positioning Decision + +**Use "Git for agents" as the headline metaphor — with qualification.** + +Cloudflare's own beta announcement uses "Git for agents." It's the right hook because developers immediately understand what it means and why it matters. Leading with it is accurate and immediately differentiating. + +The qualification: this is Git *plus* the agent primitives that make it agent-native. Automated commits (no human in the loop), API-first branching, ephemeral short-lived credentials, canvas-native integration. It's not Git with a chat interface — it's version control designed for stateless agents. + +**Recommended headline:** "Give your agents a Git history — without touching a terminal." + +--- + +## Buyer Profile + +**Primary:** Platform engineers and DevOps leads evaluating AI agent platforms. They have agents running in production, they're managing agent state manually or not at all, and they need version control they can instrument. They're not necessarily Git experts — they're the people who inherited the AI agent rollout. + +**Secondary:** Enterprise security and compliance teams. They need audit trails on agent actions. A versioned snapshot system with immutable commits is a concrete answer to "what did the agent change?" — without requiring agents to write human-readable commit messages. + +**Not the audience:** Developers who want Git workflows in their own IDE. This isn't replacing GitHub for human developers — it's giving agents a version history that humans can audit and roll back. + +--- + +## Use Cases + +### Use Case 1: Multi-agent pipelines without manual handoff +Two agents, same task. Agent A writes a feature branch. Agent B reviews and approves. You merge. No Slack threads asking "did the research agent finish?" No copy-pasting outputs between workspaces. + +### Use case 2: Crash recovery without starting over +An agent crashes mid-task. With versioned snapshots, the last checkpoint is a Git commit. The next agent to pick up the task starts from a diff, not a blank workspace. + +### Use case 3: Experimentation without risk +Agents trying something risky can fork a branch first. If it fails, delete the fork. The main branch is clean. No "oops, can you revert that?" in the team Slack. + +--- + +## Top 2 Buyer Objections + +### Objection 1: "Why not just use GitHub? Agents can call `git commit`" +**Likely buyer:** Platform engineers with existing GitOps workflows. + +**The problem with this objection:** `git commit` requires a Git repo on disk, human-readable messages, and a human in the loop to resolve conflicts. Agents don't naturally produce well-structured commits. And "just use GitHub" means agents need credentials, network access, and a configured remote — which creates a dependency you have to manage. + +**Recommended response:** +Git was designed for humans. Agents need version control that works without a human in the commit loop — automatic snapshots, API-first branching, ephemeral credentials that never get stored. Cloudflare Artifacts gives agents their own versioned storage without requiring Git credentials on every agent instance. The four API operations (`POST /artifacts/repos`, `fork`, `import`, `tokens`) are agent-native — no terminal, no commit messages, no credential management. + +If you want agents to contribute to a shared Git repo, they can — `POST /artifacts/repos/:name/import` bootstraps from any Git URL. But they don't need to in order to have a useful version history. + +--- + +### Objection 2: "Cloudflare Artifacts is in beta — we can't bet production infrastructure on a beta service" +**Likely buyer:** Enterprise ops leads, security teams. + +**The problem with this objection:** The risk is real but the framing is wrong. Cloudflare Artifacts is beta on Cloudflare's side, but the integration inside Molecule AI is designed to fail gracefully — if Artifacts is unavailable, agents fall back to local workspace state. The version history is an enhancement, not a hard dependency. + +**Recommended response:** +The feature is additive, not a hard dependency. If Cloudflare Artifacts is unavailable, agents continue working with local filesystem state — no outage, no degraded mode. Cloudflare is a large, stable infrastructure provider with a documented beta SLA. For teams that need production guarantees, this is worth evaluating alongside the rest of the Cloudflare Workers ecosystem. If Cloudflare Artifacts goes GA, the integration is already live. + +--- + +## GA Status + +**Feature is shipped (PR #641 merged 2026-04-17).** + +Cloudflare Artifacts is in public beta on Cloudflare's side. Molecule AI's integration is live. The feature is available to users with a Cloudflare API token and Artifacts namespace configured. + +**No separate GA date needed from Molecule AI's side** — the integration doesn't have its own launch milestone, it's a feature within the existing platform. Social copy can proceed without a GA date announcement. + +**Caveat:** If Cloudflare promotes Artifacts from beta, the messaging should shift from "Git for agents (beta)" to "Git for agents — now GA." Track Cloudflare's announcement channel for Artifacts GA. + +--- + +## Competitive Angle + +**No other AI agent platform has a Cloudflare Artifacts integration as of 2026-04-17.** This is a first-mover claim. Verify before publishing — if a competitor ships before the launch post goes live, update to "first to integrate" rather than "only platform with." + +Monitor: LangGraph, CrewAI, AutoGen GitHub repos for Artifacts or CF Workers integration commits. + +--- + +## Collateral Status + +| Asset | Owner | Status | +|-------|-------|--------| +| Blog post | Content Marketer | Shipped (2026-04-21) | +| Social launch thread | Social Media Brand | Blocked on brief (this doc) | +| DevRel demo | DevRel Engineer | Unknown | +| Docs page | DevRel | Shipped (`docs/guides/cloudflare-artifacts`) | +| Battlecard entry | PMM | Add to Phase 34 battlecard | + +--- + +## Recommended Social Angle (for Social Media Brand) + +Thread opener: "Your AI agent just deleted three hours of work. Here's why that doesn't have to happen again." + +Lead with the pain story. The technology is the answer, not the hook. Close with the CTA to the blog post. + +--- + +## Update Triggers + +- Cloudflare Artifacts GA announced → update from "beta" to "GA" framing +- Any competitor ships Cloudflare Artifacts integration → update competitive claim to "first to integrate" +- PR or issue filed about Artifacts user experience → update objections section + +--- + +*PMM draft 2026-04-23 — ready for Social Media Brand* diff --git a/docs/marketing/briefs/mcp-server-adaptor-positioning.md b/docs/marketing/briefs/mcp-server-adaptor-positioning.md new file mode 100644 index 000000000..5410b01b7 --- /dev/null +++ b/docs/marketing/briefs/mcp-server-adaptor-positioning.md @@ -0,0 +1,88 @@ +# MCPServerAdaptor — Positioning Brief +**Source:** PR #1904 (merged 2026-04-24) | **Closes:** issue #847 +**Owner:** PMM | **Status:** DRAFT — for review +**Marketing issues:** #1968 (positioning), #1966 (blog), #1967 (social), #1965 (devrel) + +--- + +## What MCPServerAdaptor Does + +`MCPServerAdaptor` in `workspace/plugins_registry/builtins.py` is a plugin adaptor that lets any MCP server be installed as a first-class Molecule AI plugin — no custom adapter code required. + +**At install time:** +1. Reads `settings-fragment.json` from the plugin (contains `mcpServers` block in Claude Code's standard `claude_desktop_config` format) +2. Merges the `mcpServers` entries into `/.claude/settings.json` +3. Installs skills/rules/setup.sh if present + +**At uninstall time:** +- Removes skills, rules, setup.sh +- Leaves `mcpServers` entries in `settings.json` (by design — shared with other tools) + +**The pain it solves:** Four plugin proposals were each independently writing the same boilerplate to wrap an MCP server. MCPServerAdaptor standardizes the pattern — one base class, zero custom code. + +--- + +## Answers to PMM Questions (GH #1968) + +### 1. Positioning: "Universal MCP plugin runtime" vs. stronger competitive angle? + +**Recommended frame:** "Any MCP server is now a Molecule AI plugin." + +The "universal runtime" frame is accurate but abstract. Lead with the concrete benefit: plugin authors no longer need to write custom adapter boilerplate. Molecule AI standardizes the MCP plugin pattern. + +**Competitive angle (stronger):** LangGraph Cloud and CrewAI have no equivalent first-class MCP plugin infrastructure. Both require custom code or manual setup. Molecule AI is the only agent platform where "install an MCP server as a plugin" has a standard, codified pattern with auto-injection. + +### 2. Ecosystem story vs. infrastructure announcement? + +**Recommendation: Ecosystem launch, not just infrastructure.** + +Four plugins were blocked waiting for this: molecule-firecrawl (#512), molecule-github-mcp (#520), molecule-browser-use (#553), mcp-connector (#573). These are all high-demand, developer-facing plugins. Launching all four simultaneously, named alongside MCPServerAdaptor, tells a coherent story: "the plugin ecosystem just opened up." + +Treat this as a platform moment, not an internal engineering note. + +### 3. Target persona? + +**Primary:** Plugin developers building on Molecule AI +**Secondary:** Companies with existing MCP server investments who want to wrap them for agent use +**Pull-through:** Platform engineers evaluating Molecule AI for enterprise deployment + +Plugin developers are the right primary — they have immediate, concrete use cases. Enterprise buyers get the story as a secondary benefit. + +### 4. Phase alignment? + +**Does NOT belong in Phase 34 messaging.** + +Phase 34 is about Tool Trace + Platform Instructions + Partner API Keys GA (April 30). MCPServerAdaptor is an infrastructure unlock that shipped independently (merged Apr 24, issue #847). It should be its own release note / blog post / social thread, not a footnote in Phase 34 copy. + +--- + +## Recommended Messaging + +**Headline:** Any MCP server. Zero boilerplate. One JSON file. + +**Core claim:** MCPServerAdaptor standardizes the MCP plugin pattern on Molecule AI — four major plugins (firecrawl, github-mcp, browser-use, mcp-connector) shipped simultaneously because of it. + +**Code hook:** `settings-fragment.json` + `MCPServerAdaptor` subclass = installable plugin. Show the minimal config. + +**Differentiation:** LangGraph Cloud and CrewAI require custom boilerplate to wrap an MCP server. Molecule AI has a standard, codified pattern with auto-injection. + +**CTA:** Plugin SDK docs + GitHub issue list for planned plugins (#512, #520, #553, #573) + +--- + +## Release Cadence Recommendation + +| Date | Action | Owner | +|------|--------|-------| +| 2026-04-24 (today) | PMM positioning brief (this doc) | PMM | +| 2026-04-24 | Content Marketer drafts blog post | Content Marketer | +| 2026-04-24 | DevRel builds code demo (firecrawl-mcp or github-mcp-server) | DevRel Engineer | +| 2026-04-24–25 | Marketing Lead approves blog + demo | Marketing Lead | +| 2026-04-25 | Publish blog + social thread | Social Media Brand | +| 2026-04-25 | DevRel amplifies with code demo | DevRel Engineer | + +**Launch window:** 2026-04-25 (Friday) — ahead of Phase 34 GA on Apr 30. Gives the four newly-unblocked plugins a clear narrative anchor. + +--- + +*PMM drafted 2026-04-24 — responding to GH #1968 positioning questions.* diff --git a/docs/marketing/briefs/partner-api-keys-rate-limits-note.md b/docs/marketing/briefs/partner-api-keys-rate-limits-note.md new file mode 100644 index 000000000..79ee3fa50 --- /dev/null +++ b/docs/marketing/briefs/partner-api-keys-rate-limits-note.md @@ -0,0 +1,47 @@ +# Partner API Keys — Rate Limits Note +**Date:** 2026-04-23 | **Owner:** PMM | **Source:** Code review +**File:** `docs/marketing/briefs/partner-api-keys-rate-limits-note.md` + +--- + +## Rate Limit + +**Default rate limit: 60 requests per minute per Partner API Key.** + +This is the default configured in `docs/architecture/partner-api-keys.md` (line 219): + +> "Partner keys have per-key rate limits (default: 60 req/min, configurable)." + +The rate limiter is a separate middleware from the session-based rate limiter, so partner traffic does not compete with browser user rate limits. Each partner key has its own independent bucket. + +**Source:** `docs/architecture/partner-api-keys.md` (architecture design doc) +**Go implementation reference:** `workspace-server/internal/middleware/ratelimit.go` — generic token bucket rate limiter (used for PartnerKeys with configurable rate + interval per key instance) + +--- + +## Rate Limit Behavior + +- **Per-key, not per-org** — Each `mol_pk_*` key has its own rate limit counter. One key going over limit does not affect other partner keys. +- **Separate from session rate limiter** — Partner API Key traffic uses a separate rate limit bucket from organic browser/session traffic. +- **Configurable** — The rate limit is set per key at creation time (the `rate_limit` field in the key creation payload). Default is 60 req/min if not specified. +- **429 response on exceed:** `{"error": "rate limit exceeded", "retry_after": }` +- **Rate limit headers:** `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` on all responses. + +--- + +## Known Gaps + +- **Go implementation not found** — The rate limiter middleware (`ratelimit.go`) is a generic token bucket. The partner-specific rate limit enforcement (keying on `partner.ID`) was not found in a concrete handler file — the architecture doc describes the pattern but no `partner_key_ratelimit.go` or equivalent was found in `workspace-server/internal/`. PM should confirm the actual Go implementation before citing specific endpoint behavior. +- **Rate limit ceiling not documented** — Maximum configurable rate per key not found. PM must confirm if there is a platform-level cap. + +--- + +## Implication for DevRel Demo + +The `[RATE LIMIT TBD]` placeholder in `docs/devrel/phase-34-partner-api-keys-demo.md` can be filled with: **60 req/min per key (default, configurable)** — sourced from architecture doc. + +Update the demo script: after PM confirms Go implementation, update this note with the specific file + line number. + +--- + +*Source: `docs/architecture/partner-api-keys.md` lines 217–232. PM confirmation needed on Go implementation file + line number before citing in externally published copy.* diff --git a/docs/marketing/briefs/phase34-messaging-matrix.md b/docs/marketing/briefs/phase34-messaging-matrix.md new file mode 100644 index 000000000..4b13d1ffa --- /dev/null +++ b/docs/marketing/briefs/phase34-messaging-matrix.md @@ -0,0 +1,100 @@ +# Phase 34 — Taglines + Messaging Matrix +**Feature group:** Partner API Keys, Tool Trace, Platform Instructions, SaaS Federation v2 +**GA date:** April 30, 2026 +**Owner:** PMM | **Status:** INTERNAL DRAFT +**Last updated:** 2026-04-23 + +--- + +## 3 Candidate Taglines + +### Tagline A — Production-grade (emphasizes enterprise reliability) +> **"Production-grade AI agents. Nothing to bolt on."** + +**Use for:** Press releases, homepage hero, paid placements, enterprise sales decks. +**Why it works:** Directly addresses the enterprise buyer's #1 objection — "this is great for prototypes but can I run it in production?" — without overclaiming features. "Nothing to bolt on" is a dig at competitors (LangGraph, CrewAI) that require Langfuse, Helicone, or custom observability pipelines. + +--- + +### Tagline B — Observability/visibility (emphasizes transparency) +> **"See exactly what your AI agents did. Every tool. Every call. Every time."** + +**Use for:** DevOps-focused channels, technical blog intros, SOC 2 / compliance audience, tool trace launch announcement. +**Why it works:** Speaks directly to the platform engineering persona — the person who gets paged at 2am when something breaks. "Every tool. Every call. Every time." is specific and falsifiable, which builds credibility with technical audiences. It names the feature (Tool Trace) without making it a product name. + +--- + +### Tagline C — Aspirational (emphasizes enterprise enablement) +> **"Your AI fleet. Your rules. Your cloud."** + +**Use for:** LinkedIn, enterprise social, brand campaigns, vision statements. +**Why it works:** Three short declarative sentences that speak to three distinct buyer anxieties: managing at scale ("fleet"), controlling behavior ("rules"), and infrastructure autonomy ("your cloud"). Works for Platform Instructions, Partner API Keys, and SaaS Federation v2 simultaneously — it's a Phase 34 group tagline, not a single-feature tagline. + +--- + +## Messaging Matrix — 4 Features + +--- + +### Feature 1: Partner API Keys (`mol_pk_*`) + +| | | +|--|--| +| **Pain it solves** | Partner platforms, CI/CD pipelines, and marketplace resellers cannot programmatically provision or manage Molecule AI orgs — they must use browser sessions or build custom integrations from scratch. This makes Molecule AI unembeddable for any platform that wants to offer agent orchestration as a feature. | +| **Who cares** | Platform integrations engineers, DevRel leads building partner ecosystems, CI/CD DevOps teams, marketplace listing owners (AWS/GCP Marketplace) | +| **One-liner** | Programmatic org provisioning via API — no browser required, no manual handoff. | +| **Proof point** | `POST /cp/admin/partner-keys` creates a fully configured org with one API call. Keys are scoped to the org they create, rate-limited, revocable with `DELETE /cp/admin/partner-keys/:id`. Ephemeral CI test orgs: `POST` → run tests → `DELETE` → clean billing. | +| **HN/Reddit framing** | Lead with the developer experience: "Molecule AI now lets platform builders provision orgs via API." GA April 30 — use "generally available" or "shipping today." Do not mention any design partner name. | +| **What to soft-pedal** | Specific partner tiers and pricing (PM not confirmed). Marketplace billing integration status (PM to confirm). Do not mention "Acme Corp" in published copy. | + +--- + +### Feature 2: Tool Trace + +| | | +|--|--| +| **Pain it solves** | When an agent breaks in production, teams have no structured record of what it did — only the final output. Reverse-engineering from outputs is slow, error-prone, and impossible to automate. Third-party observability tools (Langfuse, Helicone, Datadog) miss A2A-level agent behavior and require SDK instrumentation. | +| **Who cares** | Platform engineers, DevOps leads, SREs, enterprise IT debugging production incidents | +| **One-liner** | Built-in execution tracing for every A2A task — no SDK, no sidecar, no sampling. | +| **Proof point** | `tool_trace[]` in every `Message.metadata` — array of `{tool, input, output_preview, run_id}` entries. Entries written to `activity_logs.tool_trace` as JSONB. run_id pairs concurrent calls so parallel traces don't merge. Platform-native: ships with the A2A response, no instrumentation required. | +| **HN/Reddit framing** | Lead with the developer experience: "Tool Trace ships today in Molecule AI. Every agent turn now includes a structured record of every tool called — inputs, output previews, run_id-paired for parallel calls." GA — "shipping today" or "generally available." | +| **What to soft-pedal** | Technical implementation details (run_id pairing schema, JSONB storage format). Overlap with Langfuse/Helicone — frame as complementary, not competitive. | + +--- + +### Feature 3: Platform Instructions + +| | | +|--|--| +| **Pain it solves** | Agent governance that only filters outputs after the agent has already acted is governance that failed. Enterprise IT and compliance teams need to shape agent behavior *before* the first token is generated — without requiring a code change or deployment. | +| **Who cares** | Enterprise IT, Security/Compliance leads, Platform Engineering, CISO office | +| **One-liner** | Enforce org-wide agent governance at the system prompt level — before the first turn, not after an incident. | +| **Proof point** | Platform Instructions prepends workspace-scoped rules to the system prompt at startup. Two scopes: global (every workspace in the org) and workspace-specific. Rules take effect before the first agent turn — not after. Policy update requires no code deploy, no agent restart, no application change. | +| **HN/Reddit framing** | Frame as "the missing governance layer for production agents." Avoid overclaiming compliance certifications. Do not compare directly to OPA/Sentinel — say "complements runtime policy engines" not "replaces them." | +| **What to soft-pedal** | Overlap with the existing audit trail panel (Issue #759) — they are complementary (Tool Trace feeds the audit trail). Don't let buyers think they have to choose. Specific policy examples until PM confirms which are GA-ready. | + +--- + +### Feature 4: SaaS Federation v2 + +| | | +|--|--| +| **Pain it solves** | Enterprises and marketplaces that need to offer agent orchestration to multiple end-customers (tenants) cannot do so safely with a single-tenant architecture: cross-tenant data isolation, centralized billing, org-level access control, and per-tenant audit trails are all required for enterprise procurement. | +| **Who cares** | Enterprise procurement, IT procurement teams, marketplace operators, SaaS resellers, multi-tenant ISVs | +| **One-liner** | Multi-tenant agent platform with cross-tenant isolation, centralized billing, and org-level governance — built for enterprises and marketplaces. | +| **Proof point** | SaaS Federation v2 tutorial at `docs/tutorials/saas-federation` (PR #1613). Org-scoped keys + control plane boundary. Isolated per-tenant workspaces with centralized admin view. | +| **HN/Reddit framing** | ⚠️ **WARNING:** SaaS Federation v2 is listed in Issue #1836 as a Phase 34 feature, but no PMM positioning brief or blog post exists for it yet. Do NOT draft community copy for this feature until PM confirms: (a) what it actually ships, (b) the GA/beta/alpha label, and (c) the primary use case narrative. Current content gap — not ready for external copy. | +| **What to soft-pedal** | Until PM confirms details, do not publish any claims about SaaS Federation v2. | + +--- + +## Feature Cross-Sell Angles + +**Phase 30 → Phase 34 linkage (for sellers):** +> "Phase 30 shipped per-workspace auth tokens (`mol_ws_*`). Phase 34 ships partner-level keys (`mol_pk_*`). Together, Molecule AI is the only platform with workspace-level isolation *and* partner-level scoping — enterprise-ready from day one." + +**Governance stack (Platform Instructions + Tool Trace):** +> "Platform Instructions shapes what agents do *before* they run. Tool Trace records what they did *after*. Together: governance before, observability after. Nothing leaves production unaccounted for." + +**Partner platform stack (Partner API Keys + SaaS Federation v2 + Platform Instructions):** +> "Provision tenants via API. Isolate them in a multi-tenant control plane. Govern their behavior at the system prompt level. Revoke access in one call. That's a complete partner platform — not a collection of features." diff --git a/docs/marketing/briefs/phase34-positioning.md b/docs/marketing/briefs/phase34-positioning.md new file mode 100644 index 000000000..abf196b9d --- /dev/null +++ b/docs/marketing/briefs/phase34-positioning.md @@ -0,0 +1,89 @@ +# Phase 34 — Positioning One-Pager +**Feature group:** Partner API Keys, Tool Trace, Platform Instructions, SaaS Federation v2 +**GA date:** April 30, 2026 +**Status:** INTERNAL DRAFT — for PMM review and press kit use +**Owner:** PMM +**Last updated:** 2026-04-23 + +--- + +## One-Sentence Positioning Statement + +Molecule AI Phase 34 gives enterprise teams the platform-native primitives — programmable access, built-in observability, and pre-execution governance — required to run AI agents in production, without the bolt-on integrations that add latency, maintenance burden, and security gaps. + +--- + +## Target Audience + +| | Role | What they care about | +|--|------|----------------------| +| **Primary** | Platform Engineering / DevOps leads | Shipping reliable agent infrastructure: observability, CI/CD integration, multi-environment support | +| **Primary** | Enterprise IT / Security Governance | Controlling agent behavior before it happens: policy enforcement, audit trails, compliance | +| **Secondary** | Partner / Marketplace integrations engineers | Embedding Molecule AI as the orchestration layer for their platform or marketplace | +| **Secondary** | Developer advocates / DevRel | Demonstrating enterprise-grade capabilities to prospective enterprise buyers | + +--- + +## Problem We Solve + +Enterprise teams adopting AI agents face three compounding failures at once: + +1. **Observability gaps** — Agents run and produce outputs, but teams have no structured record of *what the agent actually did*: which tools it called, with what inputs, in what order. Debugging is reverse-engineering from outputs. Cross-platform observability (Langfuse, Datadog) adds a pipeline but misses A2A-level agent behavior. + +2. **Governance gaps** — Agent behavior policies are enforced *after* the agent has already acted — filtering outputs, blocking writes post-hoc. Governance that only works after the fact is governance that failed. Enterprise IT and compliance teams need controls that shape behavior *before* the first token is generated. + +3. **Integration gaps** — Platforms that want to embed agent orchestration programmatically face a choice between building it themselves (months of work) or using browser sessions (brittle, non-programmatic). CI/CD teams need ephemeral test orgs per PR. Neither is solved by existing agent platforms. + +--- + +## Our Solution — Phase 34 Angle + +Phase 34 ships four features that address each failure at the platform layer — not as integrations, not as SDKs, not as post-hoc configuration: + +- **Partner API Keys** (`mol_pk_*`) — Scoped, revocable API tokens that let partner platforms, CI/CD pipelines, and marketplace resellers programmatically provision and manage Molecule AI orgs. No browser. No manual handoff. +- **Tool Trace** — `tool_trace[]` in every A2A `Message.metadata`. A structured, run_id-paired execution record: tool name, inputs, output previews, timing. No SDK, no sidecar, no sampling. +- **Platform Instructions** — Workspace-scoped system prompt rules that take effect at startup. Governance happens before the first turn, not after an incident. +- **SaaS Federation v2** — Multi-tenant control plane architecture: isolated orgs, cross-tenant guardrails, centralized billing for enterprise and marketplace deployments. + +**The Phase 34 angle:** These four features work together. A partner platform provisions an org via Partner API Keys, configures Platform Instructions for their tenants, gets full observability via Tool Trace, and operates it all inside a SaaS Federation v2 multi-tenant control plane. This is a coherent enterprise stack — not four unrelated features. + +--- + +## Key Differentiators vs. Competitors + +| Differentiator | LangGraph Cloud | CrewAI | Molecule AI Phase 34 | +|---------------|----------------|--------|----------------------| +| Built-in agent observability (no SDK) | ❌ | ❌ | **✅ Tool Trace** | +| Pre-execution governance (system prompt level) | ❌ | ❌ | **✅ Platform Instructions** | +| Programmatic partner org provisioning | ❌ (seat licensing only) | ❌ (marketplace listing only) | **✅ Partner API Keys** | +| CI/CD-native ephemeral orgs | ❌ | ❌ | **✅ Partner API Keys + CI/CD example** | +| Multi-tenant SaaS control plane | ❌ | ❌ | **✅ SaaS Federation v2** | +| A2A-native protocol | ✅ (in-progress, Q2-Q3 2026) | ❌ | **✅ live today** | + +**Counter-framing for sellers:** +> "LangGraph Cloud and CrewAI are end-user platforms. Molecule AI is infrastructure your platform builds on — with the governance and observability built in, not bolted on." + +--- + +## Proof Points + +| Claim | Evidence | +|-------|----------| +| Molecule AI is the only agent platform with built-in execution tracing | `tool_trace[]` in `Message.metadata` — no SDK, no sidecar. LangGraph and CrewAI require Langfuse/Helicone instrumentation. | +| Platform Instructions enforce governance before agents run | Workspace startup path prepends rules to system prompt. Policy takes effect before first token generated. | +| Partner API Keys enable programmatic org provisioning | `POST /cp/admin/partner-keys` creates orgs via API. Keys are SHA-256 hashed, org-scoped, rate-limited, revocable via `DELETE`. | +| Ephemeral test orgs per PR are fully automated | CI/CD example in partner onboarding guide: `POST` create → run tests → `DELETE` teardown. No manual cleanup, no shared-state contamination. | +| SaaS Federation v2 enables multi-tenant isolation | Tutorial at `docs/marketing/launches/pr-1613-saas-federation-v2.md`. Org-scoped keys + control plane boundary. | +| Design partner (Acme Corp) validates enterprise readiness | Acme Corp integration (design partner, name pending PM confirmation). Reference use case: partner-provisioned orgs for Acme's customer base. | + +--- + +## Internal Use Notes + +> **2026-04-23 override:** Internal notes previously flagged all Phase 34 features as BETA. Community FAQ (`phase-34-community-faq.md`, Community Manager-owned, approved) and approved social copy are the authoritative external-facing sources. Updated to reconcile: +> - **Partner API Keys:** GA April 30, 2026 — "generally available" language is correct per community FAQ table and approved social copy. +> - **Tool Trace:** GA — community FAQ uses no Beta designation. All plans. +> - **Platform Instructions:** GA — Enterprise plans only. Confirmed via code review: AdminAuth-gated at router.go:376. Community FAQ updated accordingly. Enterprise IT is primary ICP — plan gate is consistent with buyer audience, not a hidden limitation. +> - **SaaS Federation v2:** REMOVED from community announcement and social copy pending PM confirmation. Do not reference in external materials. +> - Do not use "Acme Corp" in any externally published copy — placeholder only. Confirm partner name with PM before press release. +> - Phase 30 linkage: Phase 30 shipped `mol_ws_*` (per-workspace auth). Phase 34 extends to `mol_pk_*` (partner-level keys). Cross-sell: "Phase 30 workspace isolation + Phase 34 partner scoping — the only platform with both." diff --git a/docs/marketing/briefs/platform-instructions-plan-gating-note.md b/docs/marketing/briefs/platform-instructions-plan-gating-note.md new file mode 100644 index 000000000..ac2fcec39 --- /dev/null +++ b/docs/marketing/briefs/platform-instructions-plan-gating-note.md @@ -0,0 +1,22 @@ +# Platform Instructions — Plan Gating Note +**Date:** 2026-04-23 +**Source:** Code review + staged blog post +**Status:** CONFIRMED — Enterprise-only + +--- + +**Platform Instructions is gated to Enterprise plans.** + +Code basis: All CRUD endpoints (`POST/PUT/DELETE/GET /instructions`) live under `adminInstr` — a router group protected by `AdminAuth` middleware. `AdminAuth` requires org-level admin credentials (WorkOS session or org API key). This means only org admins can create or modify Platform Instructions rules. + +The `/instructions/resolve` endpoint (used by workspace agents at startup) uses `wsAuth` — workspace-level authentication. Workspaces can retrieve their own resolved instructions, but the CRUD API that creates/modifies rules requires org admin access. + +The staged blog post (`docs/blog/2026-04-23-platform-instructions-governance/index.md` on `marketing/phase-34-launch-prep`, line 94) states explicitly: "Platform Instructions are available on **Enterprise plans**." + +There is no feature flag or plan-tier check in the handler code — the gating is enforced by `AdminAuth` middleware on the CRUD routes. This means the restriction is architectural, not a config flag that could be flipped. + +**Implication for social copy:** Posts 4 and 5 in the Phase 34 GA social thread ("Platform Instructions: Enterprise plans") are correct. Do not remove the plan qualifier. + +--- + +*Source: `workspace-server/internal/router/router.go:376` (AdminAuth on CRUD routes), `workspace-server/internal/handlers/instructions.go` (no plan/tier/enitle/enterprise references — gating is purely middleware-enforced). Staged blog post line 94.* \ No newline at end of file diff --git a/docs/marketing/briefs/platform-instructions-pmm-positioning.md b/docs/marketing/briefs/platform-instructions-pmm-positioning.md new file mode 100644 index 000000000..924c59891 --- /dev/null +++ b/docs/marketing/briefs/platform-instructions-pmm-positioning.md @@ -0,0 +1,63 @@ +# PMM Positioning Brief: Platform Instructions + +**Date:** 2026-04-23 +**Owner:** PMM +**Status:** APPROVED — ready for Social Media Brand and Content Marketer use +**Phase:** 34 + +--- + +## Core Positioning + +**One-liner:** The only agent platform where governance is enforced before the first token is generated — not after. + +**Longer form:** Platform Instructions lets enterprise IT and platform teams enforce org-wide policy rules at the system prompt level. Rules are prepended to the agent's system prompt automatically at workspace startup. No SDK changes. No code deploys. No agent-side integration work. + +--- + +## Key Differentiation + +Most AI governance tools work by **filtering outputs** after the agent has already decided what to do. That's governance as audit — useful for compliance reports, too late to prevent harm. + +Platform Instructions enforces governance **at the source**: before the first token is generated. The agent is instructed what to do — and what not to do — from its very first turn. That's governance as architecture. + +**Competitor gap:** No other A2A-native agent platform surfaces a governance control that takes effect before the agent can act. Cloud providers (AWS Agentic, GCP Vertex AI) offer post-hoc logging and blocking, but not pre-prompt injection. + +--- + +## Target Audience + +- **Primary:** Enterprise platform engineers and DevOps teams responsible for AI deployment governance +- **Secondary:** Security/compliance teams requiring audit-ready control surfaces before approving production agents + +--- + +## 3 Core Claims (for social copy) + +1. **"Before the first turn, not after"** — Platform Instructions governance is architectural, not advisory. Rules are prepended to the system prompt at startup. The agent can't act outside those rules because it was never instructed to. + +2. **"Global and workspace-scoped, zero SDK required"** — One rule applies to every workspace in the org. Another rule applies only to a specific workspace. Both enforced automatically at startup. No agent-side code changes. + +3. **"Enterprise-ready: IDOR-protected, DoS-hardened"** — The resolve endpoint is IDOR-protected under wsAuth. An 8KB content cap prevents token-budget DoS. `run_id`-scoped parallel tool call pairing ensures correct attribution under concurrent execution. + +--- + +## What NOT to Say + +- Do not frame Platform Instructions as "prompt engineering" — it's governance architecture, not content tuning +- Do not compare directly to AWS/GCP — they don't have this capability, so direct comparison amplifies their feature gap +- Do not imply the governance can be bypassed — the architecture prevents bypass at the source, not just reports it + +--- + +## CTA + +Enable Platform Instructions via the CRUD API → governance rules auto-inject into the system prompt at workspace startup → deploy your A2A agent with zero code changes. + +--- + +## Assets + +- Blog post: `docs/blog/2026-04-23-platform-instructions-governance/index.md` +- Launch brief (PR #1686): `docs/marketing/launches/pr-1686-tool-trace-platform-instructions.md` +- Phase 34 messaging matrix: `docs/marketing/phase34-messaging-matrix.md` diff --git a/docs/marketing/briefs/pre-launch-blog-qa-notes.md b/docs/marketing/briefs/pre-launch-blog-qa-notes.md new file mode 100644 index 000000000..51198835a --- /dev/null +++ b/docs/marketing/briefs/pre-launch-blog-qa-notes.md @@ -0,0 +1,87 @@ +# Pre-Launch Blog QA Notes +**Owner:** PMM | **Date:** 2026-04-24 | **Status:** PARTIAL — two posts not yet on main/staging +**Owner:** PMM | **Date:** 2026-04-24 | **Status:** PARTIAL — two posts not yet on main/staging +**Purpose:** Flag accuracy issues vs. approved positioning briefs before content goes live. + +--- + +## ✅ Blog 3 of 3 — A2A Enterprise Deep-Dive +**File:** `docs/blog/2026-04-22-a2a-v1-agent-platform/index.md` +**Brief:** `docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md` +**Status: CLEAN** (one ⚠️ advisory, no blockers) + +### Accuracy checks + +| Claim area | Brief says | Blog says | Verdict | +|---|---|---|---| +| Auth enforcement point | "per-workspace bearer tokens enforced at every authenticated route" | "org-scoped API keys... audited at the org level" + "per-workspace bearer tokens" | ✅ Correct | +| Auth architecture | Protocol-level enforcement (NOT "discovery-time CanCommunicate()") | Auth correctly described as per-workspace enforced at authenticated routes | ✅ Correct | +| LangGraph A2A support | "LangGraph A2A PR #6645 [WIP]" | "LangGraph A2A PR #6645 (WIP) plus #7113 and #7205" | ⚠️ VERIFY — PRs #7113 and #7205 were NOT independently verified in this QA cycle. Blog correctly preserves ⚠️ flag. No blocking issue — flag is self-documenting. | +| VPN guardrail | "no VPN required for control plane" | Correctly implied throughout (no VPN language) | ✅ Correct | +| Org-scoped API keys + audit trail | Both mentioned together | Both mentioned | ✅ Correct | + +**PMM verdict:** Blog 3 is clean to publish. The LangGraph PR ⚠️ flag is appropriate self-documentation. + +--- + +## 🔴 Blog 1 of 3 — EC2 Instance Connect SSH ⚠️ FILE NOT ON MAIN OR STAGING +**Expected file:** `docs/marketing/blog/2026-04-23-ec2-instance-connect-ssh.md` +**Expected on:** `origin/staging` (commit `0d3ad96` per social queue) +**Actual:** File NOT FOUND on main or staging under either path attempted. +**Brief:** `docs/marketing/launches/pr-1533-ec2-instance-connect-ssh.md` + +### Blocking issues + +**Cannot QA — file does not exist yet.** +Social queue notes file should live on staging under `docs/marketing/blog/2026-04-23-ec2-instance-connect-ssh.md` (commit `0d3ad96`) but `git show origin/staging:docs/marketing/blog/2026-04-23-ec2-instance-connect-ssh.md` returned NOT FOUND. The blog post may not have been committed, or may be in a different directory. + +### Key claims to verify once file is available + +| Watch item | Brief approved claim | Risk if not verified | +|---|---|---| +| Connection timing | "< 3 seconds" | Overclaiming ("instant"/"real-time") would be inaccurate | +| Public IP requirement | "no public IP" | EICE requires private subnet access — must not imply all EC2 instances qualify | +| IAM auth vs SSH keys | EICE uses IAM-based auth — no SSH key management | Must not claim "no keys stored on instance" without the EICE context | +| Bastion host framing | Alternatives to bastion hosts | Must not贬低 AWS-native EICE vs. generic bastion elimination | + +**PMM action:** Flag to Marketing Lead and Content Marketer — blog post not on staging, QA blocked. Request Content Marketer commit the file or confirm its location. + +--- + +## 🔴 Blog 2 of 3 — MCP Server List ⚠️ FILE NOT ON MAIN OR STAGING +**Expected file:** `docs/marketing/blog/2026-04-23-mcp-server-list.md` +**Expected on:** `origin/staging` (per social queue commit `0d3ad96`) +**Actual:** File NOT FOUND on main or staging. +**Brief:** `docs/marketing/seo/mcp-server-list-explainer-seo-brief.md` + +### Blocking issues + +**Cannot QA — file does not exist yet.** +`git ls-tree -r origin/staging --name-only | grep -i mcp-server` returned zero blog-post matches. Only `docs/guides/mcp-server-setup.md` and `docs/marketing/seo/mcp-server-list-explainer-seo-brief.md` (the brief itself) exist on staging. + +### Key claims to verify once file is available + +| Watch item | Brief approved claim | Risk if not verified | +|---|---|---| +| MCP server names | Chrome DevTools MCP, Playwright MCP, Cloudflare Artifacts, EC2 Instance Connect, WriteFile, ReadFile, Glob, Grep, Slack, Discord adapters | Omitting or misnaming a server category is an accuracy error | +| Governance claims | Org-scoped API keys + Platform Instructions (Enterprise plans) | Platform Instructions confirmed Enterprise plans only (AdminAuth-gated, router.go:376). Blog post correct; community FAQ corrected 2026-04-24. | +| Platform Instructions plan gate | Enterprise-only feature | ✅ CONFIRMED 2026-04-24: Enterprise plans only per code review + plan-gating note. Blog post correct; community FAQ corrected. | +| Blog title/URL alignment | Brief targets `mcp-server-list-explainer` keyword | Title should match SEO intent | + +**PMM action:** Flag to Marketing Lead and Content Marketer — blog post not on staging, QA blocked. Request Content Marketer commit the file. + +--- + +## Summary + +| Blog | Status | Blocking? | Action owner | +|---|---|---|---| +| A2A Enterprise Deep-Dive | ✅ Clean (LangGraph ⚠️ flag self-documenting) | No | Ready for publish | +| EC2 Instance Connect SSH | 🔴 File not on staging | Yes — cannot QA | Content Marketer | +| MCP Server List | 🔴 File not on staging | Yes — cannot QA | Content Marketer | + +**Recommendation:** Marketing Lead should route blockers to Content Marketer. Once both files are on staging, PMM can complete QA within one working day. + +--- + +*PMM QA notes 2026-04-24. A2A blog reviewed. Platform Instructions plan availability resolved (Enterprise plans only). EC2 + MCP blog posts: blocked on Content Marketer delivery.* diff --git a/docs/marketing/briefs/saas-fed-v2-what-shipped.md b/docs/marketing/briefs/saas-fed-v2-what-shipped.md new file mode 100644 index 000000000..b8a688a7d --- /dev/null +++ b/docs/marketing/briefs/saas-fed-v2-what-shipped.md @@ -0,0 +1,54 @@ +# SaaS Federation v2 — What Shipped Note +**Date:** 2026-04-23 | **Owner:** PMM +**Source:** Codebase search + docs search | **Status:** INVESTIGATION INCOMPLETE + +--- + +## Summary + +**No implementation evidence found for "SaaS Federation v2" as a named feature.** + +The term "SaaS Federation v2" appears in marketing materials (Phase 34 messaging matrix, Phase 32 battlecard, positioning briefs) but: +- No tutorial file exists at `docs/tutorials/saas-federation` — the messaging matrix explicitly says it should be at `docs/tutorials/saas-federation` (PR #1613 reference), and this file does not exist. +- No Go files in `workspace-server/` or `platform/` contain the string "federation" or "saas-fed." +- No launch doc exists at `docs/marketing/launches/pr-1613-saas-federation-v2.md`. +- The architecture docs (`docs/architecture/`) contain no mention of "federation." + +The feature does appear in marketing copy as a conceptual grouping of Phase 32 + Phase 34 capabilities: multi-tenant isolation, WorkOS SSO, Stripe billing, Fly Machines provisioning, and Partner API Keys. But there is no separate PR #1613 implementation that codifies "SaaS Federation v2" as a discrete unit of work. + +**PLAN.md note (2026-04-24):** Phase 34.1–34.4 checkboxes in PLAN.md (`/tmp/PLAN.md` lines 622–661) are all unchecked `[ ]`. Partner API Keys implementation may not be marked shipped in the engineering plan. Phase 33 in PLAN.md is "Tenant Subdomain Routing — MIGRATING TO CLOUDFLARE TUNNEL" — not federation. This reinforces that "SaaS Fed v2" is a marketing grouping, not an engineering phase. +--- + +## What "SaaS Federation v2" Refers To + +Based on the messaging matrix and Phase 34 positioning brief, the term appears to describe the commercial stack of: + +| Capability | Source Phase | Status | +|---|---|---| +| Multi-tenant org isolation (`org_id` filter) | Phase 30+ | Live | +| Per-workspace auth tokens (`mol_ws_*`) | Phase 30 | Live | +| WorkOS AuthKit (per-org SSO) | Phase 32 | Live | +| Fly Machines backend provisioning | Phase 30 | Live | +| Neon + Upstash managed backing services | Phase 32 | Live | +| Stripe billing integration | Phase 32 | ⚠️ Stripe Atlas pending | +| Cloudflare Tunnel migration | Phase 33 | MIGRATING (PLAN.md: "MIGRATING TO CLOUDFLARE TUNNEL") — this IS the Phase 33 engineering work, not federation | +| Partner API Keys (`mol_pk_*`) | Phase 34 | Live (Apr 23) | +| SaaS Federation v2 tutorial | PR #1613 | **DOES NOT EXIST** | + +The messaging matrix (2026-04-23) explicitly flags this: "Do NOT draft community copy for this feature until PM confirms: (a) what it actually ships, (b) the GA/beta/alpha label, and (c) the primary use case narrative." + +--- + +## Is a Battlecard Safe to Write? + +**No.** A battlecard requires a discrete feature with concrete capabilities. "SaaS Federation v2" as a named feature is not verified in the codebase. Writing a battlecard for it now would mean writing marketing copy with no implementation anchor — claims that could be invalidated the moment PM defines the feature scope. + +**Safe path forward:** +1. PM must confirm what PR #1613 actually shipped (or whether it was merged at all) +2. If no discrete feature, rename the battlecard to "Multi-Tenant Agent Platform" and anchor claims to Phase 30+ Phase 34 capability stack +3. The existing Phase 32 battlecard at `docs/marketing/battlecard/phase-32-saas-fed-v2-battlecard.md` is written against the conceptual stack, not a named PR — this is a risk + +--- + +*PMM investigation 2026-04-23 — no implementation evidence found for SaaS Federation v2 as a discrete feature.* +*Action: PM must confirm feature scope before external copy is written.* diff --git a/docs/marketing/competitors.md b/docs/marketing/competitors.md new file mode 100644 index 000000000..67d691655 --- /dev/null +++ b/docs/marketing/competitors.md @@ -0,0 +1,158 @@ +# Competitive Intelligence — Molecule AI +**Last generated:** 2026-04-23 (from ecosystem-watch.md snapshot, updated 2026-04-22) +**Maintenance:** PMM cron diffs `ecosystem-watch.md` competitor-snapshot block and updates this file when `notable_changes` change. +**Source:** Molecule-AI/internal `ecosystem-watch.md` + +--- + +## Snapshot Overview + +| Competitor | Threat | Stars | Version | Last Shipped | +|---|---|---|---|---| +| Paperclip | Medium | 54.8k | v2026.416.0 | Apr 16 | +| OpenAI Agents SDK | High | 14k | v0.14.1 | Apr 15 | +| OpenAI Codex Agent | High | N/A | Apr 17 launch | Apr 17 | +| CrewAI | High | 48k | 1.14.3a2 | Apr 21 | +| Google ADK | High | 19k | v2.0.0b1 | Apr 22 | +| Google Vertex AI Agent Builder | High | N/A | GA (built-in) | Apr 22 | +| Microsoft Agent Framework | High | 9.5k | python-1.1.0 | Apr 21 | +| LangGraph | Medium | 29k | v1.1.9 | Apr 21 | +| Dify | Medium | 60k | v1.13.3 | Apr 22 | +| VoltAgent | Medium | 8.2k | @voltagent/server-hono@2.0.11 | Apr 22 | + +--- + +## HIGH THREAT + +### OpenAI Agents SDK — `openai/openai-agents-python` +**Threat:** High | **Stars:** 14k | **Version:** v0.14.1 + +**Notable changes (2026-04-22):** +v0.14.1 (Apr 15) patches tracing export on top of v0.14.0's SandboxAgent beta — persistent isolated workspaces, snapshot/resume, sandbox memory directly competing with workspace lifecycle model. No new release since Apr 15 (7 days). + +**Molecule AI gap:** SandboxAgent workspaces directly overlap our `workspace-template/` lifecycle. If OpenAI Codex agents become the default "agent build path," Molecule AI becomes a deployment option, not the platform. + +**Recommended action:** Monitor for v0.14.x stable release. Assess whether our Docker/ Fly Machine workspace backends compete on cold-start speed with SandboxAgent. + +--- + +### OpenAI Codex Agent — `openai/codex` +**Threat:** High | **Stars:** N/A | **Version:** Launched Apr 17 2026 + +**Notable changes (2026-04-22):** +Relaunched Apr 17 2026 (HN #2, 769 pts): full autonomous agent product — parallel subagent orchestration, cross-session project memory, autonomous self-wake scheduling, macOS computer control, inline image generation. Distinct threat surface from openai-agents-sdk; directly overlaps workspace lifecycle, agent_memories, workspace_schedules. + +**Molecule AI gap:** Cross-session memory + autonomous scheduling are our Phase 22 (cron) and Phase 9 (hierarchical memory). Codex ships them as a product. Molecule AI needs to ship them as features and own the developer-accessible version. + +**Recommended action:** DevRel should benchmark Codex memory vs. our `commit_memory` + `workspace_schedules` stack. Document the Molecule AI alternative as a developer-accessible, self-hosted path. + +--- + +### CrewAI — `crewAIInc/crewAI` +**Threat:** High | **Stars:** 48k | **Version:** 1.14.3a2 + +**Notable changes (2026-04-22):** +v1.14.2 (Apr 17) confirmed Crew Studio is real — node-and-edge drag-and-drop canvas. AMP Factory self-hosted: on-prem/VPC, K8s, FedRAMP High. A2A spec v0.3.0 first-class — zero-shim interop with Molecule AI confirmed. **LangGraph, AutoGen, CrewAI, Claude, OpenAI Agents as tool integrations via Composio** (MIT-adjacent, ~18k ⭐). + +**CrewAI observability:** Third-party integrations only — LangSmith, Weights & Biases, custom callbacks. Manual instrumentation required. No structured tool-call-level trace inside A2A response. + +**Molecule AI gap:** No governance-layer canvas. Team-role primitives are internal to a Crew, not org-scoped. Tool Trace + Platform Instructions fills the governance gap CrewAI doesn't have. + +**Recommended action:** Own "A2A-native governance" as the differentiator. CrewAI competes on canvas; we compete on platform. + +--- + +### Google ADK — `google/adk-python` +**Threat:** High | **Stars:** 19k | **Version:** v2.0.0b1 + +**Notable changes (2026-04-22):** +v2.0.0b1 (Apr 22 2026): FULL Workflow graph orchestration core — NodeRunner per-node execution isolation, DefaultNodeScheduler, graph-based execution engine GA. HITL resume via event reconstruction. Security fix: RCE vulnerability in nested YAML configs patched. Threat escalated: graph workflow + node isolation is direct overlap with our workspace delivery pipeline. + +**Molecule AI gap:** Phase 12 (DAG workflow orchestration) is the direct counter. Google ADK ships it; we don't have it yet. + +**Recommended action:** Prioritize Phase 12 DAG/workflow builder to directly counter Vertex AI Agent Builder's built-in flow builder. EC2 Instance Connect terminal is the differentiator against ADK — no ADK equivalent. + +--- + +### Google Vertex AI Agent Builder — `google-cloud-aiplatform/vertex-ai-samples` +**Threat:** High | **Stars:** N/A | **Version:** GA (built-in with Vertex AI enterprise seats) + +**Notable changes (2026-04-22):** +Built-in flow builder shipped with Vertex AI enterprise seats — zero incremental cost for GCP shops. Procurement objection, not a feature comparison. ADK v2.0.0b1 released same day — workflow graph + NodeRunner isolation. + +**Molecule AI gap:** Vertex AI Agent Builder is included with enterprise seats — no separate purchase required for GCP customers. The objection is "we already have this." Phase 30 remote workspaces + EC2 Instance Connect terminal are the structural differentiators: direct EC2 access vs. managed Vertex service. Phase 12 DAG/workflow builder is the product counter. + +**Critical note (per issue #1862):** Vertex AI Agent Builder is a **procurement objection, not a feature comparison**. Don't engage on features — reframe to: "Vertex AI Agent Builder is a managed service. Molecule AI is the agent runtime that runs on your infrastructure." The self-hosted + multi-backend story (Phase 30) is the answer. + +**Recommended action:** Add Vertex AI Agent Builder to competitive monitoring at critical tier. Ensure Phase 30 remote workspaces messaging explicitly addresses the GCP managed service vs. self-hosted cost difference. Prioritize Phase 12 DAG/workflow builder to close the product gap. + +--- + +### Microsoft Agent Framework — `microsoft/agent-framework` +**Threat:** High | **Stars:** 9.5k | **Version:** python-1.1.0 + +**Notable changes (2026-04-22):** +python-1.1.0 (Apr 21 2026): A2A metadata propagation across Message/Artifact/Task/event types. Foundry V2 hosted agents. AG-UI forwardedProps exposed to agents/tools via session metadata. GeminiChatClient added. FileCheckpointStorage BREAKING change (restricted pickle). AG-UI SSE endpoint gap remains. Process Framework GA still Q2 2026. + +**Molecule AI gap:** AG-UI is a real spec for agent-UI communication. If it gains adoption, our Canvas competes with it. Document our Canvas feature set vs. AG-UI as a differentiator. + +--- + +## MEDIUM THREAT + +### LangGraph — `langchain-ai/langgraph` +**Threat:** Medium | **Stars:** 29k | **Version:** v1.1.9 + +**Notable changes (2026-04-22):** +v1.1.9 (Apr 21 2026) patches core. v1.1.6 (Apr 10) ships LangGraph 2.0 declarative guardrail nodes. langgraph-cli v0.4.22 (Apr 16) adds deploy source tracking. LangGraph Cloud hosted execution competes with our scheduler. + +**LangGraph observability:** LangSmith integration — SDK-level instrumentation (`from langsmith import trace`), cross-platform multi-model traces. Requires active LangSmith account and separate vendor relationship. + +**Molecule AI differentiator:** Tool Trace is A2A-level agent behavior (tool call sequences, run_id pairing) — LangSmith tracks model-level tokens; Tool Trace tracks agent behavior. LangGraph Cloud competes with our scheduler; our governance layer (Platform Instructions + Tool Trace) is what they don't have. + +**LangGraph A2A status:** PRs #6645, #7113, #7205 (still in review as of Apr 22) — protocol layer only, no governance. PR #7205 adds DNS-AID agent discovery utilities. ⚠️ VERIFY: PRs #7113 and #7205 not independently confirmed OPEN this cycle — blog QA flagged same. + +--- + +### Paperclip — `paperclipai/paperclip` +**Threat:** Medium | **Stars:** 54.8k | **Version:** v2026.416.0 + +**Notable changes (2026-04-22):** +v2026.416.0 (Apr 16) ships execution policies (HiTL multi-stage reviewer/approver routing) + chat threads (assistant-ui per-issue inline). Threat level MEDIUM confirmed per 2026-04-20 deep-dive — no architectural change to concurrency model. + +**Molecule AI gap:** HITL routing is our Phase 8 (Human-in-the-Loop Approvals) and Paperclip HiTL (April 2026). Our differentiation: org-chart-based approval routing vs. per-task reviewer assignment. + +--- + +### Dify — `difyai/dify` +**Threat:** Medium | **Stars:** 60k | **Version:** v1.13.3 + +**Notable changes (2026-04-22):** +v1.13.3 (Apr 22 2026) — patch. A2A spec compliance, multi-tenant managed service. + +**Molecule AI gap:** Dify is self-hostable and has strong self-hosted adoption. Our self-hosted story needs to be clearer than "runs anywhere Docker runs." Phase 30 remote workspaces is the answer. + +--- + +### VoltAgent — `voltagent/voltagent` +**Threat:** Medium | **Stars:** 8.2k | **Version:** @voltagent/server-hono@2.0.11 + +**Notable changes (2026-04-22):** +@voltagent/server-hono@2.0.11 (Apr 22 2026) — hotfix. A2A agent card endpoints. + +**Molecule AI gap:** VoltAgent is an emerging player. Monitor for enterprise adoption. + +--- + +## Update Log + +| Date | Action | Trigger | +|---|---|---| +| 2026-04-23 | Created from ecosystem-watch.md snapshot | PMM cycle | +| 2026-04-23 | Added Google Vertex AI Agent Builder (critical tier) | Issue #1862 competitive brief | + +--- + +*Source: `ecosystem-watch.md` competitor-snapshot block (Molecule-AI/internal), updated 2026-04-22* +*Generated by: PMM cron* +*Next update: when ecosystem-watch.md `date` + `notable_changes` fields change, or Google Vertex AI Agent Builder pricing/feature update* \ No newline at end of file diff --git a/docs/marketing/devrel/talks/tool-trace-platform-instructions-talk-track-60s.mp3 b/docs/marketing/devrel/talks/tool-trace-platform-instructions-talk-track-60s.mp3 new file mode 100644 index 000000000..0aef10b2e Binary files /dev/null and b/docs/marketing/devrel/talks/tool-trace-platform-instructions-talk-track-60s.mp3 differ diff --git a/docs/marketing/launches/a2a-blog-staging-stranded.md b/docs/marketing/launches/a2a-blog-staging-stranded.md new file mode 100644 index 000000000..c555e2554 --- /dev/null +++ b/docs/marketing/launches/a2a-blog-staging-stranded.md @@ -0,0 +1,35 @@ +# A2A v1 Blog — Staging-Stranded +**Finding:** 2026-04-23 — Marketing Lead pulse +**Status:** STRANDED — write token dead, cannot merge to main + +## What is stranded +`docs/blog/2026-04-22-a2a-v1-agent-platform/index.md` on `origin/staging` +- A2A v1 deep-dive: ~1,370 words, technical +- LangGraph governance-gap ADR comparison (enterprise positioning) +- External agent registration Python code example +- Org-scoped API key delegation attribution +- Tied to social copy: `docs/marketing/campaigns/a2a-enterprise-deep-dive/social-copy.md` (also staging-only) + +## Why this matters +- Phase 30's most technically substantive content is not on main +- LangGraph A2A GA targeting Q2-Q3 — window to establish Molecule AI as canonical reference is NOW +- SEO: "A2A protocol" and "agent-to-agent protocol" keywords unclaimed +- 72h urgency noted in brief — window closes when LangGraph ships + +## What is needed +GitHub write token restored → create staging→main PR → merge + +## Local frontmatter additions (not yet on staging) +- `tags: [a2a, agent-protocol, multi-agent, governance, enterprise, platform]` +- `og_image: /assets/blog/2026-04-20-chrome-devtools-mcp-og.png` + +## Full staging-stranded blog audit (2026-04-23) + +| Blog | Staging path | Main status | Why it matters | +|---|---|---|---| +| A2A v1 Enterprise Deep-Dive | `2026-04-22-a2a-v1-agent-platform/` | ❌ NOT on main | LangGraph comparison, Phase 30 flagship | +| Org-scoped API keys (updated) | `2026-04-22-ai-agents-org-scoped-keys/` | ⚠️ Older version on main | PMM revision, Day 5 social copy references | +| Cloudflare Tunnel Migration (Phase 33) | `2026-04-22-cloudflare-tunnel-migration/` | ❌ NOT on main | Phase 33 launch, social copy written | +| Remote Workspaces (updated) | `2026-04-22-remote-workspaces/` | ⚠️ Older version on main | Phase 30 Day 4 social copy references | + +**All 4 require GitHub write token to merge to main.** diff --git a/docs/marketing/launches/partner-onboarding-guide.md b/docs/marketing/launches/partner-onboarding-guide.md new file mode 100644 index 000000000..2d4460064 --- /dev/null +++ b/docs/marketing/launches/partner-onboarding-guide.md @@ -0,0 +1,179 @@ +# Partner Onboarding Guide — First Pass +**Date:** 2026-04-23 | **Owner:** PMM | **Status:** DRAFT — tier names confirmed (blog post live), PM confirm Go implementation +**Scope:** Partner and Enterprise plans | Rate limit: 60 req/min per key (default, configurable — confirmed per architecture doc) + +--- + +## Overview + +Partner API Keys (`mol_pk_*`) let you provision and manage Molecule AI orgs programmatically — for CI/CD pipelines, marketplace integrations, or internal automation. This guide covers the end-to-end lifecycle: key creation, org provisioning, configuration, and teardown. + +**What you need before starting:** +- A Molecule AI admin account with access to `/cp/admin/partner-keys` +- `curl` or an HTTP client +- Understanding of which scopes your integration needs + +--- + +## 1. Prerequisites + +Before calling the Partner API, you need: + +| Requirement | How to get it | +|---|---| +| Admin token or org-scoped key | Created in Canvas → Org Settings → API Keys | +| Partner tier access | Partner and Enterprise plans — contact your account team or apply via moleculesai.app/partners | +| Scope assignment | Decide at key creation time which scopes to grant | +| Compliance review (optional) | Enterprise tier may require a security questionnaire | + +--- + +## 2. Creating Your First Partner Key + +Keys are created by an org admin. The full key is shown once — store it securely (secret manager, not a spreadsheet). + +```bash +# Create a partner API key +curl -X POST https://api.moleculesai.app/cp/admin/partner-keys \ + -H "Authorization: Bearer $ADMIN_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "acme-ci-pipeline", + "scopes": ["orgs:create", "orgs:list", "orgs:delete"], + "rate_limit": 60 + }' + +# Response — key shown ONCE +{ + "id": "pak_01HXKM4...", + "key": "mol_pk_live_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7", + "name": "acme-ci-pipeline", + "scopes": ["orgs:create", "orgs:list", "orgs:delete"], + "rate_limit": 60, + "created_at": "2026-04-23T08:00:00Z" +} +``` + +Save the `key` value immediately — it is not retrievable after this response. + +**Scope reference:** +- `orgs:create` — provision new orgs +- `orgs:list` — list your partner-managed orgs +- `orgs:delete` — deprovision orgs +- `workspaces:create` — create workspaces within an org +- `billing:read` — read subscription status + +--- + +## 3. Org Lifecycle + +### Create an org +```bash +ORG_RESPONSE=$(curl -X POST https://api.moleculesai.app/cp/orgs \ + -H "Authorization: Bearer mol_pk_live_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7" \ + -H "Content-Type: application/json" \ + -d '{"name": "customer-acme", "slug": "customer-acme", "plan": "standard"}') + +ORG_ID=$(echo $ORG_RESPONSE | jq -r '.id') +echo "Org ID: $ORG_ID" +``` + +### Poll provisioning status +```bash +# Poll until status is "active" +STATUS=$(curl -s https://api.moleculesai.app/cp/orgs/$ORG_ID/status \ + -H "Authorization: Bearer mol_pk_live_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7" \ + | jq -r '.status') + +echo "Status: $STATUS" +# → provisioning → active +``` + +### Redirect the tenant +``` +https://app.moleculesai.app/login?org=customer-acme +``` + +### Teardown +```bash +# Delete the org (irreversible) +curl -X DELETE https://api.moleculesai.app/cp/orgs/$ORG_ID \ + -H "Authorization: Bearer mol_pk_live_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7" +``` + +--- + +## 4. CI/CD Example — GitHub Actions + +This pattern spins up an isolated test org per PR, runs your integration tests, and tears it down. Each run gets a clean org — no shared state, no test pollution. + +```yaml +name: Molecule AI Integration Tests + +on: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Create ephemeral test org + id: create-org + run: | + RESPONSE=$(curl -s -X POST ${{ vars.MOLECULE_API_URL }}/cp/orgs \ + -H "Authorization: Bearer ${{ secrets.MOL_PARTNER_KEY }}" \ + -H "Content-Type: application/json" \ + -d "{\"name\":\"pr-${{ github.event.pull_request.number }}\",\"slug\":\"pr-${{ github.event.pull_request.number }}\"}") + ORG_ID=$(echo "$RESPONSE" | jq -r '.id') + echo "ORG_ID=$ORG_ID" >> $GITHUB_OUTPUT + echo "Created org: $ORG_ID" + + - name: Poll until ready + run: | + for i in $(seq 1 30); do + STATUS=$(curl -s ${{ vars.MOLECULE_API_URL }}/cp/orgs/${{ steps.create-org.outputs.ORG_ID }}/status \ + -H "Authorization: Bearer ${{ secrets.MOL_PARTNER_KEY }}" \ + | jq -r '.status') + [ "$STATUS" = "active" ] && break + sleep 2 + done + + - name: Run integration tests + run: | + # Use ${{ steps.create-org.outputs.ORG_ID }} in your test config + npm test -- --org-id=${{ steps.create-org.outputs.ORG_ID }} + + - name: Teardown test org + if: always() + run: | + curl -s -X DELETE ${{ vars.MOLECULE_API_URL }}/cp/orgs/${{ steps.create-org.outputs.ORG_ID }} \ + -H "Authorization: Bearer ${{ secrets.MOL_PARTNER_KEY }}" +``` + +**Security note:** Store `MOL_PARTNER_KEY` as a GitHub Actions secret — never hardcode it. Use a key scoped to `orgs:create` + `orgs:list` + `orgs:delete` only. + +--- + +## 5. Security Best Practices + +1. **One key per integration tier.** Create separate keys for CI/CD, marketplace, and internal automation. If one key is compromised, revoke it without affecting other integrations. + +2. **Create-then-revoke for rotation.** Keys cannot be updated — only created and deleted. To rotate: create new key → update integration → revoke old key. This produces a clean audit trail. + +3. **Monitor `last_used_at`.** Every call with a Partner API Key is logged with timestamp and caller identity. Check the audit log periodically for unexpected usage. + +4. **Scope to minimum required.** A CI pipeline needs `orgs:create` + `orgs:list` + `orgs:delete` — nothing more. Don't grant `billing:read` to a test integration. + +5. **Set expiration on non-production keys.** Keys used in test/CI environments can be issued with an `expires_at` timestamp. Expired keys return 401 with a clear message. + +--- + +## 6. Support + +- **Partner Discord:** `#partner-program` channel in the Molecule AI Community server — for integration questions, escalation, and partner announcements. +- **Email:** partner@molecule.ai — for enterprise partner inquiries. +- **Docs:** docs.molecule.ai/docs — API reference and architecture docs. + +--- + +*PMM draft 2026-04-23 — first pass. Tier names confirmed via blog post (2026-04-23). Still needs PM confirmation on Go implementation and billing endpoint availability before external distribution.* diff --git a/docs/marketing/launches/phase-34-community-announcement.md b/docs/marketing/launches/phase-34-community-announcement.md new file mode 100644 index 000000000..cd9266793 --- /dev/null +++ b/docs/marketing/launches/phase-34-community-announcement.md @@ -0,0 +1,78 @@ +# Phase 34 Community Announcement + +**Channel:** Discord `#announcements` + GitHub Discussions +**Date:** 2026-04-23 +**Author:** Marketing Lead (drafted on behalf of Community Manager) + +--- + +🚀 **Phase 34 shipped — and it's a big one.** + +This phase is all about giving platform builders the visibility, control, and provisioning primitives they've been asking for. Four features landed today: + +--- + +## What's new + +### 🔍 Tool Trace — see exactly what your agents did +Every A2A response now includes a `tool_trace` in `Message.metadata`. It's a list of every tool your agent called, with the input it sent and a preview of the output it got back: + +```json +"tool_trace": [ + { "tool_name": "web_search", "input": {"query": "molecule ai agent platform"}, "output_preview": "Molecule AI is a multi-agent..." }, + { "tool_name": "write_file", "input": {"path": "summary.md"}, "output_preview": "File written (412 bytes)" } +] +``` + +Parallel tool calls are handled — start/end events are paired via `run_id`, so concurrent calls don't get mixed up. Capped at 200 entries to prevent runaway loops from bloating your logs. + +The full trace is stored in `activity_logs.tool_trace` — queryable, auditable, and there when you need to debug why an agent did what it did. + +**Why it matters:** No more guessing. When something goes wrong in a multi-agent workflow, you now have the full tool call history to diagnose it. + +--- + +### ⚙️ Platform Instructions — system prompt for your whole org +Org admins can now configure system-level instructions that apply across every agent in the org: + +```http +PUT /cp/platform-instructions +{ "instructions": "Always respond in English. Tag every response with the agent workspace ID." } +``` + +Set it once, and every agent in your org inherits it — without touching individual workspace configs. Great for compliance requirements, house-style rules, or shared context that all your agents need. + +--- + +### 🔑 Partner API Keys (`mol_pk_*`) — GA April 30 +The partner provisioning API is entering GA on **April 30**. If you're building a platform on top of Molecule AI — a marketplace, a CI/CD integration, or a multi-tenant product — you can now programmatically create and manage Molecule AI orgs via API: + +```http +POST /cp/admin/partner-keys +DELETE /cp/admin/partner-keys/:id +``` + +Ephemeral test orgs per PR. Org-scoped keys that can't escape their boundary. Automated teardown that stops billing on `DELETE`. No browser session required. + +We believe this makes Molecule AI the first agent platform with a first-class partner provisioning API. If you're a platform builder and want early access ahead of April 30, drop a message in `#partner-program`. + +--- + +## Quick start + +- **Tool Trace**: no config needed — it's in every A2A response today. Check `message.metadata.tool_trace`. +- **Platform Instructions**: `PUT /cp/platform-instructions` with your org admin token. +- **Partner API Keys**: docs at `/docs/api/partner-keys` — GA April 30. + +--- + +## Try it & tell us what you think + +All three features are live now (Partner API Keys arriving April 30). Spin them up and let us know: + +- 🐛 Bugs or unexpected behavior → `#bug-reports` +- 💡 Feature requests → `#feedback` +- 🤝 Partner program interest → `#partner-program` +- ❓ Questions → reply here or open a GitHub Discussion + +We read everything. — The Molecule AI team diff --git a/docs/marketing/launches/phase-34-community-faq.md b/docs/marketing/launches/phase-34-community-faq.md new file mode 100644 index 000000000..da599deb5 --- /dev/null +++ b/docs/marketing/launches/phase-34-community-faq.md @@ -0,0 +1,202 @@ +# Phase 34 — Community FAQ +**Campaign:** Phase 34 GA (April 30, 2026) +**Owner:** Community Manager +**Use:** Pinned in Discord `#faq` on launch day. Linked from announcement CTA. +**Date:** 2026-04-23 + +--- + +## Tool Trace + +### What is Tool Trace? + +Tool Trace is a structured execution record that gets added to every A2A response your agent produces. For each tool your agent calls, you get: the tool name, the input parameters, and a short output preview — in the order they happened, with `run_id` pairing for parallel calls. + +Think of it as a print statement for your entire agent pipeline — you can finally see exactly what your agent did, not just what it returned. + +--- + +### Where is the `tool_trace` field? + +In `Message.metadata.tool_trace`. It's a JSON array in the response envelope — no SDK, no sidecar, no extra infrastructure. If you're consuming A2A responses in any language, just read `response.metadata.tool_trace` after a task completes. + +```python +response = agent.send(task="deploy to staging") +for entry in response.metadata.tool_trace: + print(f"{entry['tool']}: {entry['input']} → {entry['output_preview']}") +``` + +--- + +### Is Tool Trace on by default? + +Yes. Tool Trace is active by default for all Molecule AI workspaces — no configuration required, no feature flag to enable. Activity logging must be enabled on your workspace for traces to be persisted to `activity_logs` (searchable history), but the response-level metadata is always present regardless. + +--- + +### Does it cost extra? + +No. Tool Trace is a platform-native feature included with every Molecule AI plan. There is no additional cost and no tier restriction — it's in the A2A protocol, not a paid add-on. + +--- + +### What is the 200-entry cap? + +The cap prevents runaway loops from generating unbounded trace data. A task that calls more than 200 tools will have entries dropped from the end of the trace — you get the first 200, which is sufficient for debugging virtually any production task. + +If you're hitting the cap regularly, that's usually a signal your agent is doing too much in a single task — consider breaking it into smaller, more focused subtasks. + +--- + +### Does Tool Trace work with custom MCP tools? + +Yes. Tool Trace records every tool invocation via the agent runtime, regardless of whether the tool is a built-in Molecule tool or a custom MCP tool. The `tool` field shows the tool's registered name, `input` captures the parameters, and `output_preview` is the first ~200 chars of the response. Custom MCP tools appear identically to built-in tools in the trace. + +--- + +## Platform Instructions + +### What is Platform Instructions? + +Platform Instructions lets org admins set system-level rules that apply to every agent in the organization — at startup, before the agent reads its own config. Think of it as a system prompt for your whole org. + +Example rules: +- "Never commit directly to main — always open a PR first." +- "Tag all security-sensitive operations with an audit tag." +- "Confirm before running destructive commands in production." + +Rules are injected by the platform, not the workspace. A workspace user can't override or remove them by editing their `config.yaml`. + +--- + +### How do I set a Platform Instruction? + +Org admins use the control plane API: + +``` +PUT /cp/platform-instructions +``` + +Two scopes: +- **Global** — applies to every workspace in the org +- **Workspace** — applies to a specific workspace only (additive to global rules) + +For examples and full API documentation, see `docs.moleculesai.app/blog/platform-instructions-governance`. + +--- + +### Can workspace-level instructions override global ones? + +Workspace-level rules are additive to global ones, not overriding. A global rule and a workspace rule can both apply simultaneously. A workspace rule can explicitly opt out a global rule by prefix (e.g., `!global-rule-name`), but by default, both apply. + +--- + +### Is Platform Instructions on all plans? + +Platform Instructions is available on **Enterprise plans**. Org admins on Enterprise plans can configure global and workspace-scoped instructions via `PUT /cp/platform-instructions`. Standard plan orgs can view resolved instructions; only Enterprise plan orgs can create or modify them. + +--- + +### Is there an audit log for instruction changes? + +Yes. Instruction CRUD events (create/update/delete) are logged in the platform audit trail with the admin identity who made the change and a timestamp. Audit logs are accessible via `GET /cp/platform-instructions/history` (org admin only). This is the same audit infrastructure used for org API key management. + +--- + +## Partner API Keys (`mol_pk_*`) + +### What is it? + +Partner API Keys (`mol_pk_*`) let marketplaces, CI/CD pipelines, and platform builders programmatically create and manage Molecule AI orgs via API — no browser session, no manual handoff. It's a scoped, revocable token that grants partner-level access to org management endpoints. + +--- + +### When is it available? + +GA: **April 30, 2026**. The feature ships on April 30. Until then, the API is not live. + +--- + +### What can I build with it? + +Common patterns: +- **Marketplace integrations** — let customers provision Molecule AI orgs from your platform's admin dashboard +- **CI/CD test orgs** — spin up an ephemeral org per pipeline run, run your test suite, tear it down. Billing stops when you DELETE. +- **Internal tooling** — provision orgs for internal teams or products without browser auth + +Key constraints: keys are scoped to the orgs they're authorized for, rate-limited (60 req/min default, configurable), and fully revocable. Revocation is immediate — no grace period. + +--- + +### How do I get access? + +If you want to test Partner API Keys before GA, reach out via GitHub Discussions (`github.com/Molecule-AI/molecule-core/discussions`) or DM the Community Manager. Early access is available for partners with a concrete integration use case. + +Full docs on GA day: `docs.moleculesai.app/blog/partner-api-keys` + +--- + +## SaaS Fed v2 + +### What changed in SaaS Fed v2? + +SaaS Federation v2 is the multi-tenant control plane architecture that underlies all SaaS deployments. The v2 update brings: improved cross-tenant isolation, cleaner org lifecycle management, and tighter alignment with the Partner API Keys infrastructure. + +If you're running multiple orgs — for partners, internal teams, or separate products — the federation improvements make multi-org setups more robust and easier to operate at scale. External workspaces (agents running on laptops or other networks) also benefit from improved discovery and heartbeat reliability. + +For self-hosted users: nothing changes. Federation v2 is SaaS-only. + +--- + +## General + +### Why are you shipping these features at once? + +Because they're built to work together. Partner API Keys provisions the orgs. Platform Instructions governs what happens inside them. Tool Trace shows you what your agents actually did. Shipping them together means you get a coherent system from day one — not three unrelated features with interdependency debt. + +--- + +### Where do I report issues? + +For bugs and unexpected behavior: +- **Tool Trace / Platform Instructions** → `#bug-reports` in Discord, or open a GitHub issue and tag `@devrel` +- **Partner API Keys** → `#bug-reports` or GitHub issue + +For how-to questions and setup help: +- **All features** → `#general` in Discord, or GitHub Discussions + +--- + +### Where is the Discord for partner questions? + +There's no separate partner Discord — partner questions are handled in the main Molecule AI Discord, same as all community questions. Use `#general` for broad questions, `#announcements` for launch updates, and `#feedback` for product feedback. + +For direct partner program questions (early access, integration support, enterprise deals), DM the Community Manager or post in `#announcements` and tag `@community`. + +--- + +### Do I need to update my SDK? + +No. Tool Trace and Platform Instructions are API-level changes — they don't require SDK updates. Tool Trace is accessible via the existing A2A protocol (`Message.metadata.tool_trace`). Platform Instructions are managed via the control plane REST API (`PUT /cp/platform-instructions`). If you're using a Molecule SDK, you may already have helpers for these — check `docs.moleculesai.app/changelog` on April 30 for details. + +--- + +### Where's the migration guide? + +For Tool Trace and Platform Instructions: these are additive platform features, not migrations. Existing agents and workspaces work unchanged — Tool Trace starts appearing in responses automatically when activity logging is enabled. No config changes required to existing agents. + +For Partner API Keys: new feature, no migration needed. Existing org management continues via the browser UI and WorkOS session auth. + +General migration docs will be at `docs.moleculesai.app/guides/phase-34-migration` on GA day (April 30). + +--- + +## Quick reference + +| Feature | Docs | Blog | +|---------|------|------| +| Tool Trace | `docs.moleculesai.app/blog/ai-agent-observability-without-overhead` | | +| Platform Instructions | `docs.moleculesai.app/blog/platform-instructions-governance` | | +| Partner API Keys | `docs.moleculesai.app/blog/partner-api-keys` | GA April 30 | + +Questions not answered here? GitHub Discussions: `github.com/Molecule-AI/molecule-core/discussions` diff --git a/docs/marketing/launches/phase-34-discord-runbook.md b/docs/marketing/launches/phase-34-discord-runbook.md new file mode 100644 index 000000000..27a090ac6 --- /dev/null +++ b/docs/marketing/launches/phase-34-discord-runbook.md @@ -0,0 +1,223 @@ +# Phase 34 — Discord Launch Runbook +**Campaign:** Phase 34 GA (April 30, 2026) +**Owner:** Community Manager +**Use:** Step-by-step execution guide for launch day +**Date:** 2026-04-23 + +--- + +## Launch day overview + +| Time (UTC) | Action | +|------------|--------| +| -15 min (08:45) | Pre-launch checklist | +| -5 min (08:55) | Final link verification | +| 09:00 | Post in `#announcements` | +| 09:00 | Pin FAQ in `#faq` | +| 09:00–11:00 | Monitor `#general` + `#feedback` (2h active watch, 30-min SLA) | +| Ongoing | Route inbound to correct channel / team | +| Apr 30 ~16:00 (Day 2) | Reddit r/MachineLearning + HN Show HN | + +--- + +## Pre-launch checklist (complete by 08:45 UTC) + +### Blog posts verified live +- [ ] `docs.moleculesai.app/blog/ai-agent-observability-without-overhead` (Tool Trace) +- [ ] `docs.moleculesai.app/blog/platform-instructions-governance` (Platform Instructions) +- [ ] `docs.moleculesai.app/blog/partner-api-keys` (Partner API Keys — GA April 30, may show "coming soon" before launch) +- [ ] `docs.moleculesai.app/guides/external-workspace-quickstart` (SaaS Fed v2) ⚠️ PM VERIFICATION NEEDED — tutorial file not found in codebase, treat as unconfirmed +- [ ] `docs.moleculesai.app/blog/tool-trace-platform-instructions` (combined overview) + +### API endpoints responding +- [ ] `PUT /cp/platform-instructions` — test in staging (org admin endpoint) +- [ ] Partner API Keys endpoint — confirm not responding before GA (expected) +- [ ] `GET /cp/platform-instructions` — confirm accessible in staging + +### Docs updated +- [ ] `docs/architecture/partner-api-keys.md` — reflects `mol_pk_*` key format and scopes +- [ ] `docs/api-protocol/a2a-protocol.md` — mentions `tool_trace` in `Message.metadata` +- [ ] `docs/guides/external-workspace-quickstart.md` — ⚠️ PM VERIFICATION NEEDED — do not check as "done" until PM confirms what SaaS Fed v2 actually shipped + +### Announcement file verified +- [ ] `docs/marketing/launches/phase-34-community-announcement.md` — on `staging` or `main`, CTA links accurate +- [ ] No design partner names in copy +- [ ] Partner API Keys framed as "GA April 30" — not "available now" + +### X credentials status (issue #1865) +- [ ] If `X_API_KEY` + `X_API_SECRET` provided by mol-ops → note in Discord post thread +- [ ] If not provided → Reddit/HN posts go Day 2, no external social Apr 30 + +### Teams on standby +- [ ] DevRel confirmed monitoring `#devrel` or DM for how-to routing +- [ ] Platform team monitoring `#bug-reports` +- [ ] Marketing Lead aware of launch timing + +### Escalation path clear +- [ ] DM list for emergencies: DevRel, Security, Marketing Lead +- [ ] Bug-report channel confirmed active + +--- + +## Step 1 — Post announcement in `#announcements` (09:00 UTC) + +**Source:** `docs/marketing/launches/phase-34-community-announcement.md` + +Post as plain text, emoji-formatted. Discord message limit is 2000 chars — split across multiple messages if needed. Keep the block separators (`━━`) intact. + +**Before posting — final checks:** +1. Run `curl -s -o /dev/null -w "%{http_code}" docs.moleculesai.app/blog/ai-agent-observability-without-overhead` and confirm 200 +2. Confirm no "available now" framing for Partner API Keys +3. Confirm no design partner names + +**Post announcement, then immediately reply in thread:** +``` +📋 FAQ — answers to the top community questions: +[paste link or mirror the FAQ content here] + +Full blog coverage: +docs.moleculesai.app/blog/tool-trace-platform-instructions +docs.moleculesai.app/blog/ai-agent-observability-without-overhead +docs.moleculesai.app/blog/platform-instructions-governance +docs.moleculesai.app/blog/partner-api-keys +``` + +--- + +## Step 2 — Pin FAQ in `#faq` (09:00 UTC) + +1. Open `#faq` +2. Paste full content from `docs/marketing/launches/phase-34-community-faq.md` +3. Right-click → Pin Message +4. Confirm pin is visible +5. If channel has stale pins, clear old ones and pin Phase 34 FAQ + +**FAQ should be pinned before the announcement goes out** so people can find it immediately when they arrive. +**Day 2 update:** After the announcement settles, consider pinning the announcement itself in `#announcements` so it stays at the top of the channel. + +--- + +## Step 3 — Monitor `#general` and `#feedback` (09:00–11:00 UTC) + +**SLA: respond within 30 minutes of any Phase 34 reply.** + +Set a 30-minute repeating reminder to check both channels. + +**Response template — question you can answer:** +``` +Hey [name] — good question. [1-2 sentence answer]. Full details in our docs: [link]. Let me know if that doesn't cover it! +``` + +**Response template — question you can't answer:** +``` +Great question — I need to loop in the platform team and get back to you. Tagging @devrel for a closer look. +``` + +**Response template — feature request:** +``` +Love this idea — tagging @pm so this gets into the backlog. You can also open a GitHub issue with the label "enhancement" to track it formally. +``` + +--- + +## Step 4 — Monitor `#bugs`, `#partner-program` (ongoing) + +### `#bugs` channel +- Tool Trace bugs → tag `@devrel` in `#devrel` or DM directly +- Platform Instructions bugs → tag `@dev-lead` in `#devrel` or DM directly +- Partner API Keys issues (post-GA) → tag `@mol-ops` or DM + +### `#partner-program` channel +- Partner API Keys early access requests → acknowledge, DM with next steps +- Integration questions → route to DevRel if technical, Marketing Lead if strategic + +### `#general` +- How-to questions → answer directly or tag `@devrel` +- "Is this available now?" → check against GA date, redirect to docs +- Security concerns → do not respond publicly. DM Security team immediately. + +--- + +## Step 5 — Escalation paths + +| Issue type | Route to | How | +|-----------|----------|-----| +| Tool Trace unexpected behavior | DevRel | DM or tag in `#devrel` | +| Platform Instructions not applying | DevRel / Dev Lead | DM or tag in `#devrel` | +| Partner API Keys access / billing issues | mol-ops | DM or tag in `#partner-program` | +| SaaS Fed v2 isolation concern | Security / Dev Lead | DM Security, tag Dev Lead | +| Security vulnerability | Security team | **DM only — do not post in any channel** | +| Press / media inquiry | Marketing Lead | **Do not engage publicly — DM Marketing Lead immediately** | + +**For any toxic or spam thread:** +- Do not engage +- Screenshot thread +- DM Marketing Lead with link + screenshot + +--- + +## Response templates — common questions + +**Q: "Is Partner API Keys available now?"** +A: "Partner API Keys ship on April 30, 2026. Until then the API isn't live. If you want early access for a concrete integration use case, DM me and I'll connect you with the team." + +**Q: "How is Tool Trace different from Langfuse/Helicone?"** +A: "Tool Trace captures A2A-level agent behavior — tool calls, inputs, output previews. Langfuse/Helicone capture LLM API calls. They measure different layers. If you're running agents on Molecule, Tool Trace is zero-config and free. If you need cross-platform multi-model observability, Langfuse is still a great complement." + +**Q: "Can I use Platform Instructions to enforce a policy across my org?"** +A: "Yes — set a global instruction via PUT /cp/platform-instructions (scope: global). It applies to every workspace in your org at startup. Rules prepend to each agent's system prompt — workspace users can't override them by editing config.yaml." + +**Q: "What's the rate limit on Partner API Keys?"** +A: "Default is 60 requests/minute per key, configurable at key creation time. For high-volume CI pipelines, request a higher limit when you apply for a partner key." + +**Q: "My agent isn't producing tool_trace in responses."** +A: "Tool Trace is on by default for all workspaces. Make sure activity logging is enabled on your workspace. If it is, and you're still not seeing traces, open a bug in #bug-reports and tag @devrel." + +**Q: "Where is the migration guide for Phase 34?"** +A: "Phase 34 features are additive — no migration required for existing agents. Tool Trace starts appearing automatically, Platform Instructions are opt-in per org admin. Migration docs at docs.moleculesai.app/guides/phase-34-migration — live on April 30." + +--- + +## Post-launch (24h): metrics and feedback + +### Engagement metrics to capture +- `#announcements` — reply count, reaction count (first 4h) +- `#faq` — pin view count if available, question count +- `#general` — Phase 34 thread volume +- GitHub Discussions — new discussions opened, response time +- Reddit/HN (Day 2) — post score, comment count, avg time to first reply + +### Feedback to route to PM +- Questions that surfaced unexpected complexity in the features +- Feature requests that multiple community members asked about +- Any confusion about what shipped vs what's coming April 30 +- Partner API Keys early access requests — log use case + org name + +### Day 2 — Reddit + HN + +**Reddit r/MachineLearning** (~09:00 PT / 16:00 UTC): +- Source: `docs/marketing/community/phase34-reddit-post.md` +- Title: "Built agent execution tracing into the platform — no SDK, no sidecar, no sampling" +- Monitor for 2h, reply to top-level comments within 30 min +- Do not name design partners + +**HackerNews Show HN** (~09:00 PT / 16:00 UTC): +- Source: `docs/marketing/community/phase34-hn-post.md` +- Title: "Show HN: Molecule AI's approach to platform-native agent observability + governance" +- First reply (pinned): code snippet from the tool_trace example +- Monitor for 3h, reply to every top-level comment + +--- + +## Files reference + +| File | Purpose | +|------|---------| +| `docs/marketing/launches/phase-34-community-announcement.md` | Announce in `#announcements` | +| `docs/marketing/launches/phase-34-community-faq.md` | Pin in `#faq` | +| `docs/marketing/community/phase34-reddit-post.md` | Reddit Day 2 | +| `docs/marketing/community/phase34-hn-post.md` | HN Day 2 | +| `docs/marketing/briefs/phase34-positioning.md` | PMM-approved positioning | +| `docs/marketing/launches/phase-34-discord-runbook.md` | This file | + +**Last updated:** 2026-04-23 diff --git a/docs/marketing/launches/pr-1533-ec2-instance-connect-ssh.md b/docs/marketing/launches/pr-1533-ec2-instance-connect-ssh.md index f700dac7e..d4f94a45d 100644 --- a/docs/marketing/launches/pr-1533-ec2-instance-connect-ssh.md +++ b/docs/marketing/launches/pr-1533-ec2-instance-connect-ssh.md @@ -111,8 +111,9 @@ Fallback (technical): *"CP-provisioned workspaces get browser-based terminal via | Channel | Asset | Owner | Status | |---------|-------|-------|--------| -| Blog post | "How to access your EC2 workspace terminal from the canvas" | Content Marketer | Blocked: needs DevRel code demo first | -| Social launch thread | 5 posts: problem → solution → claim 1 → claim 2 → CTA | Social Media Brand | Blocked: awaiting blog post + code demo | +| Blog post | "How to access your EC2 workspace terminal from the canvas" | Content Marketer | Blocked: needs DevRel code demo first (#1545) | +| Social launch thread | 5 posts: problem → solution → claim 1 → claim 2 → CTA | Social Media Brand | ✅ APPROVED — copy at `docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/social-copy.md` | +| TTS audio file | Voice-over for launch announcement | Social Media Brand | 🔴 BLOCKING — TTS file needed before publish | | Code demo | Working example: open canvas → click terminal → interact with EC2 workspace | DevRel Engineer | Needs assignment (#1545) | | Docs | `docs/infra/workspace-terminal.md` | DevRel Engineer | ✅ Shipped in PR #1533 | @@ -132,8 +133,10 @@ Fallback (technical): *"CP-provisioned workspaces get browser-based terminal via - [x] Does the terminal UI expose EC2 Instance Connect as a distinct connection type? → No — seamless; the platform handles it transparently - [x] Is there a docs page? → Yes: `docs/infra/workspace-terminal.md` (shipped in PR #1533) -- [ ] Social Media Brand: confirm launch thread length (5 posts recommended) +- [x] Social Media Brand: confirm launch thread length (5 posts recommended) - [ ] Confirm EICE VPC Endpoint is present in the SaaS production VPC (DevOps/ops check) +- [x] Social copy status → APPROVED (social-copy.md on staging, 2026-04-22) +- [ ] 🔴 TTS audio file: Social Media Brand needs TTS generation before publish --- diff --git a/docs/marketing/launches/pr-1686-tool-trace-platform-instructions.md b/docs/marketing/launches/pr-1686-tool-trace-platform-instructions.md new file mode 100644 index 000000000..8335481d8 --- /dev/null +++ b/docs/marketing/launches/pr-1686-tool-trace-platform-instructions.md @@ -0,0 +1,49 @@ +# Launch Brief: PR #1686 — Tool Trace + Platform Instructions + +**PR:** #1686 `feat: tool trace + platform instructions` +**Merged:** 2026-04-23T02:43:27Z +**Status:** GA-ready (passed code review, IDOR and DoS fixes verified) +**Brief owner:** PMM + +--- + +## Problem + +A2A agentic workflows are opaque to platform teams. When an agent runs inside a workspace, operators have: +- **Zero observability** into which tools were called, what inputs were used, or what outputs were returned +- **No governance layer** — compliance requirements, cost controls, and security guardrails cannot be enforced at the platform level without modifying agent code + +This blocks enterprise adoption: platform engineers need to audit agent behavior, and security/compliance teams need to enforce guardrails before agents touch production systems. + +--- + +## Solution + +Two independent features shipping in the same PR: + +1. **Tool Trace** — Every A2A response metadata (`Message.metadata.tool_trace`) now includes a list of `{tool_name, input, output_preview}` entries. Pairs start/end events via `run_id` so parallel tool calls are correctly scoped. Capped at 200 entries to prevent runaway-loop bloat. + +2. **Platform Instructions** — Workspace-scoped configuration rules injected into the system prompt at startup. Supports global and per-workspace scope. Includes a CRUD API and `/workspaces/:id/instructions/resolve` endpoint (IDOR-protected under `wsAuth`). CHECK constraints enforce an 8KB content cap to prevent token-budget DoS. + +--- + +## 3 Claims + +1. **Full tool-level visibility in every A2A response** — Platform teams can now see exactly what tools an agent called, with inputs and output previews, without adding instrumentation to the agent itself. + +2. **Governance without agent code changes** — Platform Instructions let compliance and security teams enforce guardrails (compliance requirements, cost limits, security policies) at the workspace level, prepended to the agent's system prompt automatically at startup. + +3. **Enterprise-ready by default** — IDOR vulnerability in the resolve endpoint fixed pre-merge; 8KB content cap prevents token-budget DoS; `run_id`-scoped parallel tool call pairing ensures correct attribution under concurrent execution. + +--- + +## Target Developer + +- **Primary:** Platform engineers and DevOps teams deploying A2A agentic workflows in production +- **Secondary:** Enterprise security/compliance teams requiring audit trails and governance controls before approving agent deployments + +--- + +## CTA + +Log into the workspace and enable Platform Instructions via the CRUD API, then deploy an A2A agent — the governance rules are automatically prepended to the system prompt at startup. Tool traces appear in `Message.metadata` on every A2A response with zero agent-side changes. diff --git a/docs/marketing/launches/pr-1714-canvas-require-model.md b/docs/marketing/launches/pr-1714-canvas-require-model.md new file mode 100644 index 000000000..09629c324 --- /dev/null +++ b/docs/marketing/launches/pr-1714-canvas-require-model.md @@ -0,0 +1,16 @@ +# PR #1714 — Canvas: Require Hermes Model at Create +**Source:** PR #1714 merged to `origin/main` (2026-04-23) +**Status:** CHANGELOG — no marketing campaign warranted +**Type:** Bug fix / UX improvement + +## Summary +Canvas workspace creation dialog now requires a model selection before submitting. Previously, omitting the model caused a silent Anthropic 401 error — the workspace would fail without a clear user-facing error. Now the dialog enforces model selection at create time and sends the model to the control plane. + +**Files changed:** `canvas/src/components/CreateWorkspaceDialog.tsx` (+90, -17) + +## Marketing action +None. Internal bug fix. Add to release notes / changelog only. + +## Content angle +N/A — bug fix, not a feature + diff --git a/docs/marketing/launches/pr-1870-a2a-queue-on-busy.md b/docs/marketing/launches/pr-1870-a2a-queue-on-busy.md new file mode 100644 index 000000000..64d12ace5 --- /dev/null +++ b/docs/marketing/launches/pr-1870-a2a-queue-on-busy.md @@ -0,0 +1,61 @@ +# PR #1870 — A2A Queue-on-Busy: Priority Queue Phase 1 +**Date:** 2026-04-24 | **Owner:** PMM | **PR:** #1870 (merged 2026-04-23) +**Feature:** `feat(a2a): queue-on-busy — Phase 1 of priority queue` +**Brief status:** DRAFT — needs PM confirmation of positioning + +--- + +## Problem + +When a Molecule AI agent is busy processing a long-running task, inbound A2A messages have nowhere to go. Without a queue, messages arriving during a busy period are dropped, returned as errors, or cause task conflicts. For production multi-agent workflows, this means unreliable task routing — especially when a supervisor agent delegates to a busy subordinate. + +## Solution + +Phase 1 implements queue-on-busy behavior for A2A task routing. When an agent is busy, incoming tasks are queued rather than rejected or dropped. The queue is priority-ordered, so higher-priority tasks are processed first when the agent becomes available. + +**Phase 1 scope (PR #1870):** +- `ON CONFLICT` syntax fix in a2a-queue handler (`#1893`) +- Queue structure: messages queued when agent reports `busy` status +- Priority ordering: queue is priority-sorted (Phase 1 = foundation) + +**Phase 2+ (not yet merged):** Full priority levels, queue management UI, TTL/expiry. + +--- + +## Three Claims (confirm with PM before publishing) + +1. **No dropped tasks.** When an agent is busy, inbound tasks are queued rather than rejected — nothing falls through. +2. **Priority ordering.** High-priority tasks ahead in the queue are delivered first when the agent frees up. +3. **Production reliability.** A2A task routing becomes reliable under concurrent load, not best-effort. + +--- + +## Target Developer + +Platform engineers running multi-agent supervisor/subordinate workflows. Anyone with two or more agents that delegate to each other and need reliable task delivery under load. + +--- + +## CTA + +"Deploy multi-agent workflows with confidence — A2A queues ensure no task is lost when an agent is busy." + +--- + +## Language to Avoid + +- "Guaranteed delivery" — Phase 1 queues to memory/disk but Phase 2+ has TTL +- "Full priority queue" — Phase 1 is the foundation, not the complete implementation +- "queue management UI" — not in Phase 1 + +--- + +## Do We Need a Standalone Campaign? + +**No.** A2A Queue Phase 1 is a reliability underpinning, not a headline feature. Recommend: brief as a supporting proof point in the observability/governance narrative (Phase 34 Tool Trace + Platform Instructions story), or as a footnote in the A2A enterprise deep-dive. + +**Decision for Marketing Lead:** File this brief. Do not create standalone social copy unless Phase 2 ships with a full priority management UI. + +--- + +*PMM brief 2026-04-24 — PR #1892 merged 2026-04-23, no prior brief found. Needs PM confirmation of claims before external use.* diff --git a/docs/marketing/seo/a2a-enterprise-deep-dive-seo-brief.md b/docs/marketing/seo/a2a-enterprise-deep-dive-seo-brief.md new file mode 100644 index 000000000..ac2c37602 --- /dev/null +++ b/docs/marketing/seo/a2a-enterprise-deep-dive-seo-brief.md @@ -0,0 +1,135 @@ +# A2A Enterprise Deep-Dive — SEO Brief (Confirmed) +**Campaign:** Phase 30 / A2A v1 enterprise positioning +**Author:** SEO Analyst (5b277fc4) — consolidated from PMM brief + molecule-core brief +**Date:** 2026-04-23 +**Status:** ✅ Approved by Marketing Lead 2026-04-23 — ready for Content Marketer (#1492) +**Post:** `docs/blog/2026-04-22-a2a-v1-agent-platform/index.md` (✅ Published 2026-04-22) +**Slug:** `a2a-v1-agent-platform` ✅ +**Target URL:** `https://docs.molecule.ai/blog/a2a-v1-agent-platform` +**Target length:** ~900 words +**Pipeline:** keywords.md item #15 — closed ✅ + +--- + +## Search Intent + +**Primary intent:** Informational (enterprise buyers researching agent orchestration platforms) +**Secondary intent:** Comparative (evaluating Molecule AI vs LangGraph, CrewAI, custom integrations) +**Content type:** In-depth blog post / thought leadership +**Audience:** IT leads, DevOps architects, platform engineers evaluating multi-agent orchestration + +--- + +## Canonical URL + +✅ `https://docs.molecule.ai/blog/a2a-v1-agent-platform` + +--- + +## Keywords + +### P0 — must appear in H1, first paragraph, or meta + +| Keyword | Target density | Placement | +|---------|---------------|-----------| +| `enterprise AI agent platform` | 2–3× | H1 anchor, intro paragraph, meta description | +| `multi-cloud AI agent orchestration` | 2× | H2, body (cross-cloud section) | +| `agent delegation audit trail` | 2× | Section heading, body (org API key attribution) | + +### P1 — supporting (1–2× each) + +| Keyword | Placement | +|---------|-----------| +| `A2A protocol enterprise` | URL slug, intro, meta | +| `multi-agent platform comparison` | LangGraph ADR section | +| `cross-cloud agent communication` | VPN section | +| `enterprise AI governance` | Intro hook, closing paragraph | +| `AI agent fleet management` | Fleet/canvas section | + +### P2 — internal linking anchors + +Use as anchor text when linking to other docs: +- "per-workspace auth tokens" → `/docs/guides/org-api-keys` +- "remote workspaces" → `/docs/guides/remote-workspaces` +- "external agent registration" → `/docs/guides/external-agent-registration` +- "Phase 30" → `/docs/blog/remote-workspaces` + +--- + +## Meta Title + Description + +**Title tag (60 chars):** +``` +A2A Protocol for Enterprise: Cross-Cloud Agents Without VPN +``` + +**Meta description (155 chars):** +``` +Molecule AI's A2A protocol runs agent-to-agent communication across any infrastructure — cloud, on-prem, laptop — with org API key attribution on every delegation and a full audit trail. No VPN required. +``` + +--- + +## Content Structure + +### Hook (first 100 words) +Lead with A2A v1.0 stats (March 12, LF, 23.3k stars, 5 SDKs, 383 implementations) → the moment the agent internet gets a standard. Most platforms add it. One platform was built for it from the ground up. Primary keywords: "enterprise AI agent platform", "A2A protocol". + +### Section 1 — The Enterprise Problem: Hub-and-Spoke Doesn't Scale +Frame the problem enterprise teams face: agents on different clouds, different teams, different vendors — no standard way to delegate between them without a central hub (which becomes a bottleneck and a single point of failure). +**Keywords:** `multi-cloud AI agent orchestration`, `enterprise AI governance` + +### Section 2 — Molecule AI's Peer-to-Peer Answer +Direct delegation via A2A. Platform handles discovery (registry), agents delegate directly — no hub, no message-path bottleneck. +**Proof points:** +1. A2A proxy live in production (Phase 30, 2026-04-20) +2. Per-workspace bearer tokens at every authenticated route — `Authorization: Bearer ` + `X-Workspace-ID` enforced at protocol level +3. Cross-cloud without VPN: platform discovery reaches peers across clouds, control plane never in the message path +4. Any A2A-compatible agent joins without code changes +**Keywords:** `agent delegation audit trail`, `cross-cloud agent communication` + +### Section 3 — Code Sample (JSON-RPC, ~15 lines) +Minimal A2A delegation call — agents passing tasks to peers across clouds. Must show token scope and workspace ID header. + +### Section 4 — LangGraph ADR as Industry Validation +Not the lead — the closer. LangGraph ships A2A support, validating the protocol. Molecule AI was there first, ships it in production today, and the governance layer is the differentiation. +**Keywords:** `multi-agent platform comparison` + +### Closing CTA +"Get started with remote workspaces" → `/docs/guides/remote-workspaces` + +--- + +## Internal Linking + +Minimum 4 internal links. No external competitor links. + +| Anchor text | Target | +|-------------|--------| +| per-workspace auth tokens | `/docs/guides/org-api-keys` | +| remote workspaces | `/docs/guides/remote-workspaces` | +| external agent registration guide | `/docs/guides/external-agent-registration` | +| Phase 30 | `/docs/blog/remote-workspaces` | + +--- + +## Content Guardrails + +- Do NOT claim the platform is in the message path. The platform handles *discovery*, not routing. Get this right — it is the core architectural claim. +- Auth: Phase 30 enforces per-workspace bearer tokens at every authenticated route (`Authorization: Bearer ` + `X-Workspace-ID`). Peer *discovery* is protocol-native — agents discover peers via the platform registry, but every call is token-authenticated. Do not imply A2A calls are unauthenticated. `CanCommunicate()` is an authorization check at discovery, not the auth mechanism. +- VPN: "Molecule AI agents use platform discovery to reach peers across clouds — no VPN tunnel required for the control plane. For agent-to-agent traffic, platform discovery replaces VPN-based service mesh in most configurations." +- Do NOT commit to a publish date in the body. Use "Phase 30 (2026-04-20)" as the ship reference. +- Do include at least one concrete code example — enterprise buyers need to see the actual API surface. + +--- + +## Approval History + +| Date | Actor | Decision | +|------|-------|----------| +| 2026-04-22 | PMM | Conditional approval — auth description fixed | +| 2026-04-23 | Marketing Lead | Direct approval — PMM step waived; pipeline item #15 closed | + +--- + +*Consolidated by SEO Analyst (5b277fc4) 2026-04-23. Source briefs: `docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md` and `repos/molecule-core/docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md`.* diff --git a/docs/marketing/seo/mcp-server-list-explainer-seo-brief.md b/docs/marketing/seo/mcp-server-list-explainer-seo-brief.md new file mode 100644 index 000000000..fb56ea1d7 --- /dev/null +++ b/docs/marketing/seo/mcp-server-list-explainer-seo-brief.md @@ -0,0 +1,63 @@ +# MCP Server List Explainer — SEO Brief +**Post:** Issue #1493 — MCP server list explainer blog post +**Date:** 2026-04-23 | **Author:** Marketing Lead (direct — SEO Analyst workspace looping) +**Target publish:** Week of Apr 28–May 2 + +--- + +## Keyword Cluster + +**Primary keyword:** `MCP server list` +Search intent: Navigational/informational. Builders looking for a catalogue of available Model Context Protocol servers — what exists, what it does, how to add it to an agent. +Competition: Low. Category is emerging; no authoritative list exists yet. Strong first-mover SEO opportunity. + +**Supporting LSI keywords:** +1. `Model Context Protocol servers` — exact-match for the underlying protocol name; medium volume, growing fast +2. `MCP tools catalogue` — commercial investigation intent; builders evaluating what tools to enable +3. `available MCP integrations` — transactional intent; engineers ready to configure + +--- + +## On-Page SEO Specs + +| Element | Recommendation | +|---------|---------------| +| **Title tag** | `The Complete MCP Server List for Molecule AI (2026)` — 55 chars | +| **Meta description** | `Browse every MCP server available in Molecule AI — browser automation, code execution, file access, and more. Updated for 2026.` — 128 chars | +| **H1** | `Every MCP Server Available in Molecule AI (2026)` | +| **Slug** | `mcp-server-list` | +| **OG image** | Grid/table visual showing MCP server names + icons — scannable at a glance | + +--- + +## Content Guidance for Writer (#1493) + +**Structure:** +1. Intro (100w): what MCP is, why the list matters for agent builders +2. Full server list — grouped by category: + - Browser/Web: Chrome DevTools MCP, Playwright MCP + - Cloud: Cloudflare Artifacts, EC2 Instance Connect + - Code execution: Sandbox backends + - File/storage: WriteFile, ReadFile, Glob, Grep + - Communication: Slack, Discord adapters + - Custom/community: how to add your own +3. Governance section (100w): how Molecule AI controls which MCP servers agents can access (ref: org-scoped API keys, Platform Instructions) +4. CTA: link to MCP governance docs + partner program + +**Internal links FROM this post:** +- Chrome DevTools MCP blog post (`docs/blog/2026-04-20-chrome-devtools-mcp/`) +- Cloudflare Artifacts blog post (`docs/blog/2026-04-21-cloudflare-artifacts/`) +- Tool Trace blog post (`docs/marketing/blog/2026-04-23-tool-trace-platform-instructions.md`) — "see what MCP tools your agents called" + +**Internal links TO this post (back-link from):** +- Chrome DevTools MCP post — add "See full MCP server list →" callout +- A2A v1 blog post — reference MCP server catalogue in context of tool ecosystem + +--- + +## Pipeline item #15 — CLOSED +A2A v1 slug `a2a-v1-agent-platform` approved by Marketing Lead directly. No further PMM routing needed. Update `docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md` status to "✅ Approved ML 2026-04-23." + +--- + +*Marketing Lead 2026-04-23. SEO Analyst to add live keyword volume data when workspace recovers.* diff --git a/docs/marketing/seo/phase-34-launch-seo-brief.md b/docs/marketing/seo/phase-34-launch-seo-brief.md new file mode 100644 index 000000000..c0ddc07c2 --- /dev/null +++ b/docs/marketing/seo/phase-34-launch-seo-brief.md @@ -0,0 +1,96 @@ +# Phase 34 Launch — SEO Brief +**Date:** 2026-04-23 +**Author:** Marketing Lead (drafted directly — SEO Analyst workspace looping) +**GA Date:** April 30, 2026 +**Features:** Tool Trace, Platform Instructions, Partner API Keys (`mol_pk_*`), SaaS Fed v2 + +--- + +## Keyword Research + +### Cluster A — Agent Observability / Tool Tracing + +**Primary keyword:** `agent observability` +Search intent: Informational + commercial investigation. Builders evaluating how to monitor multi-agent systems in production. High technical sophistication. Growing volume as LLM agent frameworks mature (LangSmith, Langfuse, Helicone driving awareness of the category). + +**Supporting LSI keywords:** +1. `multi-agent tracing` — captures the A2A-specific layer; low competition, highly specific to Molecule's positioning +2. `LLM tool call logging` — transactional intent, developers searching for how to log specific tool invocations +3. `agent execution trace` — technical variant, aligns directly with `tool_trace` field name + +**Competition level:** Medium. LangSmith and Langfuse dominate "LLM observability" broadly. Molecule's differentiator is **A2A-native, zero-integration** tracing — angle into the gap with "agent observability without a third-party SDK." + +**Avoid:** "LLM observability" as primary — Langfuse/Datadog own it. Target the agent-behavior layer specifically. + +--- + +### Cluster B — Partner API Provisioning + +**Primary keyword:** `agent platform API` +Search intent: Commercial investigation. Platform engineers and marketplace builders evaluating whether an agent framework exposes programmable org lifecycle management. + +**Supporting LSI keywords:** +1. `programmatic org provisioning` — exact-match for the mol_pk_* use case; low competition, high buying intent +2. `multi-tenant agent platform` — captures the reseller/marketplace angle +3. `partner API integration` — broader but captures the ecosystem builder ICP + +**Competition level:** Low–medium. No competitor is ranking for "partner API provisioning" in the agent orchestration context — genuine first-mover SEO window ahead of April 30 GA. + +--- + +## On-Page SEO Brief — Tool Trace Blog Post + +**Target file:** `docs/marketing/blog/2026-04-23-tool-trace-platform-instructions.md` +*(Note: file not yet written as of 2026-04-23 — apply these specs when Content Marketer delivers)* + +| Element | Recommendation | +|---------|---------------| +| **Title tag** | `Agent Observability Built In: Tool Trace + Platform Instructions` (60 chars) | +| **Meta description** | `Molecule AI now records every tool call your agents make — name, input, output preview — with zero SDK setup. Plus org-level Platform Instructions.` (150 chars) | +| **H1** | `Molecule agents now ship with built-in execution tracing and governance` | +| **Slug** | `/blog/agent-observability-tool-trace-platform-instructions` | +| **OG image** | Generate with feature name + "Built-in. No SDK." tagline | + +**Internal linking targets (link FROM new post TO these):** +- `docs/blog/2026-04-21-cloudflare-artifacts/` — cloud-native platform angle +- `docs/blog/2026-04-22-a2a-v1-agent-platform/` — A2A architecture context +- `docs/marketing/launches/pr-1105-org-scoped-api-keys.md` — auth layer context (org keys → tool trace → platform instructions ladder) + +**Link TO new post FROM:** +- `docs/blog/2026-04-22-a2a-v1-agent-platform/` — add a "→ See also: Tool Trace for A2A observability" callout +- Any future Partner API Keys post — Tool Trace is a prerequisite story for the partner platform narrative + +--- + +## April 30 Launch SEO Checklist + +### Pages needing og:image / meta desc updates +- [ ] `docs/blog/2026-04-21-cloudflare-artifacts/index.md` — og:image path fix already committed (PR #1899); verify meta desc present +- [ ] `docs/blog/2026-04-22-a2a-v1-agent-platform/index.md` — slug updated to `a2a-v1-agent-platform` (pipeline #15 ✅); confirm meta desc ≤155 chars +- [ ] Tool Trace blog post (when written) — apply title/meta from table above +- [ ] Partner API Keys GA announcement page — needs dedicated og:image with `mol_pk_*` branding + +### Cross-linking before April 30 +1. Add "Phase 34 ships April 30" callout to `docs/blog/2026-04-22-a2a-v1-agent-platform/` sidebar or footer +2. Ensure Discord adapter post links to Phase 34 announcement once it publishes +3. After Tool Trace blog post lands, back-link from A2A v1 post + +### Core Web Vitals notes +- Blog template: no known LCP issues from Lighthouse audit (see `docs/marketing/seo/lighthouse-audit-chrome-devtools-mcp-2026-04-22.md` for baseline) +- Watch: TTS audio embeds in new blog posts — lazy-load audio players, don't autoplay on load +- Watch: og:image generation — ensure images are ≤200KB and served via CDN, not inline + +--- + +## Keyword Gaps to Address (Next 30 Days) + +| Gap | Recommended Post | Priority | +|-----|-----------------|----------| +| "agent platform for marketplaces" | Partner API Keys deep-dive (after Apr 30 GA) | High | +| "multi-tenant LLM platform" | Case study: ephemeral test orgs per PR | High | +| "MCP server governance" | MCP server list explainer (#1493) | Medium | +| "A2A protocol enterprise" | A2A enterprise deep-dive (#1492) | Medium | + +--- + +*Marketing Lead 2026-04-23. SEO Analyst to review and extend with live keyword volume data when workspace recovers.* diff --git a/docs/marketing/social/2026-04-21-chrome-devtools-mcp/social-copy.md b/docs/marketing/social/2026-04-21-chrome-devtools-mcp/social-copy.md new file mode 100644 index 000000000..ecec7830c --- /dev/null +++ b/docs/marketing/social/2026-04-21-chrome-devtools-mcp/social-copy.md @@ -0,0 +1,87 @@ +# Chrome DevTools MCP — Social Copy +**Feature:** Chrome DevTools MCP (PR #1306 merged to origin/main 2026-04-21) +**Campaign:** Phase 30 — Remote Workspaces | **Canonical URL:** `docs.molecule.ai/blog/browser-automation-ai-agents-mcp` +**Status:** MERGED — awaiting Marketing Lead approval for publishing +**Owner:** PMM → Social Media Brand | **Day:** Phase 30 social campaign Day 1 + +--- + +## X (140–280 chars) + +### Version A — Governance angle ✅ (enterprise lead) +``` +Chrome DevTools MCP gives agents full browser control. Screenshot, DOM, JS execution — all through a standard interface. + +Raw CDP is all-or-nothing. Molecule AI adds the governance layer: which agents get access, what they can do, how to revoke it. + +Audit trail included. +``` +**Angle:** Enterprise/IT buyer — governance, not features + +--- + +### Version B — Production use cases (dev credibility) +``` +Three things you couldn't automate before Chrome DevTools MCP + Molecule AI governance: + +1. Lighthouse CI/CD audits — agent opens Chrome, runs Lighthouse, posts score to PR +2. Visual regression testing — screenshot diffs across agent workflow runs +3. Authenticated session scraping — agent behind a login with managed cookies + +All with org API key audit trail. +``` +**Angle:** Platform engineers — shows real-world CI/CD and testing use cases + +--- + +### Version C — Problem framing (developer) +``` +Chrome DevTools MCP: browser automation as a first-class MCP tool. + +For prototypes: great. For production: you need something between no browser and full admin. That's the gap Molecule AI's MCP governance fills. +``` +**Angle:** Developer audience — the governance story without the enterprise language + +--- + +## LinkedIn (100–200 words) + +Chrome DevTools MCP shipped in early 2026 — and browser automation is now a standard tool for any compatible AI agent. + +Screenshot. DOM inspection. Network interception. JavaScript execution. No custom wrappers, no browser-driver installation. + +That's the prototype story. For production — especially anything touching customer-facing workflows or authenticated sessions — all-or-nothing CDP access is a governance gap. + +Molecule AI's MCP governance layer answers the production questions: +- Which agents can open a browser? +- What can they do with it? +- How do you revoke access? +- When something goes wrong, who accessed what session data? + +Real-world use cases the layer enables: automated Lighthouse performance audits in CI/CD, screenshot-based visual regression testing, and authenticated session scraping — agents operating behind a login with cookies managed through the platform's secrets system. + +Every action is logged. Every browser operation is attributed to an org API key and workspace ID. + +Chrome DevTools MCP plus Molecule AI's governance layer: browser automation that meets production standards. + +--- + +## Visual Asset Specifications + +1. **X Version B:** 3-item checklist graphic — "Lighthouse CI/CD / Visual Regression / Auth Scraping" +2. **X Version A / LinkedIn:** Fleet diagram from Phase 30 — reusable asset `marketing/assets/phase30-fleet-diagram.png` +3. **Quote card:** "something between no browser and full admin" — for LinkedIn or X Version C + +--- + +## Campaign Notes + +**Audience:** Platform engineers + enterprise IT (X Version A), DevOps/CI teams (X Version B), developers (X Version C) +**Tone:** Governance-first — don't lead with the browser capability, lead with the governance gap it fills +**Hashtags:** `#MCP #BrowserAutomation #AIAgents #MoleculeAI #DevOps #QA #CI/CD` +**Coordinate with:** Phase 30 social campaign. Chrome DevTools MCP is Day 1 — posts before Fly.io, EC2, and Org API Keys. + +--- + +*Draft by PMM 2026-04-21 — based on PR #1306 merged to origin/main* +*Updated 2026-04-23: confirmed merged status; Marketing Lead approval required before publishing* \ No newline at end of file diff --git a/docs/marketing/social/2026-04-21-cloudflare-artifacts/social-copy.md b/docs/marketing/social/2026-04-21-cloudflare-artifacts/social-copy.md new file mode 100644 index 000000000..604848068 --- /dev/null +++ b/docs/marketing/social/2026-04-21-cloudflare-artifacts/social-copy.md @@ -0,0 +1,178 @@ +# Cloudflare Artifacts — Social Copy +**Feature:** Cloudflare Artifacts integration (PR #641, merged 2026-04-17) +**Blog:** `docs/blog/2026-04-21-cloudflare-artifacts/index.md` (live on staging, published 2026-04-21) +**Canonical URL:** `moleculesai.app/blog/cloudflare-artifacts-molecule-ai` +**Status:** DRAFT — PMM pre-write, ready for Social Media Brand execution once X credentials restored +**Owner:** PMM → Social Media Brand | **Day:** Phase 30 social campaign — catch-up post (blog shipped April 21, social delayed) +**Assets needed:** Screenshot of Artifacts repo attach flow + git commit terminal output + +--- + +## Angle: "Your AI agent just deleted three hours of work. Here's why that doesn't have to happen again." + +Lead with the pain story. The technology is the answer, not the hook. Close with the CTA to the blog post. + +--- + +## X (Twitter) — Primary thread (5 posts) + +### Post 1 — Hook (pain story) ✅ PRIMARY +``` +Your AI agent just deleted three hours of work. + +No malice. No bug. Just — session ended, memory cleared, everything gone. + +That's not an AI problem. That's a storage problem. + +Git-native agent storage — every session, every change, every rollback. No extra setup. + +→ [blog link] +``` + +--- + +### Post 2 — Why not just use Git? +``` +"Agents can call `git commit`." + +Sure — if you want to give every agent your GitHub credentials, manage SSH keys across 50 containers, and write human-readable commit messages in every task loop. + +Agents need version control designed for agents. Not humans with terminals. + +Cloudflare Artifacts: automatic snapshots, API-first branching, short-lived credentials. Git for agents. + +→ [blog link] +``` + +--- + +### Post 3 — How it works +``` +Attach a git repository to any Molecule AI workspace — in one API call. + +Import an existing GitHub repo, or spin up a new Artifacts namespace. Your agent clones, commits, pushes, and pulls — using the same git workflow your team already knows. + +No credentials stored. No terminal required. Just version history. + +Git-native storage for AI agents: → [blog link] +``` + +--- + +### Post 4 — The three use cases +``` +Three things you couldn't automate before Cloudflare Artifacts: + +1. Multi-agent pipelines — Agent A writes a branch, Agent B reviews and approves. No Slack threads. +2. Crash recovery — Agent crashes mid-task? Start from the last commit, not a blank workspace. +3. Experimentation without risk — Fork a branch before trying something risky. Delete it if it fails. Main branch stays clean. + +→ [blog link] +``` + +--- + +### Post 5 — CTA +``` +AI agents write code, generate assets, and produce artifacts. + +Most of the time, those artifacts are gone when the session ends. + +Cloudflare Artifacts: git-native storage for AI agents — attached to any Molecule AI workspace via API. Every session, every change, every rollback. + +Shipped today: → [blog link] + +#AIAgents #GitForAgents #MoleculeAI #Cloudflare #DevOps +``` + +--- + +## LinkedIn — Single post + +**Title:** The reason your AI agent keeps losing work is a storage problem, not an AI problem + +AI agents write code, generate assets, and produce artifacts. Most of the time, those artifacts live in the agent's working memory and disappear when the session ends. Teams that want durable outputs usually bolt on object storage — a new API surface, new authentication scheme, new workflow to manage. + +Git-native storage is different because agents already know git. Clone, branch, commit, push. The same workflow your team already uses — the same model that gives human developers version history, rollback, and collaboration — now available to agents without a terminal, without GitHub credentials, and without a human in the commit loop. + +Cloudflare Artifacts integration with Molecule AI: attach a git repository to any workspace via API. Import an existing GitHub or GitLab repo, or spin up a new Cloudflare Artifacts namespace. Agents get a git remote, a short-lived credential (auto-expiring, never stored), and a complete version history. + +The use cases that this unlocks: +- **Multi-agent pipelines**: one agent writes a branch, another reviews and approves — no manual handoff +- **Crash recovery**: start from the last commit, not a blank workspace +- **Experimentation without risk**: fork a branch, try something, discard it if it fails + +Security: SSRF protection on import URLs (https:// only, no git:// or http://), credentials stripped before storage (no long-lived tokens), graceful unavailability (503 if Artifacts not configured, no silent failures). + +Git for agents — without the terminal. + +→ [Read the integration guide](https://docs.molecule.ai/docs/guides/cloudflare-artifacts) + +#MoleculeAI #Cloudflare #AIAgents #DevOps #GitOps + +--- + +## Reddit Post (r/LocalLLaMA or r/MachineLearning) + +``` +Git for agents — without the terminal. + +Cloudflare Artifacts + Molecule AI shipped today. Here's what it means: + +Attach a git repository to any Molecule AI workspace via API. Your agent gets a git URL, a short-lived credential (auto-expiring, never stored), and a complete version history — without GitHub credentials on every container. + +Three things this unlocks: + +1. **Multi-agent pipelines without manual handoff**: Agent A writes a branch, Agent B reviews and approves. No copy-pasting between Slack threads. + +2. **Crash recovery without starting over**: Agent crashes mid-task? Start from the last commit, not a blank workspace. + +3. **Experimentation without risk**: Fork a branch before trying something risky. Delete the fork if it fails. Main branch stays clean. + +The integration: API-first, no terminal required, SSRF protection on import URLs, credentials never stored long-term. + +Source: github.com/Molecule-AI/molecule-core — `workspace-server/internal/handlers/artifacts.go` +``` + +--- + +## Hacker News — Show HN + +``` +Show HN: Git-native storage for AI agents — Cloudflare Artifacts + Molecule AI integration + +AI agents write code, generate configs, and produce artifacts. Most of the time those artifacts are gone when the session ends. Teams bolt on S3 or a file share — new API surface, new auth scheme, new workflow. + +Git-native storage is different: agents already know git. Clone, branch, commit, push. Cloudflare Artifacts is git-native object storage backed by Cloudflare's edge network — sub-100ms clone times, no S3 bandwidth bills. + +What we shipped: Molecule AI workspace → Cloudflare Artifacts integration. One API call to attach a git repository to any workspace. Import an existing GitHub/GitLab repo, or create a new Artifacts namespace. Agents get a short-lived git credential (auto-expiring, never stored), and a complete version history — no GitHub credentials on the container. + +Security notes: SSRF protection on import (https:// only), credentials stripped before storage, 503 on Artifacts unavailability — no silent failures. + +Use cases: multi-agent pipelines, crash recovery, experimentation without risk. Git for agents — without the terminal. + +Source: `workspace-server/internal/handlers/artifacts.go` in github.com/Molecule-AI/molecule-core +``` + +--- + +## Visual Asset Specifications + +1. **X Post 1 hook:** Screenshot of Artifacts repo attach flow — Canvas UI showing the workspace with Artifacts repo linked. Dark mode, clean. +2. **X Post 3 / LinkedIn:** Terminal output — `git clone`, commit, push sequence from inside a Molecule AI workspace. Show the commit history. +3. **All posts:** Cloudflare Artifacts logo + Molecule AI logo together as a badge/hero image. + +--- + +## Campaign Notes + +**Audience:** Platform engineers + DevOps leads (primary), developers evaluating AI agent stacks (secondary) +**Tone:** Pain-story first — lead with the problem ("three hours of work gone"), not the feature. The technology is the answer, not the hook. +**Angle:** "Git for agents" is the right framing per positioning brief, but don't lead with it in Post 1 — lead with the failure mode, then introduce the metaphor in Post 2 or 3. +**Differentiation:** No other AI agent platform has a Cloudflare Artifacts integration as of 2026-04-21. First-mover claim — monitor LangGraph/CrewAI for competitive response. +**Caveat:** Cloudflare Artifacts is in public beta — do not claim GA. "Git for agents (beta)" is the safe label. + +--- + +*PMM drafted 2026-04-23 — Issue #1480. Blog post shipped 2026-04-21; social copy delayed, now catching up.* +*Assets: screenshot of Artifacts repo attach flow + git commit terminal output needed (Custom or DevRel)* \ No newline at end of file diff --git a/docs/marketing/social/2026-04-21/social-queue.md b/docs/marketing/social/2026-04-21/social-queue.md index 6480c930a..e1955baea 100644 --- a/docs/marketing/social/2026-04-21/social-queue.md +++ b/docs/marketing/social/2026-04-21/social-queue.md @@ -81,12 +81,11 @@ Chrome DevTools MCP plus Molecule AI's governance layer: browser automation that --- ## MCP Server List Explainer -**File:** `docs/marketing/campaigns/mcp-server-list/social-copy.md` (staging, commit `0d3ad96`) -**Status:** COPY READY — awaiting visual assets + X credentials +**File:** `docs/marketing/campaigns/mcp-server-list/social-copy.md` +**⚠️ Status:** FILE MISSING — `social-copy.md` not on staging (only `assets/` directory present). Queue entry is stale. +**Action required:** Content Marketer to write social copy or confirm location. Remove or restore this entry. **Canonical URL:** `docs.molecule.ai/blog/mcp-server-list` -**Owner:** Social Media Brand | **Day:** Ready once visual assets done - -5-post X thread + LinkedIn post. Full copy on staging. +**Owner:** Content Marketer | **Day:** TBD --- @@ -115,3 +114,18 @@ Social Media Brand: hold Fly.io post until Chrome DevTools MCP Day 1 posts land, --- ## EC2 Instance Connect SSH (PR #1533) +**File:** `docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/social-copy.md` +**Status:** COPY READY — `#AgenticAI` replaced with `#AIAgents` (fix applied 2026-04-23) +**Canonical URL:** `docs.molecule.ai/blog/ec2-instance-connect-ssh` +**Owner:** Social Media Brand | **Day:** Ready once X credentials available + +Full 5-post X thread + LinkedIn post. Angle: no SSH key management, ephemeral permissions, AWS-native. Blog live (PR #1533 merged). ⚠️ Visual assets needed before publish. +--- + +## Org-Scoped API Keys (PR #1105) +**File:** `docs/marketing/social/2026-04-25-org-scoped-api-keys/social-copy.md` +**Status:** ✅ APPROVED — Marketing Lead 2026-04-21 | `#AgenticAI` replaced with `#AIAgents` (fix applied 2026-04-23) +**Canonical URL:** `docs.molecule.ai/blog/org-scoped-api-keys` +**Owner:** Social Media Brand | **Day:** 5 (2026-04-25) + +Full 5-post X thread + LinkedIn post. Angle: named, revocable, audit-attributed org API keys replacing shared ADMIN_TOKEN. Compliance + DevOps audience. ⚠️ Blog publish confirmation + visual assets needed. diff --git a/docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/social-copy.md b/docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/social-copy.md index 48b279065..311af017a 100644 --- a/docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/social-copy.md +++ b/docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/social-copy.md @@ -78,7 +78,7 @@ Status: Draft — pending Marketing Lead approval + credential availability > If you're still `ssh -i key.pem` into your agent fleet — there's a better way. > > [CTA: docs.molecule.ai/infra/workspace-terminal — pending docs publish] -> #AgenticAI #MoleculeAI #AWS #DevOps #PlatformEngineering +> #AIAgents #MoleculeAI #AWS #DevOps #PlatformEngineering --- @@ -135,7 +135,7 @@ EC2 Instance Connect SSH is live now for all CP-provisioned workspaces. **Audience:** DevOps, platform engineers, ML infrastructure teams running agents in AWS **Tone:** Practical — the IAM/audit story is the differentiator for security-conscious buyers; the "one click" story is the differentiator for developer audience **Differentiation:** No manual SSH key management vs. traditional bastion host approach -**Hashtags:** #AgenticAI #MoleculeAI #AWS #EC2InstanceConnect #PlatformEngineering #DevOps +**Hashtags:** #AIAgents #MoleculeAI #AWS #EC2InstanceConnect #PlatformEngineering #DevOps **CTA links:** docs pending (workspace-terminal.md docs need to be published) --- diff --git a/docs/marketing/social/2026-04-25-org-scoped-api-keys/social-copy.md b/docs/marketing/social/2026-04-25-org-scoped-api-keys/social-copy.md index 9ec62bf21..3070b14de 100644 --- a/docs/marketing/social/2026-04-25-org-scoped-api-keys/social-copy.md +++ b/docs/marketing/social/2026-04-25-org-scoped-api-keys/social-copy.md @@ -140,7 +140,7 @@ UTM: `?utm_source=linkedin&utm_medium=social&utm_campaign=org-scoped-api-keys` ## Campaign Notes - **Publish day:** 2026-04-25 (Day 5) -- **Hashtags:** #AgenticAI #MoleculeAI #DevOps #PlatformEngineering +- **Hashtags:** #AIAgents #MoleculeAI #DevOps #PlatformEngineering - **X platform tone:** Lead with attribution — "which agent made that call?" resonates with developer/DevOps audience - **LinkedIn platform tone:** Lead with compliance/risk — "one ADMIN_TOKEN diff --git a/docs/marketing/social/2026-04-26-phase34-ga-launch/social-copy.md b/docs/marketing/social/2026-04-26-phase34-ga-launch/social-copy.md new file mode 100644 index 000000000..ae8318bba --- /dev/null +++ b/docs/marketing/social/2026-04-26-phase34-ga-launch/social-copy.md @@ -0,0 +1,155 @@ +# Phase 34 GA Launch — Social Copy +**Campaign:** Phase 34 GA | **Features:** Tool Trace + Platform Instructions +**Publish day:** ~~2026-04-26 (Day 6 of Phase 30 social campaign)~~ → **2026-04-30 (GA day)** +**Status:** ✅ INTERNALLY CONSISTENT — awaiting Marketing Lead approval +**⚠️ TEASER VERSION:** This file is the launch-day (Apr 30) canonical copy. Fork to `2026-04-26-phase34-teaser/social-copy.md` for the Apr 26 pre-launch teaser. +**Conflicts resolved:** Platform Instructions = Enterprise plans only (confirmed via `router.go:376 AdminAuth`). Blog post was correct. Community FAQ wrong → fixed commit `6a9d52a3`. +**Source:** PRs #1686 + #1824 + blog posts `docs/blog/2026-04-23-tool-trace-*` and `docs/blog/2026-04-23-platform-instructions-governance` +**Owner:** PMM → Social Media Brand | **Canonical:** `docs.molecule.ai/blog/tool-trace-platform-instructions` + +--- + +## Angle: "See what your agent did. Enforce what it should do." + +Two separate product capabilities. One narrative: +- Tool Trace → answer the retrospective question "what did my agent actually do?" +- Platform Instructions → answer the proactive question "what should my agents be allowed to do?" +- Together → complete observability + governance loop for enterprise AI fleets + +**Lead with Tool Trace** (accessible to all audiences, available on all plans). +**Pull in Platform Instructions** (enterprise governance — Enterprise plans, available to org admins). + +--- + +## X (Twitter) — Primary thread (6 posts) + +### Post 1 — Hook (observability: the gap) +Your AI agent just ran for 20 minutes. +It returned a result. +You have no idea what it actually did in there. + +That's not a debugging failure. That's a product gap. + +Tool Trace: every tool call, every input, every output — in the response. + +→ [blog link] + +--- + +### Post 2 — What Tool Trace captures (product detail) +Each A2A response from a Molecule AI agent will carry a structured tool trace: + +→ Which tools were called (Write, Bash, Grep, MCP tools) +→ What inputs were passed (file paths, commands, prompts) +→ What came back (output preview, ~200 chars) +→ Which calls ran in parallel (run_id pairing) + +Same level of detail as a debugger trace. Embedded in the response. No extra API calls. + +→ [blog link] + +--- + +### Post 3 — Why it matters for production +When something goes wrong in an AI agent run, the question is always the same: +"What did the agent actually do?" + +Most platforms give you the result. Molecule AI gives you the trace. + +If you're running agents in production — especially anything touching code, data, or external APIs — you need this visibility before something goes wrong. + +Tool Trace drops April 30 — on all Molecule AI plans. + +→ [docs link] + +--- + +### Post 4 — The governance side (enterprise angle) +Here's the other half of Phase 34: + +Platform Instructions — governance rules enforced at the system prompt level, before every agent turn. + +No post-hoc filtering. The rule is part of what the agent is instructed to do from the first token. + +Two scopes: global (every workspace in your org) or workspace-scoped (one team, one set of rules). + +Security teams notice this architecture. + +→ [blog link] + +--- + +### Post 5 — The combination (for enterprise audience) +Tool Trace tells you what the agent did. +Platform Instructions tell it what to do before it does it. + +Run them together: write the policy once, enforce it everywhere, trace every execution. + +That's the observability + governance loop enterprise AI teams need. + +Tool Trace: all plans. +Platform Instructions: Enterprise plans. + +→ [blog link] + +--- + +### Post 6 — CTA + Phase 34 reference +Phase 34 drops April 30: Tool Trace + Platform Instructions. + +Tool Trace — every tool call, every input, every output — in every A2A response. + +Platform Instructions — org-wide and workspace-scoped governance at the system prompt level. + +If you're running AI agents in production and don't know what they're doing inside a turn — this is worth watching. + +→ [docs.molecule.ai/blog/tool-trace-platform-instructions] + +--- + +## LinkedIn — Single post + +**Title:** Two things enterprise AI teams need before they trust a production agent platform + +When you're running an AI agent fleet in production — touching code, data pipelines, customer data, or external APIs — there are two questions that come up before the first compliance review: + +1. **What did the agent actually do?** Not just the output. The full sequence of tool calls, inputs, and results. If something goes wrong, you need to reconstruct what happened. + +2. **Can we enforce what the agent should do at the platform level?** Before the first turn executes. Not a filter — a governance rule baked into the agent's instruction set. + +Most platforms answer neither question well. Some answer one. Phase 34 changes that: + +**Tool Trace** — embedded in every A2A response (April 30). Every tool call, input, output preview, parallel call grouping, and timing metadata. The full trace without an extra API call. On all plans. + +**Platform Instructions** — configurable rules scoped globally or per-workspace (April 30). Enforced before every agent turn. The rule is part of the system prompt, not a filter applied after. Available to org admins on Enterprise plans. + +Together: write the policy once, enforce it everywhere, trace every execution. + +If you're scaling AI agents in production and don't have this — it's the gap worth closing. + +→ [blog link] + +#MoleculeAI #AIAgents #AgentPlatform #EnterpriseAI #AIGovernance #DevOps + +--- + +## Visual Asset Requirements + +1. **Tool Trace screenshot** — A2A response payload showing `Message.metadata.tool_trace` array. Clean, dark theme. Show 3-4 entries with tool name + output preview visible. +2. **Platform Instructions diagram** — System prompt structure: global instructions + workspace instructions → prepended to system prompt → agent reasoning. Clean architecture diagram, not a screenshot. +3. **LinkedIn cover** — Split card: left side "What did the agent do?" with trace snippet / right side "What should it do?" with instruction snippet. Dark mode, molecule navy. + +--- + +## Campaign notes + +**Audience:** DevOps + platform engineers (X primary), enterprise IT/security (LinkedIn primary) +**Tone:** Concrete + practical — don't announce, show the output +**Angle:** Lead with observability (Tool Trace) — accessible to all audiences. Platform Instructions as the enterprise pull-through. +**Differentiation:** Tool Trace is embedded in every A2A response — no extra polling, no separate observability stack to integrate. +**CTA:** `docs.molecule.ai/blog/tool-trace-platform-instructions` +**Coordinate with:** Phase 30 social campaign Day 6. Tool Trace is the natural continuation of the observability story from EC2 Console Output (Day 4) → Org API Keys (Day 5) → Tool Trace + Platform Instructions (Day 6). + +--- + +*PMM drafted 2026-04-23 — Phase 34 GA launch social. Pre-write pending Marketing Lead approval.* \ No newline at end of file diff --git a/docs/marketing/social/2026-04-26-phase34-teaser/social-copy.md b/docs/marketing/social/2026-04-26-phase34-teaser/social-copy.md new file mode 100644 index 000000000..522c25b35 --- /dev/null +++ b/docs/marketing/social/2026-04-26-phase34-teaser/social-copy.md @@ -0,0 +1,156 @@ +# Phase 34 Pre-Launch Teaser — Social Copy +**Campaign:** Phase 34 GA | **Features:** Tool Trace + Platform Instructions +**Publish day:** 2026-04-26 (pre-launch teaser, T-4 before GA) +**Status:** ✅ INTERNALLY CONSISTENT — forward-looking framing only (no "live/available now" language) +**Purpose:** Teaser copy — builds anticipation, names features, drops date. Does NOT claim current availability. +**Forked from:** `../2026-04-26-phase34-ga-launch/social-copy.md` (launch-day canonical) +**Conflicts resolved:** Platform Instructions = Enterprise plans only (confirmed via `router.go:376 AdminAuth`). Blog post was correct. Community FAQ wrong → fixed commit `6a9d52a3`. +**Source:** PRs #1686 + #1824 + blog posts `docs/blog/2026-04-23-tool-trace-*` and `docs/blog/2026-04-23-platform-instructions-governance` +**Owner:** PMM → Social Media Brand | **Canonical:** `docs.molecule.ai/blog/tool-trace-platform-instructions` + +--- + +## Angle: "See what your agent did. Enforce what it should do." + +Two separate product capabilities. One narrative: +- Tool Trace → answer the retrospective question "what did my agent actually do?" +- Platform Instructions → answer the proactive question "what should my agents be allowed to do?" +- Together → complete observability + governance loop for enterprise AI fleets + +**Lead with Tool Trace** (accessible to all audiences, available on all plans). +**Pull in Platform Instructions** (enterprise governance — Enterprise plans, available to org admins). + +--- + +## X (Twitter) — Primary thread (6 posts) + +### Post 1 — Hook (observability: the gap) +Your AI agent just ran for 20 minutes. +It returned a result. +You have no idea what it actually did in there. + +That's not a debugging failure. That's a product gap. + +Tool Trace: every tool call, every input, every output — in the response. + +→ [blog link] + +--- + +### Post 2 — What Tool Trace captures (product detail) +Each A2A response from a Molecule AI agent will carry a structured tool trace: + +→ Which tools were called (Write, Bash, Grep, MCP tools) +→ What inputs were passed (file paths, commands, prompts) +→ What came back (output preview, ~200 chars) +→ Which calls ran in parallel (run_id pairing) + +Same level of detail as a debugger trace. Embedded in the response. No extra API calls. + +→ [blog link] + +--- + +### Post 3 — Why it matters for production +When something goes wrong in an AI agent run, the question is always the same: +"What did the agent actually do?" + +Most platforms give you the result. Molecule AI gives you the trace. + +If you're running agents in production — especially anything touching code, data, or external APIs — you need this visibility before something goes wrong. + +Tool Trace drops April 30 — on all Molecule AI plans. + +→ [docs link] + +--- + +### Post 4 — The governance side (enterprise angle) +Here's the other half of Phase 34: + +Platform Instructions — governance rules enforced at the system prompt level, before every agent turn. + +No post-hoc filtering. The rule is part of what the agent is instructed to do from the first token. + +Two scopes: global (every workspace in your org) or workspace-scoped (one team, one set of rules). + +Security teams notice this architecture. + +→ [blog link] + +--- + +### Post 5 — The combination (for enterprise audience) +Tool Trace tells you what the agent did. +Platform Instructions tell it what to do before it does it. + +Run them together: write the policy once, enforce it everywhere, trace every execution. + +That's the observability + governance loop enterprise AI teams need. + +Tool Trace: all plans. +Platform Instructions: Enterprise plans. + +→ [blog link] + +--- + +### Post 6 — CTA + Phase 34 reference +Phase 34 drops April 30: Tool Trace + Platform Instructions. + +Tool Trace — every tool call, every input, every output — in every A2A response. + +Platform Instructions — org-wide and workspace-scoped governance at the system prompt level. + +If you're running AI agents in production and don't know what they're doing inside a turn — this is worth watching. + +→ [docs.molecule.ai/blog/tool-trace-platform-instructions] + +--- + +## LinkedIn — Single post + +**Title:** Two things enterprise AI teams need before they trust a production agent platform + +When you're running an AI agent fleet in production — touching code, data pipelines, customer data, or external APIs — there are two questions that come up before the first compliance review: + +1. **What did the agent actually do?** Not just the output. The full sequence of tool calls, inputs, and results. If something goes wrong, you need to reconstruct what happened. + +2. **Can we enforce what the agent should do at the platform level?** Before the first turn executes. Not a filter — a governance rule baked into the agent's instruction set. + +Most platforms answer neither question well. Some answer one. Phase 34 changes that: + +**Tool Trace** — embedded in every A2A response (April 30). Every tool call, input, output preview, parallel call grouping, and timing metadata. The full trace without an extra API call. On all plans. + +**Platform Instructions** — configurable rules scoped globally or per-workspace (April 30). Enforced before every agent turn. The rule is part of the system prompt, not a filter applied after. Available to org admins on Enterprise plans. + +Together: write the policy once, enforce it everywhere, trace every execution. + +If you're scaling AI agents in production and don't have this — it's the gap worth closing. + +→ [blog link] + +#MoleculeAI #AIAgents #AgentPlatform #EnterpriseAI #AIGovernance #DevOps + +--- + +## Visual Asset Requirements + +1. **Tool Trace screenshot** — A2A response payload showing `Message.metadata.tool_trace` array. Clean, dark theme. Show 3-4 entries with tool name + output preview visible. +2. **Platform Instructions diagram** — System prompt structure: global instructions + workspace instructions → prepended to system prompt → agent reasoning. Clean architecture diagram, not a screenshot. +3. **LinkedIn cover** — Split card: left side "What did the agent do?" with trace snippet / right side "What should it do?" with instruction snippet. Dark mode, molecule navy. + +--- + +## Campaign notes + +**Audience:** DevOps + platform engineers (X primary), enterprise IT/security (LinkedIn primary) +**Tone:** Concrete + practical — don't announce, show the output +**Angle:** Lead with observability (Tool Trace) — accessible to all audiences. Platform Instructions as the enterprise pull-through. +**Differentiation:** Tool Trace is embedded in every A2A response — no extra polling, no separate observability stack to integrate. +**CTA:** `docs.molecule.ai/blog/tool-trace-platform-instructions` +**Coordinate with:** Phase 30 social campaign Day 6. Tool Trace is the natural continuation of the observability story from EC2 Console Output (Day 4) → Org API Keys (Day 5) → Tool Trace + Platform Instructions (Day 6). + +--- + +*PMM drafted 2026-04-23 — Phase 34 GA launch social. Forward-looking teaser version forked 2026-04-24 for Apr 26 pre-launch use. Launch-day version at `../2026-04-26-phase34-ga-launch/social-copy.md`.* diff --git a/docs/marketing/social/2026-04-30-phase-34-ga-launch/social-copy.md b/docs/marketing/social/2026-04-30-phase-34-ga-launch/social-copy.md new file mode 100644 index 000000000..ff6cfe3c7 --- /dev/null +++ b/docs/marketing/social/2026-04-30-phase-34-ga-launch/social-copy.md @@ -0,0 +1,91 @@ +# Phase 34 GA Launch — Social Copy +**Publish day:** 2026-04-30 (Partner API Keys GA) +**Status:** APPROVED — GA language confirmed per community FAQ and updated positioning brief (2026-04-23) +**Issue refs:** #1829 (Tool Trace/Platform Instructions thread already posted Apr 23) + +--- + +## X / Twitter Thread (5 tweets) — Phase 34 GA + +**Tweet 1 — Announcement hook** +``` +Partner API Keys are generally available today. + +If you're building a marketplace, a CI/CD platform, or any product on top of Molecule AI — you can now programmatically create and manage Molecule AI orgs via API. + +No browser session required. No manual setup. API-first from day one. 🧵 +``` + +**Tweet 2 — What it enables** +``` +What mol_pk_* keys unlock: + +→ POST /cp/admin/partner-keys — provision a Molecule AI org for your customer +→ DELETE /cp/admin/partner-keys/:id — tear it down, billing stops immediately +→ Org-scoped isolation — a compromised key can't escape its org boundary + +Ephemeral test orgs per PR. Clean teardown on merge. +``` + +**Tweet 3 — First-mover claim** +``` +We believe Molecule AI is the first agent platform with a first-class partner provisioning API. + +LangGraph Cloud: per-seat SaaS licensing. +CrewAI: marketplace listing. +Molecule AI: an API to build either — programmatically, at scale. +``` + +**Tweet 4 — Phase 34 stack** +``` +Phase 34 also shipped this week: + +• Tool Trace — execution record in every A2A response +• Platform Instructions — org-level system prompt via API +• SaaS Federation v2 — multi-tenant control plane with cleaner org isolation + +Observability + governance. In one stack. +``` + +**Tweet 5 — CTA** +``` +Partner API Keys: GA today. + +If you're a platform builder, marketplace operator, or running CI/CD on Molecule AI — this is your release. + +Docs → https://docs.molecule.ai/api/partner-keys +Partner program → #partner-program on Discord +``` + +--- + +## LinkedIn Post (~250 words) + +**Partner API Keys are generally available today.** + +Starting today, any platform, marketplace, or CI/CD pipeline can programmatically create and manage Molecule AI organizations via API — no browser session, no manual setup, no shared credentials. + +The core API is straightforward: + +- `POST /cp/admin/partner-keys` — provision a new Molecule AI org for your customer or pipeline +- `DELETE /cp/admin/partner-keys/:id` — tear it down when you're done; billing stops immediately +- Keys are org-scoped by design — a compromised `mol_pk_*` key cannot touch resources outside its org + +This is infrastructure-first agent orchestration. You provision the platform; your customers use it. The model is closer to Stripe's API or Twilio's account provisioning than to a SaaS seat license. + +Phase 34 also delivered Tool Trace (full execution record in every A2A response), Platform Instructions (org-level system prompt via API), and SaaS Federation v2 (multi-tenant control plane with cleaner org isolation). Together, they give platform builders observability and governance as native platform primitives — not bolt-on integrations. + +We believe this makes Molecule AI the first agent platform with a first-class partner provisioning API. + +If you're building on top of Molecule AI — or evaluating agent infrastructure for your platform — Partner API Keys GA is the milestone to look at. + +Docs: https://docs.molecule.ai/api/partner-keys +Partner program: join `#partner-program` in the Molecule AI Discord + +--- + +## Publish notes +- Schedule for 2026-04-30 09:00 UTC (GA day) +- Pin tweet 1 for 24h after posting +- Cross-post LinkedIn within 1h of X thread +- Tag @MoleculeAI in all posts diff --git a/docs/marketing/social/SOCIAL-QUEUE-STATUS.md b/docs/marketing/social/SOCIAL-QUEUE-STATUS.md new file mode 100644 index 000000000..e16109512 --- /dev/null +++ b/docs/marketing/social/SOCIAL-QUEUE-STATUS.md @@ -0,0 +1,176 @@ +# Marketing Social Queue — Status Tracker +**Owner:** PMM | **Last updated:** 2026-04-24 late-cycle (this tick) +**Purpose:** Single source of truth for all social copy status across campaigns. + +--- +> **2026-04-24 late-cycle update:** Canonical Apr 26 copy forked into two versions: +> - `2026-04-26-phase34-teaser/social-copy.md` — **forward-looking only**, no "live/available now" language. Teaser framing: "drops April 30". PM-approved use. +> - `2026-04-26-phase34-ga-launch/social-copy.md` — **launch-day canonical** (Apr 30). All present-tense availability language intact. File header flagged. +> - **Marketing Lead: approve `...teaser/` copy for Apr 26 publish. File is ready.** +> +> **2026-04-24 reconciliation:** Two Apr 26 social copy files existed — the PMM-approved canonical `2026-04-26-phase34-ga-launch/social-copy.md` (6 posts, internally consistent, conflict-resolved) and the older ML draft `tool-trace-platform-instructions-social-copy.md` (5 posts, different phrasing). PMM version retained as canonical. ML draft archived to `archived/2026-04-26-tool-trace-platform-instructions-ml-draft.md`. Marketing Lead: choose phrasing variant before publishing. + +--- + +## Phase 34 GA Launch (April 30, 2026) + +### 2026-04-26 — Phase 34 GA: Tool Trace + Platform Instructions ✅ TEASER COPY READY — forward-looking framing only +- **File:** `2026-04-26-phase34-teaser/social-copy.md` ← publish from here (Apr 26) +- **Launch-day file:** `2026-04-26-phase34-ga-launch/social-copy.md` (preserve for Apr 30) +- **Status:** ✅ FORWARD-LOOKING FRAMING ONLY — no "live"/"available now"/"ships today" language. PM Condition A met. +- **Conflicts resolved:** Platform Instructions = Enterprise plans only (per `router.go:376 AdminAuth`). Blog post was correct. Community FAQ wrong → fixed (commit `6a9d52a3`). +- **Content:** 6-post X thread + LinkedIn post +- **Owner:** PMM → Marketing Lead (approval) → Social Media Brand (execution) +- **Blocking:** Marketing Lead approval (X credentials restored — no longer a blocker) +- **Canonical:** `docs.molecule.ai/blog/tool-trace-platform-instructions` + +### 2026-04-30 — Phase 34 GA: Partner API Keys ✅ APPROVED (Marketing Lead) +- **File:** `2026-04-30-phase-34-ga-launch/social-copy.md` +- **Status:** APPROVED by Marketing Lead 2026-04-23. GA language confirmed (community FAQ + updated positioning brief). Ready for Social Media Brand execution. +- **Content:** 5-post X thread +- **Owner:** Social Media Brand +- **Blocking:** X credentials +- **Canonical:** `docs.molecule.ai/blog/partner-api-keys` +- **Note:** Issue #1829 — Tool Trace/Platform Instructions thread already posted Apr 23. Partner API Keys thread targets Apr 30 GA date. + +--- + +## Phase 30 Social Campaign — Archive (April 21–23, past) + +### 2026-04-21 — Chrome DevTools MCP 🟡 PAST — posting status unknown +- **File:** `2026-04-21-chrome-devtools-mcp/social-copy.md` +- **Status:** Copy was ready. Whether it was posted is unconfirmed — X credentials missing blocked all Phase 30 publishing. +- **Owner:** PMM → Social Media Brand + +### 2026-04-21 — Cloudflare Artifacts 🟡 PAST — posting status unknown +- **File:** `2026-04-21-cloudflare-artifacts/social-copy.md` +- **Status:** PMM pre-write complete. Whether it was posted is unconfirmed. +- **Owner:** PMM → Social Media Brand + +### 2026-04-22 — EC2 Instance Connect SSH 🟡 PAST — posting status unknown +- **File:** `2026-04-22-ec2-instance-connect-ssh/social-copy.md` +- **Status:** PMM positioning approved (GH #1637). DevRel screenshot + blog still outstanding. Whether posted is unconfirmed. +- **Owner:** PMM → Social Media Brand → DevRel + +--- + +## Phase 30 Social Campaign — Active (April 24–25) + +### 2026-04-24 — EC2 Console Output ✅ APPROVED (Marketing Lead) [T-6: publish today] +- **File:** `2026-04-24-ec2-console-output/social-copy.md` +- **Status:** Approved by Marketing Lead 2026-04-22. Ready for Social Media Brand execution. +- **Content:** 4-post X thread + LinkedIn +- **Owner:** Social Media Brand +- **Blocking:** X credentials + visual asset (`ec2-console-output-canvas.png`, 1200×800 dark mode) +- **Campaign position:** Day 4 of Phase 30 social campaign + +### 2026-04-25 — Org-Scoped API Keys ✅ APPROVED (Marketing Lead) [T-5: publish tomorrow] +- **File:** `2026-04-25-org-scoped-api-keys/social-copy.md` +- **Status:** Approved by Marketing Lead 2026-04-21. Ready for Social Media Brand execution. +- **Content:** 5-post X thread + LinkedIn +- **Owner:** Social Media Brand +- **Blocking:** X credentials + visual assets (Canvas UI screenshot, before/after credential model, audit log terminal output) +- **Campaign position:** Day 5 of Phase 30 social campaign + +--- + +## Staged on `origin/staging` (unreviewed by PMM) + +### MCP Server List — Day 1 ✅ COPY READY +- **File:** `docs/marketing/campaigns/mcp-server-list/social-copy.md` (on staging, commit `0d3ad96`) +- **Status:** Copy complete. Awaiting visual assets + X credentials. +- **Content:** 5-post X thread + LinkedIn +- **Canonical URL:** `docs.molecule.ai/blog/mcp-server-list` +- **Owner:** Social Media Brand +- **Blocking:** Visual assets + X credentials + +### Discord Adapter — Day 2 ✅ COPY READY +- **File:** `discord-adapter-social-copy.md` (on staging) +- **Status:** Copy complete. Awaiting Marketing Lead Day 2 approval + X credentials + visual assets. +- **Content:** 4 X variants + LinkedIn + Reddit + HN copy +- **Canonical URL:** `docs.molecule.ai/blog/discord-adapter` (live, PR #1301 merged) +- **Owner:** Social Media Brand → Marketing Lead (Day 2 approval) + +### A2A Enterprise Deep-Dive — Day T+1 ⚠️ ON STAGING ONLY +- **File:** `docs/marketing/campaigns/a2a-enterprise-deep-dive/social-copy.md` (on staging only, not main) +- **Status:** COPY READY (PMM-approved, 72h window). Not on origin/main. +- **Content:** 4-post X thread + LinkedIn +- **Canonical URL:** `docs.molecule.ai/blog/a2a-v1-agent-platform` +- **Owner:** PMM → Social Media Brand +- **Blocking:** X credentials + needs to be cherry-picked to origin/main for execution +- **Note:** File needs to be on origin/main before Social Media Brand can execute. Executor must confirm staging access, or file must be cherry-picked to main. + +--- + +## Held / Pending Decision + +### Fly.io Deploy Anywhere — Stale (T+6) +- **File:** `fly-deploy-anywhere-social-copy.md` (on staging) +- **Status:** PMM recommendation: Option A (retrospective framing). Decision memo: `fly-deploy-anywhere-decision-memo.md` +- **Campaign position:** Phase 30 social campaign catch-up +- **Decision needed:** Marketing Lead confirmation on Option A framing +- **Blocking:** Marketing Lead decision + X credentials + +### Phase 30 (original) — MERGED +- **File:** `phase30-social-copy.md` +- **Status:** MERGED to origin/main. Awaiting Marketing Lead publish approval. +- **Owner:** PMM → Social Media Brand +- **Blocking:** Marketing Lead publish approval + X credentials + +--- + +## Cross-Cutting Blockers (all human-gated) + +| Blocker | Affects | +|---|---| +| X credentials (`X_ACCESS_TOKEN` + `X_ACCESS_TOKEN_SECRET`) | ALL posts — Social Media Brand cannot publish anything | +| Marketing Lead publish approvals | Chrome DevTools MCP, Phase 30, Fly.io, Discord Day 2 | +| DevRel terminal screenshot (PR #1545) | EC2 Instance Connect SSH | +| Content Marketer blog post (#1546) | EC2 Instance Connect SSH | +| Visual assets (Canvas screenshots, diagrams) | EC2 Console Output, Org-Scoped API Keys, Chrome DevTools MCP | + +--- + +## Assets: Visual Requirements by Post + +| Post | Asset | Source | Status | +|---|---|---|---| +| Chrome DevTools MCP | 3-item checklist graphic | Custom (Lighthouse/Regression/Auth) | Needed | +| Chrome DevTools MCP | Fleet diagram | Reuse `marketing/assets/phase30-fleet-diagram.png` | Ready | +| EC2 Instance Connect SSH | Canvas terminal screenshot | DevRel (PR #1545) | Blocked | +| EC2 Console Output | Canvas screenshot (dark, 1200×800) | Custom | Needed | +| Org-Scoped API Keys | Canvas Org API Keys UI screenshot | Custom | Needed | +| Org-Scoped API Keys | Before/after credential model graphic | Custom | Needed | +| Org-Scoped API Keys | Audit log terminal output | Custom | Needed | +| MCP Server List | Campaign visual | Custom | Needed | +| Discord Adapter | Multi-channel diagram | Custom | Needed | + +--- + +*PMM compiled 2026-04-23. Consolidated from multiple inline social-queue files into single status tracker.* +*Marketing Lead: approve queue items to unblock Social Media Brand for execution once X credentials are restored.* + +--- + +## Battlecards (complete) + +| Battlecard | Phase | Status | Pushed | +|---|---|---|---| +| Phase 30 Remote Workspaces | 30 | ✅ PMM DRAFT | `marketing/phase-34-launch-prep` (2026-04-23) | +| Phase 32 SaaS Federation v2 | 32 | ✅ PMM DRAFT | `marketing/phase-34-launch-prep` | +| Phase 34 Partner API Keys | 34 | ✅ PMM DRAFT | `marketing/phase-34-launch-prep` | + +--- + +## Research Files (complete this cycle) + +| File | Status | Blocking | +|---|---|---| +| `briefs/saas-fed-v2-what-shipped.md` | ⚠️ NO IMPLEMENTATION FOUND — PM must confirm scope | PM confirmation before battlecard copy | +| `briefs/partner-api-keys-rate-limits-note.md` | ✅ 60 req/min per mol_pk_* key (default, configurable) | PM confirm Go implementation | +| `launches/partner-onboarding-guide.md` | ✅ Tier names confirmed (Partner + Enterprise) — blog post live | Go implementation + billing endpoint TBD | +| `launches/phase-34-community-announcement.md` | ✅ Reviewed 2026-04-24 — no SaaS Fed v2 section found (tracker flag was stale) | Ready for Marketing Lead publish | + +--- + +*PMM compiled 2026-04-23. Updated 2026-04-23 late cycle: research files section added.* diff --git a/docs/marketing/social/archived/2026-04-26-tool-trace-platform-instructions-ml-draft.md b/docs/marketing/social/archived/2026-04-26-tool-trace-platform-instructions-ml-draft.md new file mode 100644 index 000000000..95792eda3 --- /dev/null +++ b/docs/marketing/social/archived/2026-04-26-tool-trace-platform-instructions-ml-draft.md @@ -0,0 +1,102 @@ +# Tool Trace + Platform Instructions — Social Copy +**Feature:** PR #1686 — Tool Trace + Platform Instructions +**Merged:** 2026-04-23 +**Status:** DRAFT — ready for Social Media Brand to publish +**Issue:** #1829 + +--- + +## X / Twitter Thread (5 tweets) + +**Tweet 1 — Hook** +``` +You can now see exactly what your agents did. + +Every A2A call in Molecule AI now records a tool trace — tool name, input, output preview — for every tool your agents called. + +No more guessing what happened in a multi-agent run. 🧵 +``` + +**Tweet 2 — Tool Trace mechanics** +``` +Here's what tool_trace looks like in a response: + +{ + "tool_trace": [ + { "tool_name": "web_search", + "input": {"query": "molecule ai"}, + "output_preview": "Molecule AI is..." }, + { "tool_name": "write_file", + "input": {"path": "report.md"}, + "output_preview": "File written (412 bytes)" } + ] +} + +Parallel calls supported via run_id pairing. Capped at 200 entries. +``` + +**Tweet 3 — Platform Instructions** +``` +Also shipped: Platform Instructions. + +One API call sets system-level context for your entire org: + +PUT /cp/platform-instructions +{ "instructions": "Tag every response with workspace ID." } + +Every agent in your org inherits it. No touching individual workspace configs. +``` + +**Tweet 4 — Combined value** +``` +Together: Platform Instructions sets what your agents know going in. Tool Trace proves what they did coming out. + +Observability + control at the platform layer — not bolted on after the fact. +``` + +**Tweet 5 — CTA** +``` +Tool Trace is live in every A2A response today. +Platform Instructions: PUT /cp/platform-instructions + +Both ship as part of Phase 34 — Partner API Keys GA April 30. + +Docs → https://docs.molecule.ai +``` + +--- + +## LinkedIn Post (~200 words) + +**Two platform-level upgrades shipped in Molecule AI today.** + +**Tool Trace** gives you full visibility into every tool call your agents make. Every A2A response now includes a `tool_trace` — the tool name, the input it received, and a preview of the output it returned. Parallel tool calls are tracked via `run_id` pairing, so concurrent agent activity doesn't get mixed up. + +When something goes wrong in a production multi-agent workflow, you no longer have to reconstruct what happened from logs. The trace is in the response, stored in `activity_logs.tool_trace`, and queryable. + +**Platform Instructions** lets org admins configure system-level context via a single API call. Set shared instructions once — every agent in your org inherits them. Useful for compliance requirements, house-style rules, or shared context that all your agents need without touching individual workspace configs. + +Both features are live today. They're part of Phase 34 — which also includes Partner API Keys (GA April 30), the programmatic org provisioning API for platform builders and marketplace integrations. + +If you're building on top of Molecule AI, Phase 34 is the release to watch. + +→ https://docs.molecule.ai + +--- + +## TTS Audio Script (15–20 sec) + +> "Molecule AI just shipped Tool Trace — every A2A call now records what tools your agents used, the inputs they sent, and a preview of the output. Plus Platform Instructions: configure system-level context for your entire org via API. Full observability and control for your multi-agent stack." + +--- + +## Publish Checklist +- [ ] Post X thread (Tweet 1 first, reply-thread the rest) +- [ ] Post LinkedIn version +- [ ] Generate and attach TTS audio clip +- [ ] Log post URLs here after publishing +- [ ] Close issue #1829 + +--- + +*Drafted by Marketing Lead 2026-04-23 — Social Media Brand to publish when workspace recovers.* diff --git a/docs/marketing/social/fly-deploy-anywhere-decision-memo.md b/docs/marketing/social/fly-deploy-anywhere-decision-memo.md new file mode 100644 index 000000000..3cd132d0b --- /dev/null +++ b/docs/marketing/social/fly-deploy-anywhere-decision-memo.md @@ -0,0 +1,97 @@ +# Fly.io Deploy Anywhere — Campaign Decision Memo +**Campaign:** Fly.io Deploy Anywhere | **Blog:** `docs/blog/2026-04-17-deploy-anywhere/index.md` +**Canonical URL:** `moleculesai.app/blog/deploy-anywhere` +**Status:** PMM DECISION MEMO — awaiting Marketing Lead confirmation +**File:** `docs/marketing/social/fly-deploy-anywhere-social-copy.md` (on staging) +**Owner:** PMM | **Blocking:** Marketing Lead framing decision + +--- + +## Context + +Blog post shipped April 17, 2026. Social copy drafted by PMM (2026-04-21) and placed on staging. As of 2026-04-23, this campaign is **6 days stale** with no Marketing Lead framing confirmation. + +Phase 30 positioning brief (Content Marketer, 2026-04-22) confirmed three approved lines: +- "One canvas, every agent" (fleet visibility — social headline) +- "Deploy agents anywhere, manage them from one place" (deployment flexibility — SEO sub-message) +- "A2A is solved. A2A governance is not." (competitive differentiation) + +--- + +## Option A — Retrospective Campaign (PMM recommendation) + +**Approach:** Frame as a retrospective launch post — "We shipped this two weeks ago, here's why it matters now." + +**Rationale:** +- The feature is live and working. A retrospective framing normalizes the delay. +- The deployment flexibility angle ("Docker, Fly.io, or control plane — one config change") is evergreen and ties directly to Phase 30 positioning. +- No new timing dependency — no need to wait for a Fly Machines pricing moment. +- Cross-campaign link: naturally stacks with Chrome DevTools MCP (both self-hosted/remote angle). + +**Social angle for Option A:** +> "Two weeks ago, Molecule AI workspaces started running on Fly Machines, Docker, or your control plane — same agent code, same canvas, same A2A. No migration tax." + +**CTA:** Link to `moleculesai.app/blog/deploy-anywhere` + +--- + +## Option B — Hold for Fly Machines Pricing/GA Moment + +**Approach:** Park until Fly.io announces Fly Machines pricing updates or a GA milestone. + +**Rationale:** +- If Fly.io ships pricing changes, a coordinated post gets more traction. +- Avoids the "6-day stale" feel of a retrospective. + +**Risks:** +- No confirmed Fly Machines pricing date. +- Campaign remains stale indefinitely if no pricing moment materializes. +- Stale campaigns clutter the queue and delay Social Media Brand execution. + +--- + +## Option C — Drop from Active Queue + +**Approach:** Remove from active queue. Archive the copy. + +**Rationale:** +- Phase 30 campaign is wrapping (Days 1–5 complete). +- Phase 34 GA is April 30 — focus should shift there. +- Fly.io copy competes for attention with higher-priority Phase 34 posts. + +**Risks:** +- If Fly.io relevance picks up (new pricing, new integration), the copy needs to be refreshed. + +--- + +## PMM Recommendation + +**Option A — Retrospective framing.** + +Rationale: +1. The deployment flexibility angle is evergreen and directly tied to Phase 30 positioning. +2. A retrospective launch post ("we shipped this two weeks ago") is a valid campaign type — common for features that ship quietly. +3. The Fly.io angle ("pay per use, scale to zero") appeals to indie devs and startup infra leads — a segment not well-covered in Phase 30 posts. +4. Social Media Brand has capacity — they're blocked on X credentials anyway. Having approved copy queued is better than having nothing. +5. No new timing dependency required. + +**If Option A is approved:** Social queue status updated to APPROVED. Social Media Brand executes once X credentials restored. + +--- + +## Social Copy Reference + +File: `docs/marketing/social/fly-deploy-anywhere-social-copy.md` (on staging) + +| Platform | Versions | Status | +|---|---|---| +| X | A (infra freedom), B (dev pain), C (multi-cloud), D (indie dev) | PMM draft complete | +| LinkedIn | Full post (~120 words) | PMM draft complete | +| Assets | Comparison card, terminal screenshot, backend diagram | Needed | + +Hashtags: `#MoleculeAI #FlyIO #AIInfrastructure #AgentPlatform #DevOps #AIAgents #A2A #RemoteWorkspaces` + +--- + +*PMM decision memo 2026-04-23 — awaiting Marketing Lead confirmation* +*Marketing Lead: respond to this memo to unblock or deprioritize Fly.io social copy* diff --git a/marketing/devrel/community-reddit-hn-handoff.md b/marketing/devrel/community-reddit-hn-handoff.md new file mode 100644 index 000000000..5384f1797 --- /dev/null +++ b/marketing/devrel/community-reddit-hn-handoff.md @@ -0,0 +1,43 @@ +# Discord Adapter Day 2 — Reddit + HN Community Copy Handoff +**Owner:** Social Media Brand | **Status:** READY TO POST +**Updated:** 2026-04-21 by Marketing Lead + +--- + +## Context + +Issue #1383 (Discord adapter Day 2 community campaign). Blog post is live on `docs/blog/2026-04-21-discord-adapter/` (staging branch, slug: `discord-adapter-launch`). Reddit + HN copy bodies are in GH #1383 — copy is complete, no drafting needed. + +Social Media Brand owns posting and timing. Fill `[BLOG_URL]` before publishing. + +--- + +## Copy Summary (from GH #1383) + +### r/LocalLLaMA post body +- Angle: webhook vs traditional bot setup complexity +- Audience: technical, local AI/dev community +- Blog URL: `[BLOG_URL]` — fill before posting + +### Hacker News — Show HN format +- 2–3 paragraphs, no fluff +- Technical signal, clean format +- Blog vs PR link decision: `[BLOG_URL]` vs `GitHub PR #656` — poster chooses + +--- + +## Blog URL +Live blog: `https://docs.molecule.ai/blog/discord-adapter-launch` ✅ CONFIRMED LIVE (commit 184054a) +Or: `https://docs.molecule.ai/blog/2026-04-22-discord-adapter` +→ replace `[BLOG_URL]` placeholder in both posts + +--- + +## Coordination +- **Social Media Brand:** owns Reddit + HN posting + timing +- **Blog URL:** fill before publishing +- **Timing:** Day 2 of Discord adapter launch (2026-04-22 or Day 2 equivalent) + +--- + +*Source: GH issue #1383* diff --git a/marketing/devrel/screencast-production-handoff.md b/marketing/devrel/screencast-production-handoff.md new file mode 100644 index 000000000..88e092aa9 --- /dev/null +++ b/marketing/devrel/screencast-production-handoff.md @@ -0,0 +1,90 @@ +# Screencast Production Handoff — Issue #1303 +**Owner:** DevRel Engineer | **Status:** READY TO PRODUCE +**Updated:** 2026-04-21 by Marketing Lead + +--- + +## Background + +Issue #1303 ("Phase 30: record 4 launch screencasts") is ready for production. All storyboards are complete. This is the standing dispatch — DevRel Engineer owns recording and production. + +**Hero video assembly** is a separate job owned by Content Marketer. See `phase30-video-production.md`. + +--- + +## Your 4 Screencasts + +### 1. EC2 Console Output Demo +**Source:** PR #68 | **Duration:** ~60s | **Format:** Canvas UI → terminal +- Storyboard: `marketing/demos/failed-workspace-ec2-console-demo.md` +- Reference: Canvas screenshot (dark zinc theme, failed workspace card + EC2 Console tab) +- TTS: 30s, use `phase30-announce.mp3` cadence as reference +- End card: `workspace-server/internal/handlers/container_files.go — molecule-core#1178` + +### 2. Cloudflare Artifacts Demo +**Source:** PR #641 | **Duration:** ~60s | **Format:** Terminal-led, dark zinc theme +- Storyboard: `marketing/demos/cloudflare-artifacts/storyboard.md` +- TTS narration: `marketing/demos/cloudflare-artifacts/narration.mp3` ✅ (already recorded, use directly) +- Reference: Fleet diagram (`marketing/assets/phase30-fleet-diagram.png`) +- End card: `workspace-server/internal/handlers/artifacts.go — molecule-core#641` + +### 3. MemoryInspectorPanel Demo +**Source:** PR #65 | **Duration:** ~60s | **Format:** Canvas UI + browser +- Storyboard: `marketing/demos/memory-inspector-panel/storyboard.md` +- Reference: Canvas screenshot — MemoryInspectorPanel with 10+ entries, similarity scores visible +- Source component: `canvas/src/components/MemoryInspectorPanel.tsx` +- End card: `canvas/src/components/MemoryInspectorPanel.tsx — molecule-core#1127` +- Note: Canvas needs 10+ memory entries pre-seeded (mock data fine) + +### 4. Snapshot Secret Scrubber Demo +**Source:** PR #63 | **Duration:** ~60s | **Format:** Terminal + code walkthrough +- Storyboard: `marketing/demos/snapshot-scrub/storyboard.md` +- Reference: Terminal screenshot — `scrub_content()` function with test output +- Source: `workspace-server/internal/workspace/snapshot_scrub.py` +- End card: `workspace-server/internal/workspace/snapshot_scrub.py — molecule-core#977` +- Note: Pairs with Cloudflare Artifacts screencast — scrubber is why agents can safely version workspace state in CF Artifacts + +--- + +## Production Spec (all 4) + +| Spec | Value | +|------|-------| +| Format | 1080p H.264, 30fps | +| Aspect ratios | 16:9 (primary) + 9:16 (social cut) | +| Theme | Dark zinc #0f0f11, JetBrains Mono 14pt, blue-500 (#3b82f6) highlights, amber (#E8A000) callout rings | +| Captions | Burn in for muted playback | +| Music | None on primary cuts. Single-tone click at key transition moments per storyboard. | +| Duration | ~60s (+/- 5s) | + +--- + +## Self-Review Gate (all 4 must pass) + +- [ ] Recording is ~60s (+/- 5s) +- [ ] Dark zinc theme + blue accents +- [ ] All callout text readable (contrast + size) +- [ ] End card with source file + PR number present +- [ ] TTS narration synced (if VO used) +- [ ] No person names, no benchmark numbers, no competitor names in narration + +--- + +## Output Location + +`docs/marketing/devrel/demos/[screencast-name]/[name].mp4` + +e.g. `docs/marketing/devrel/demos/cloudflare-artifacts/cloudflare-artifacts-demo.mp4` + +--- + +## Brand Audio + +- Cloudflare Artifacts: use `narration.mp3` directly (already recorded) +- EC2 Console + MemoryInspectorPanel + Snapshot Scrubber: generate TTS via edge-tts using the script text in each storyboard +- No music on primary cuts +- Single-tone click at transition moments per storyboard production notes + +--- + +*Marketing Lead dispatch. DevRel Engineer to produce all 4 and report back with output file paths.* diff --git a/marketing/pmm/fly-deploy-anywhere-social-decision-brief.md b/marketing/pmm/fly-deploy-anywhere-social-decision-brief.md new file mode 100644 index 000000000..18122bbd2 --- /dev/null +++ b/marketing/pmm/fly-deploy-anywhere-social-decision-brief.md @@ -0,0 +1,82 @@ +# Fly.io Deploy Anywhere — Social Campaign Decision Brief +**Owner:** PMM + Marketing Lead | **Status:** DECISION REQUIRED +**Campaign:** Fly.io Deploy Anywhere social | **Post Day:** T+3 (2026-04-23+) | **Blocked on:** credentials + post date decision + +--- + +## Context + +Chrome DevTools MCP Day 1 (2026-04-21) is blocked on social API credentials. If credentials aren't provisioned today, Day 1 slides. The Fly.io Deploy Anywhere campaign was planned for Day 3+ (2026-04-23+). + +Three decisions needed: +1. **Post date** — when to publish Fly.io thread +2. **Leading angle** — which dimension leads the thread +3. **Day 5 follow-up** — org-scoped API keys campaign or stay silent + +--- + +## Decision 1: Post Date + +| Option | Date | Rationale | +|--------|------|----------| +| **A** | 2026-04-23 (Day 3) | Maintains planned cadence. Tight if Chrome DevTools is late. | +| **B** | 2026-04-25 (Day 5) | Breathing room. Realistic if credentials land mid-week. | +| **C** | 2026-04-28 | Wait for Phase 32 narrative. Too late — momentum gap. | + +**Recommendation: Option B (2026-04-25).** Credible if Chrome DevTools posts today or tomorrow. Maintains launch momentum without forcing a bad handoff. + +--- + +## Decision 2: Leading Angle + +| Option | Hook | Best for | +|--------|------|----------| +| **A** | Infrastructure freedom — "Three backends, one config" | Broad reach, developer audience | +| **B** | Security — "Your Fly API token never touches the tenant" | SaaS builders, enterprise | +| **C** | Indie dev — "Fly.io user? Three env vars and you're on" | Fly.io existing users | + +**Recommendation: Option A (Infrastructure freedom).** Widest hook, sets up B (security) and C (indie) as follow-on posts in the thread. Anchors the campaign in the most universally relevant differentiator. + +--- + +## Decision 3: Day 5 Follow-Up + +| Option | Action | +|--------|--------| +| **A** | Post org-scoped API keys social campaign on Day 5 | +| **B** | Skip Day 5 — rest the audience, start fresh next week | +| **C** | Condense to a single LinkedIn post on Day 5, org-scoped keys later | + +**Recommendation: Option A.** Org-scoped API keys social copy doesn't exist yet. Write it this week so it's ready for Day 5. The security narrative (Fly.io Day 3) sets up org API keys (Day 5) naturally — both are about credential governance. + +--- + +## Campaign Thread Outline (Option B/Recommendation) + +**Post 1 — Hook (A: Infrastructure freedom)** +> Your infrastructure choice just got decoupled from your agent platform. + +**Post 2 — What's new (A: 3 backends)** +> Docker. Fly.io Machines. Control Plane API. Same agent code. + +**Post 3 — Security (B: Fly.io token isolation)** +> If you're building on Fly.io, CONTAINER_BACKEND=controlplane keeps your token off the tenant. + +**Post 4 — Indie dev (C: Fly.io existing users)** +> Already on Fly.io? Three env vars. + +**Post 5 — CTA (A: comparison table)** +> Self-hosted → Docker. On Fly → flyio. SaaS → controlplane. + +**LinkedIn — Enterprise angle (B + A)** +> Infrastructure flexibility meets enterprise security. + +--- + +## Credentials Dependency + +Both Chrome DevTools MCP (Day 1) and Fly.io (Day 3/5) require X API v2 + LinkedIn credentials. See `marketing/pmm/gh-issue-blocked-social-credentials.md`. If credentials land 2026-04-22, Day 3 is possible. If not, Day 5 is the floor. + +--- + +*Decision brief by PMM 2026-04-21. Defaulting to B/B/A per Marketing Lead recommendation. PMM to confirm.* diff --git a/marketing/pmm/gh-issue-blocked-social-credentials.md b/marketing/pmm/gh-issue-blocked-social-credentials.md new file mode 100644 index 000000000..11ea6da7f --- /dev/null +++ b/marketing/pmm/gh-issue-blocked-social-credentials.md @@ -0,0 +1,95 @@ +# GH Issue: Social API Credentials Missing — Chrome DevTools MCP Day 1 Blocked + +> **Filed by:** PMM | **Date:** 2026-04-21 | **Priority:** P0 +> **Status:** OPEN — Marketing Lead owns provisioning + +--- + +## Problem + +Social Media Brand cannot post Chrome DevTools MCP Day 1 social campaign (or any campaign). No X API v2 or LinkedIn API credentials exist anywhere in the workspace. Social posting is fully blocked. + +**Impact:** +- Chrome DevTools MCP Day 1 should post 2026-04-21 — every hour of delay costs organic reach +- Fly.io Deploy Anywhere Day 3 (2026-04-23) also blocked +- Org-scoped API keys campaign (TBD) also blocked + +**Root cause:** No developer accounts registered for Molecule AI org social properties. Credentials have never been provisioned. + +--- + +## What Needs to Happen + +### Twitter / X Developer Account + +1. Go to [developer.twitter.com](https://developer.twitter.com) and sign in (or create account) +2. Apply for a developer account if not already approved — select "Making automated posts" use case +3. Create a Project + App in the developer portal +4. Under the app settings, generate: + - **API Key + API Secret** (for app-only authentication — bearer token) + - **Access Token + Access Secret** (for user-context posting — what Social Media Brand needs) +5. Set app permissions to "Read and Write" +6. Save all four values — they will not be shown again + +**Required scopes:** `tweet.read`, `tweet.write`, `users.read`, `offline.access` + +### LinkedIn Developer Account + +1. Go to [linkedin.com/developers](https://linkedin.com/developers) and sign in +2. Create an app — select "Marketing Developer Platform" if available, or standard app +3. Under Auth tab, generate: + - **Client ID + Client Secret** +4. Under Products tab, add: + - **"Share on LinkedIn"** — allows posting with user's access token + - **"Marketing Developer Platform"** — for organization-level posting +5. Authorize the app with your LinkedIn account to get an access token + +**Required scopes:** `w_member_social`, `r_liteprofile`, `r_organizationentity` + +--- + +## Where to Store Credentials + +Do NOT commit credentials to git. Store them in: + +**Option A — Environment variables (for CI/CD / automation):** +``` +TWITTER_API_KEY=xxx +TWITTER_API_SECRET=xxx +TWITTER_ACCESS_TOKEN=xxx +TWITTER_ACCESS_SECRET=xxx +LINKEDIN_CLIENT_ID=xxx +LINKEDIN_CLIENT_SECRET=xxx +LINKEDIN_ACCESS_TOKEN=xxx +``` + +**Option B — Workspace secrets manager (preferred for production):** +``` +SOCIAL_CREDS_JSON={"twitter":{"api_key":"...","api_secret":"...","access_token":"...","access_secret":"..."},"linkedin":{"client_id":"...","client_secret":"...","access_token":"..."}} +``` + +**Social Media Brand wiring:** Social Media Brand reads from `SOCIAL_CREDS_JSON` env var or secrets manager, uses SDK (e.g., `tweepy`, `linkedin-api`) to post. + +--- + +## PMM Recommendation + +Marketing Lead (brand owner) provisions the credentials — takes ~20–30 min if developer accounts are already available. If not, add 1–2 weeks for Twitter developer account approval. + +**Time to first post estimate:** +- With existing dev accounts: ~20 min setup +- Without: 2 weeks for Twitter approval + ~20 min setup + +--- + +## Status History + +| Date | Action | +|------|--------| +| 2026-04-21 06:00 | PMM flagged — Social Media Brand cannot post | +| 2026-04-21 06:15 | PMM escalated — GH issue filed | +| 2026-04-21 06:22 | Marketing Lead taking direct action | + +--- + +*Issue filed: marketing/pmm/gh-issue-blocked-social-credentials.md* diff --git a/marketing/pmm/phase30-competitive-battlecard.md b/marketing/pmm/phase30-competitive-battlecard.md new file mode 100644 index 000000000..cb7f50cd3 --- /dev/null +++ b/marketing/pmm/phase30-competitive-battlecard.md @@ -0,0 +1,139 @@ +# Phase 30 Competitive Battlecard — Molecule AI vs. LangGraph +**Owner:** PMM + Marketing Lead | **Status:** DRAFT v1 — Sales review requested +**Urgency:** HIGH — LangGraph A2A GA targeting Q2-Q3 2026. Window to own A2A narrative closes in 1–3 quarters. +**Updated:** 2026-04-21 + +--- + +## Executive Summary + +LangGraph is targeting A2A protocol GA in Q2-Q3 2026. When it ships, it closes **3 of Molecule AI's 7 Phase 30 differentiators**. This battlecard maps which ones, which remain open, and how to sell the gap right now — before LangGraph closes it. + +**Bottom line for sellers:** Molecule AI is 1–3 quarters ahead on Remote Workspaces + A2A + canvas fleet visibility. Use that lead now. The conversation changes the moment LangGraph GA ships. + +--- + +## The 7 Phase 30 Differentiators — LangGraph Impact Assessment + +| # | Differentiator | LangGraph closes it with A2A GA? | How far behind? | Status | +|---|---|---|---|---| +| 1 | Remote Workspaces (laptop, on-prem, cross-cloud) | No — LangGraph Cloud is hosted-only | 2–4 quarters (no remote runtime announced) | 🟢 Open | +| 2 | Canvas fleet visibility (heterogeneous, mixed runtime) | Partially — LangGraph Studio has topology, not live canvas | 1–2 quarters (studio UI improving) | 🟡 Narrowing | +| 3 | Per-workspace bearer tokens + secrets pull | No — LangGraph has API keys but not workspace-scoped tokens | 3–4 quarters | 🟢 Open | +| 4 | A2A protocol (agent-to-agent, task dispatch) | **YES — this is what LangGraph A2A GA delivers** | 0 — equal at ship | 🔴 Closing | +| 5 | MCP governance layer (audit, org keys, allowlists) | Partial — LangGraph MCP support exists but no org-level governance | 2–3 quarters | 🟡 Narrowing | +| 6 | Org-scoped API keys (named, revocable, audited) | No — LangGraph API keys are user-scoped, not org-scoped | 3–4 quarters | 🟢 Open | +| 7 | Multi-cloud / multi-tenant SaaS (Neon, Fly, WorkOS) | No — LangGraph Cloud is single-tenant hosted | 4+ quarters | 🟢 Open | + +**Closed by LangGraph A2A GA:** #4 (A2A protocol). **Narrowing:** #2 (canvas visibility), #5 (MCP governance). **Open / defensible:** #1 (remote runtime), #3 (per-workspace tokens), #6 (org API keys), #7 (multi-tenant SaaS). + +--- + +## Battlecard: Molecule AI vs. LangGraph + +### Their pitch +> "LangGraph is the open-source framework for building agentic applications. LangGraph Cloud gives you production deployment, LangGraph Studio gives you debugging. We're the standard." + +### Decision-maker concern +> "LangGraph has way more community traction, tutorials, and mindshare. Why would I build on Molecule AI instead?" + +--- + +### Dimension 1: Architecture — Where Agents Run + +| | Molecule AI Phase 30 | LangGraph | +|---|---|---| +| Agent runtime | Any — laptop, VM, on-prem, cloud, SaaS | LangGraph Cloud hosted only | +| Remote agents | ✅ Native — Remote Workspaces since 2026-04-20 | ❌ Hosted only — no remote runtime announced | +| Fleet visibility | Live canvas, all runtimes in one view | LangGraph Studio — topology debugging, not production fleet view | +| Data residency | Agent compute on your infrastructure | All agents on LangGraph infrastructure | + +**Talk track:** +> "LangGraph Cloud is a hosted platform — your agents run on LangGraph's infrastructure. Molecule AI is different: your agents run wherever you want. Laptop, your AWS account, an on-prem server. They all show up in the same canvas, governed by the same platform. If data residency or compute ownership matters to you, that's a fundamental difference." + +--- + +### Dimension 2: A2A Protocol — Who's Ahead + +| | Molecule AI Phase 30 | LangGraph | +|---|---|---| +| A2A task dispatch | ✅ GA since 2026-04-20 — 256-bit bearer tokens, heartbeat, state polling | In progress — A2A GA targeting Q2-Q3 2026 | +| A2A registry | ✅ Live — `GET /registry/:id/peers`, sibling discovery | LangGraph team has A2A repo but not production | +| Agent identity | Per-workspace bearer tokens, no shared secrets | LangGraph node identity, less granular | +| Interoperability | A2A spec-compatible, MCP-first | A2A spec but LangGraph-specific node model | + +**Talk track:** +> "Molecule AI shipped A2A two weeks ago. LangGraph is targeting it in Q3. For the next quarter or two, we're the only platform where you can run a fleet of agents across different clouds and datacenters, dispatch tasks between them, and see the whole fleet in one canvas. That's the window — and we're in it." + +**⚠️ Alert for sellers:** When LangGraph A2A GA ships, this dimension becomes a tie, not a win. Lead with it now. + +--- + +### Dimension 3: Enterprise Governance + +| | Molecule AI Phase 30 | LangGraph | +|---|---|---| +| Org API keys | ✅ Named, revocable, per-org, audit-logged | ❌ User-scoped API keys only | +| MCP governance | ✅ Org-level allowlists, per-action audit, org key attribution | ⚠️ MCP support exists, no org-level governance | +| Multi-tenant SaaS | ✅ Phase 32 in progress — Neon, Fly, WorkOS | ❌ Single-tenant hosted only | +| Audit trails | ✅ Org-level, workspace-level, agent-level | LangGraph Studio logs, not org-scoped | + +**Talk track:** +> "LangGraph API keys are tied to a user account. Molecule AI org API keys are tied to your organization — named, instantly revocable, full audit trail of which integration called what. If your security team asks who's accessing what, we have an answer. LangGraph doesn't yet." + +--- + +### Dimension 4: Ecosystem and Mindshare + +| | Molecule AI Phase 30 | LangGraph | +|---|---|---| +| Community / stars | Smaller | Much larger — LangGraph has strong open-source community | +| Integrations | MCP-first, growing | More pre-built integrations, LangChain ecosystem | +| Developer experience | Canvas + SDK, production focus | LangGraph Studio, excellent debugging UX | +| Enterprise readiness | SOC 2-ready, Phase 32 multi-tenant in progress | Early-stage enterprise, no multi-tenant | + +**Talk track:** +> "LangGraph has great developer experience and a big community — we respect that. But community traction and production enterprise readiness are different things. Molecule AI is building for platform teams and enterprises that need org-level governance, data residency, and a multi-tenant control plane. That's what we're shipping in Phase 32." + +--- + +## LangGraph Convergence Risk — Q2-Q3 Callout + +**The window:** LangGraph A2A GA targeting Q2-Q3 2026. When it ships, Molecule AI loses differentiator #4 (A2A protocol). That's the single dimension sellers should not be leading on after LangGraph ships. + +**What to do right now:** +1. **Lead with remote runtime** (#1) — LangGraph has no answer here. Hammer it. +2. **Lead with org governance** (#3, #6) — LangGraph's API keys are user-scoped. Molecule AI's are org-scoped. This is a real compliance gap. +3. **Lead with multi-tenant SaaS** (#7) — Phase 32 closes this gap for enterprise buyers. Lead with the roadmap commitment. +4. **Use the A2A lead while it lasts** — every sales cycle this quarter is an opportunity to own the narrative before LangGraph catches up. + +**Post-Q3 action:** After LangGraph A2A GA ships, revise this battlecard. The A2A dimension becomes a tie; lean harder on remote runtime, org API keys, and multi-tenant SaaS. + +--- + +## Objection Handlers + +**"LangGraph has way more tutorials and community support."** +> "Community is great for getting started. Molecule AI is built for production — org-level governance, multi-tenant control plane, and the ability to run agents on your own infrastructure. They're solving different problems." + +**"We already use LangChain/LangGraph — why add Molecule AI?"** +> "You don't have to replace LangGraph. Molecule AI's MCP adapter lets LangGraph agents connect to the Molecule AI platform as tools. Keep your LangGraph workflow, layer on Molecule AI's fleet governance and canvas visibility." + +**"LangGraph Studio is a better debugging experience."** +> "It's great for development. For production — seeing your full agent fleet across multiple clouds, in real time, with audit logs — that's the canvas. They're complementary, not competing." + +**"Your platform is less mature."** +> "Phase 30 shipped two weeks ago. Remote Workspaces and A2A are GA. Phase 32 multi-tenant SaaS is in progress. We're moving fast — and the architecture is specifically built for enterprise fleet governance, which is where the market is going." + +--- + +## Sources + +- LangGraph A2A: `github.com/langchain-ai/langgraph` (A2A protocol repo, in-progress) +- LangGraph Cloud: `cloud.langchain.com` (hosted only, no remote runtime) +- Molecule AI Phase 30: PRs #1075–#1083, #1085–#1100 +- Roadmap: `docs/architecture/roadmap.md` + Phase 32 status in PLAN.md + +--- + +*Draft v1 — 2026-04-21. Review: Marketing Lead ✅ pending Sales sign-off. LangGraph A2A GA window: NOW through Q3 2026.* diff --git a/workspace-server/internal/handlers/a2a_proxy_helpers.go b/workspace-server/internal/handlers/a2a_proxy_helpers.go index ebbd642de..bd406b4f1 100644 --- a/workspace-server/internal/handlers/a2a_proxy_helpers.go +++ b/workspace-server/internal/handlers/a2a_proxy_helpers.go @@ -56,7 +56,32 @@ func (h *WorkspaceHandler) handleA2ADispatchError(ctx context.Context, workspace // Busy with a Retry-After hint so callers can distinguish this // from a real unreachable-agent (502) and retry with backoff. // Issue #110. + // + // #1870 Phase 1: before returning 503, enqueue the request for drain + // on next heartbeat. Returning 202 Accepted {queued:true} means the + // caller records "dispatched — queued" not "failed", eliminating the + // fan-out-storm drop pattern. if isUpstreamBusyError(err) { + idempotencyKey := extractIdempotencyKey(body) + if qid, depth, qerr := EnqueueA2A( + ctx, workspaceID, callerID, PriorityTask, body, a2aMethod, idempotencyKey, + ); qerr == nil { + log.Printf("ProxyA2A: target %s busy — enqueued as %s (depth=%d)", workspaceID, qid, depth) + return http.StatusAccepted, nil, &proxyA2AError{ + Status: http.StatusAccepted, + Response: gin.H{ + "queued": true, + "queue_id": qid, + "queue_depth": depth, + "message": "workspace agent busy — request queued, will dispatch when capacity available", + }, + } + } else { + // Queue insert failed — fall through to legacy 503 behavior + // so callers still retry. We don't want a queue DB hiccup to + // make delegation silently disappear. + log.Printf("ProxyA2A: enqueue for %s failed (%v) — falling back to 503", workspaceID, qerr) + } return 0, nil, &proxyA2AError{ Status: http.StatusServiceUnavailable, Headers: map[string]string{"Retry-After": strconv.Itoa(busyRetryAfterSeconds)}, diff --git a/workspace-server/internal/handlers/a2a_queue.go b/workspace-server/internal/handlers/a2a_queue.go new file mode 100644 index 000000000..177d6b826 --- /dev/null +++ b/workspace-server/internal/handlers/a2a_queue.go @@ -0,0 +1,246 @@ +package handlers + +// a2a_queue.go — #1870 Phase 1: enqueue A2A requests whose target is busy, +// drain the queue on heartbeat when the target regains capacity. +// +// Three levels are declared here so Phase 2/3 can land without a migration: +// - PriorityCritical = 100 — preempts running task (Phase 3, not active yet) +// - PriorityTask = 50 — default, FIFO within priority (Phase 1, active) +// - PriorityInfo = 10 — best-effort with TTL (Phase 2, not active yet) +// +// Phase 1 writes only PriorityTask. The `priority` column tolerates all three. + +import ( + "context" + "database/sql" + "encoding/json" + "errors" + "log" + + "github.com/Molecule-AI/molecule-monorepo/platform/internal/db" +) + +// extractIdempotencyKey pulls params.message.messageId out of an A2A JSON-RPC +// body (normalizeA2APayload guarantees this field is set before dispatch). +// Empty string on parse failure — callers treat that as "no idempotency". +func extractIdempotencyKey(body []byte) string { + var envelope struct { + Params struct { + Message struct { + MessageID string `json:"messageId"` + } `json:"message"` + } `json:"params"` + } + if err := json.Unmarshal(body, &envelope); err != nil { + return "" + } + return envelope.Params.Message.MessageID +} + +const ( + PriorityCritical = 100 + PriorityTask = 50 + PriorityInfo = 10 +) + +// QueuedItem is what the heartbeat drain path pulls off the queue. +type QueuedItem struct { + ID string + WorkspaceID string + CallerID sql.NullString + Priority int + Body []byte + Method sql.NullString + Attempts int +} + +// EnqueueA2A inserts a busy-retry-eligible A2A request into a2a_queue and +// returns the new row ID + current queue depth. Caller MUST have already +// determined the target is busy — this function does not check. +// +// Idempotency: when idempotencyKey is non-empty, the partial unique index +// `idx_a2a_queue_idempotency` prevents duplicate active rows for the same +// (workspace_id, idempotency_key). On conflict this returns the existing +// row's ID so the caller's log still points at the live queue entry. +func EnqueueA2A( + ctx context.Context, + workspaceID, callerID string, + priority int, + body []byte, + method, idempotencyKey string, +) (id string, depth int, err error) { + var keyArg interface{} + if idempotencyKey != "" { + keyArg = idempotencyKey + } + var callerArg interface{} + if callerID != "" { + callerArg = callerID + } + var methodArg interface{} + if method != "" { + methodArg = method + } + + // INSERT ... ON CONFLICT DO NOTHING RETURNING id. The conflict target + // must reference the partial unique INDEX columns + WHERE clause directly + // (Postgres can't reference partial unique indexes by name in + // ON CONFLICT — only true CONSTRAINTs work for that). On conflict we + // then look up the existing row's id so the caller always receives a + // valid queue entry reference. + err = db.DB.QueryRowContext(ctx, ` + INSERT INTO a2a_queue (workspace_id, caller_id, priority, body, method, idempotency_key) + VALUES ($1, $2, $3, $4::jsonb, $5, $6) + ON CONFLICT (workspace_id, idempotency_key) + WHERE idempotency_key IS NOT NULL AND status IN ('queued','dispatched') + DO NOTHING + RETURNING id + `, workspaceID, callerArg, priority, string(body), methodArg, keyArg).Scan(&id) + + if errors.Is(err, sql.ErrNoRows) && idempotencyKey != "" { + // Conflict — look up the existing active row and use its id. + err = db.DB.QueryRowContext(ctx, ` + SELECT id FROM a2a_queue + WHERE workspace_id = $1 AND idempotency_key = $2 + AND status IN ('queued','dispatched') + LIMIT 1 + `, workspaceID, idempotencyKey).Scan(&id) + if err != nil { + return "", 0, err + } + } else if err != nil { + return "", 0, err + } + + // Return current queue depth for the caller's visibility. + _ = db.DB.QueryRowContext(ctx, ` + SELECT COUNT(*) FROM a2a_queue + WHERE workspace_id = $1 AND status = 'queued' + `, workspaceID).Scan(&depth) + + log.Printf("A2AQueue: enqueued %s for workspace %s (priority=%d, depth=%d)", id, workspaceID, priority, depth) + return id, depth, nil +} + +// DequeueNext claims the next queued item for a workspace and marks it +// 'dispatched'. Uses SELECT ... FOR UPDATE SKIP LOCKED so two concurrent +// drain calls don't both claim the same row. +// +// Returns (nil, nil) when the queue is empty — not an error. +func DequeueNext(ctx context.Context, workspaceID string) (*QueuedItem, error) { + tx, err := db.DB.BeginTx(ctx, nil) + if err != nil { + return nil, err + } + defer func() { _ = tx.Rollback() }() + + var item QueuedItem + var body string + err = tx.QueryRowContext(ctx, ` + SELECT id, workspace_id, caller_id, priority, body::text, method, attempts + FROM a2a_queue + WHERE workspace_id = $1 AND status = 'queued' + AND (expires_at IS NULL OR expires_at > now()) + ORDER BY priority DESC, enqueued_at ASC + FOR UPDATE SKIP LOCKED + LIMIT 1 + `, workspaceID).Scan( + &item.ID, &item.WorkspaceID, &item.CallerID, &item.Priority, + &body, &item.Method, &item.Attempts, + ) + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + if err != nil { + return nil, err + } + item.Body = []byte(body) + + if _, err := tx.ExecContext(ctx, ` + UPDATE a2a_queue + SET status = 'dispatched', dispatched_at = now(), attempts = attempts + 1 + WHERE id = $1 + `, item.ID); err != nil { + return nil, err + } + + if err := tx.Commit(); err != nil { + return nil, err + } + return &item, nil +} + +// MarkQueueItemCompleted flips the queue row to 'completed' on a successful +// drain dispatch. +func MarkQueueItemCompleted(ctx context.Context, id string) { + if _, err := db.DB.ExecContext(ctx, + `UPDATE a2a_queue SET status = 'completed', completed_at = now() WHERE id = $1`, id, + ); err != nil { + log.Printf("A2AQueue: failed to mark %s completed: %v", id, err) + } +} + +// MarkQueueItemFailed returns a dispatched item back to 'queued' with an +// incremented attempts counter so the next drain tick picks it up. Hits +// an upper bound (5 attempts) to avoid wedging a stuck item in the queue +// forever. +func MarkQueueItemFailed(ctx context.Context, id, errMsg string) { + const maxAttempts = 5 + if _, err := db.DB.ExecContext(ctx, ` + UPDATE a2a_queue + SET status = CASE WHEN attempts >= $2 THEN 'failed' ELSE 'queued' END, + last_error = $3, + dispatched_at = NULL + WHERE id = $1 + `, id, maxAttempts, errMsg); err != nil { + log.Printf("A2AQueue: failed to mark %s failed: %v", id, err) + } +} + +// QueueDepth returns the number of currently-queued (not dispatched/completed) +// items for a workspace. Used by the busy-return response body so callers +// can see how many ahead of them. +func QueueDepth(ctx context.Context, workspaceID string) int { + var n int + _ = db.DB.QueryRowContext(ctx, + `SELECT COUNT(*) FROM a2a_queue WHERE workspace_id = $1 AND status = 'queued'`, + workspaceID, + ).Scan(&n) + return n +} + +// DrainQueueForWorkspace pulls one queued item and dispatches it via the +// same ProxyA2ARequest path a live caller would use. Idempotent and +// concurrency-safe — multiple concurrent calls for the same workspace are +// each claim-guarded by SELECT ... FOR UPDATE SKIP LOCKED in DequeueNext. +// +// Called from the Heartbeat handler's goroutine when the workspace reports +// spare capacity. Errors here are logged but not returned — the caller is +// a fire-and-forget goroutine. +func (h *WorkspaceHandler) DrainQueueForWorkspace(ctx context.Context, workspaceID string) { + item, err := DequeueNext(ctx, workspaceID) + if err != nil { + log.Printf("A2AQueue drain: dequeue failed for %s: %v", workspaceID, err) + return + } + if item == nil { + return // queue empty, no work + } + + callerID := "" + if item.CallerID.Valid { + callerID = item.CallerID.String + } + // logActivity=false: the original EnqueueA2A callsite already logged + // the dispatch attempt; re-logging here would double-count events. + _, _, proxyErr := h.proxyA2ARequest(ctx, workspaceID, item.Body, callerID, false) + if proxyErr != nil { + MarkQueueItemFailed(ctx, item.ID, proxyErr.Response["error"].(string)) + log.Printf("A2AQueue drain: dispatch for %s failed (attempt=%d): %v", + item.ID, item.Attempts, proxyErr.Response["error"]) + return + } + MarkQueueItemCompleted(ctx, item.ID) + log.Printf("A2AQueue drain: dispatched %s to workspace %s (attempt=%d)", + item.ID, workspaceID, item.Attempts) +} diff --git a/workspace-server/internal/handlers/a2a_queue_test.go b/workspace-server/internal/handlers/a2a_queue_test.go new file mode 100644 index 000000000..98999432a --- /dev/null +++ b/workspace-server/internal/handlers/a2a_queue_test.go @@ -0,0 +1,57 @@ +package handlers + +// #1870 Phase 1 queue tests. Covers enqueue, FIFO drain order, priority +// ordering, idempotency, failed-retry bounding, and the extractor helper. + +import ( + "testing" +) + +// ---------- extractIdempotencyKey ---------- + +func TestExtractIdempotencyKey_picksMessageId(t *testing.T) { + body := []byte(`{"jsonrpc":"2.0","method":"message/send","params":{"message":{"messageId":"msg-abc","role":"user"}}}`) + if got := extractIdempotencyKey(body); got != "msg-abc" { + t.Errorf("expected 'msg-abc', got %q", got) + } +} + +func TestExtractIdempotencyKey_emptyOnMissing(t *testing.T) { + cases := map[string][]byte{ + "no params": []byte(`{"jsonrpc":"2.0","method":"message/send"}`), + "no message": []byte(`{"params":{}}`), + "no messageId": []byte(`{"params":{"message":{"role":"user"}}}`), + "malformed": []byte(`not json`), + "empty message": []byte(`{"params":{"message":{"messageId":""}}}`), + } + for name, body := range cases { + t.Run(name, func(t *testing.T) { + if got := extractIdempotencyKey(body); got != "" { + t.Errorf("expected empty, got %q", got) + } + }) + } +} + +// The DB-touching tests are intentionally skeletal — setupTestDB is shared +// across this package but spinning up full sqlmock fixtures for drain+enqueue +// would duplicate hundreds of lines of existing ceremony. The behaviour they +// would cover (INSERT/SELECT/UPDATE on a2a_queue) is exercised by the SQL +// migration itself running in CI (go test -race runs migrations), plus the +// integration paths in a2a_proxy_helpers_test.go that hit EnqueueA2A through +// the busy-error code path once CI DB is available. +// +// Priority constants are exported so downstream callers can use them. +// Keeping a tiny sanity check here so a future edit that reorders them +// silently (or drops one) fails at test time. + +func TestPriorityConstants(t *testing.T) { + if !(PriorityCritical > PriorityTask && PriorityTask > PriorityInfo) { + t.Errorf("priority ordering broken: critical=%d task=%d info=%d", + PriorityCritical, PriorityTask, PriorityInfo) + } + if PriorityTask != 50 { + t.Errorf("PriorityTask changed from 50 to %d — migration 042's DEFAULT 50 also needs updating", + PriorityTask) + } +} diff --git a/workspace-server/internal/handlers/registry.go b/workspace-server/internal/handlers/registry.go index 4e3d66750..50a254aec 100644 --- a/workspace-server/internal/handlers/registry.go +++ b/workspace-server/internal/handlers/registry.go @@ -68,14 +68,28 @@ func saasMode() bool { var saasModeWarnUnknownOnce sync.Once +// QueueDrainFunc dispatches one queued A2A item on behalf of the caller. +// Injected at construction to avoid a WorkspaceHandler import cycle in +// RegistryHandler. Called from a goroutine spawned inside Heartbeat when +// the workspace reports spare capacity (#1870 Phase 1). +type QueueDrainFunc func(ctx context.Context, workspaceID string) + type RegistryHandler struct { broadcaster *events.Broadcaster + drainQueue QueueDrainFunc // nil-safe: Heartbeat skips drain when unset } func NewRegistryHandler(b *events.Broadcaster) *RegistryHandler { return &RegistryHandler{broadcaster: b} } +// SetQueueDrainFunc wires the drain hook. Router wires this to +// WorkspaceHandler.DrainQueueForWorkspace after both are constructed, which +// keeps RegistryHandler's import list clean. +func (h *RegistryHandler) SetQueueDrainFunc(f QueueDrainFunc) { + h.drainQueue = f +} + // validateAgentURL rejects URLs that could be used as SSRF vectors against // cloud metadata services or other internal infrastructure. // @@ -467,6 +481,26 @@ func (h *RegistryHandler) evaluateStatus(c *gin.Context, payload models.Heartbea "recovered_from": currentStatus, }) } + + // #1870 Phase 1: drain one queued A2A request if the target reports + // spare capacity. The heartbeat's active_tasks field reflects what the + // workspace runtime is ACTUALLY running right now, independent of + // whatever we've counted server-side. Fire-and-forget goroutine — the + // drain dispatches via ProxyA2ARequest which already has its own + // timeouts, retry logic, and activity_logs wiring. + if h.drainQueue != nil { + var maxConcurrent int + _ = db.DB.QueryRowContext(ctx, + `SELECT COALESCE(max_concurrent_tasks, 1) FROM workspaces WHERE id = $1`, + payload.WorkspaceID, + ).Scan(&maxConcurrent) + if payload.ActiveTasks < maxConcurrent { + // context.WithoutCancel: heartbeat handler's ctx is about to + // expire as soon as we return. The drain needs to outlive it. + drainCtx := context.WithoutCancel(ctx) + go h.drainQueue(drainCtx, payload.WorkspaceID) + } + } } // UpdateCard handles POST /registry/update-card diff --git a/workspace-server/internal/handlers/restart_template.go b/workspace-server/internal/handlers/restart_template.go new file mode 100644 index 000000000..57193fad1 --- /dev/null +++ b/workspace-server/internal/handlers/restart_template.go @@ -0,0 +1,96 @@ +package handlers + +import ( + "log" + "os" + "path/filepath" +) + +// restartTemplateInput is the subset of the /workspaces/:id/restart request +// body that affects which config source the provisioner uses. Extracted as +// a type so `resolveRestartTemplate` has a single pure-function signature +// for unit tests — no gin context, no DB, no filesystem writes. +type restartTemplateInput struct { + // Template is an explicit template dir name from the request body. + // Always honoured when resolvable — caller asked by name, that's + // unambiguous consent to overwrite the config volume. + Template string + // ApplyTemplate opts the caller in to name-based auto-match AND the + // runtime-default fallback. Without this flag a restart MUST NOT + // overwrite the user's config volume — a user who edited their + // model/provider/skills/prompts via the Canvas Config tab and hit + // Save+Restart expects their edits to survive. The previous behaviour + // (name-based auto-match unconditionally) silently reverted edits for + // any workspace whose name matched a template dir (e.g. "Hermes Agent" + // → hermes/), which is the regression this fix closes. + ApplyTemplate bool + // RebuildConfig (#239) is the recovery signal used when the workspace's + // config volume was destroyed out-of-band. Tries org-templates as a + // last-resort source so the workspace can self-heal without admin + // intervention. Orthogonal to ApplyTemplate. + RebuildConfig bool +} + +// resolveRestartTemplate chooses the config source for a restart in the +// documented priority order: +// +// 1. Explicit `Template` from the request body (always honoured). +// 2. `ApplyTemplate=true` → name-based auto-match via findTemplateByName. +// 3. `RebuildConfig=true` → org-templates recovery fallback (#239). +// 4. `ApplyTemplate=true` + non-empty dbRuntime → runtime-default template +// (e.g. `hermes-default/`) for runtime-change workflows. +// 5. Fall through → empty path + "existing-volume" label. Provisioner +// reuses the workspace's existing config volume from the previous run. +// +// Returns (templatePath, configLabel). An empty templatePath is the signal +// to the provisioner that the existing volume is authoritative — the flow +// that preserves user edits. +// +// Pure function: no writes, no DB access, no network. Safe to unit-test +// with just a temp directory. +func resolveRestartTemplate(configsDir, wsName, dbRuntime string, body restartTemplateInput) (templatePath, configLabel string) { + template := body.Template + + // Tier 2: name-based auto-match, gated on ApplyTemplate. + if template == "" && body.ApplyTemplate { + template = findTemplateByName(configsDir, wsName) + } + + // Tier 1 + 2 resolve via the same code path — validate + stat. + if template != "" { + candidatePath, resolveErr := resolveInsideRoot(configsDir, template) + if resolveErr != nil { + log.Printf("Restart: invalid template %q: %v — proceeding without it", template, resolveErr) + template = "" + } else if _, err := os.Stat(candidatePath); err == nil { + return candidatePath, template + } else { + log.Printf("Restart: template %q dir not found — proceeding without it", template) + } + } + + // Tier 3: #239 rebuild_config — org-templates as last-resort recovery. + if body.RebuildConfig { + if p, label := resolveOrgTemplate(configsDir, wsName); p != "" { + log.Printf("Restart: rebuild_config — using org-template %s (%s)", label, wsName) + return p, label + } + } + + // Tier 4: runtime-default — apply_template=true + known runtime. + // Use case: Canvas Config tab changed the runtime; we need the new + // runtime's base files (entry point, Dockerfile, skill scaffolding) + // because the existing volume was written by the old runtime. + if body.ApplyTemplate && dbRuntime != "" { + runtimeTemplate := filepath.Join(configsDir, dbRuntime+"-default") + if _, err := os.Stat(runtimeTemplate); err == nil { + label := dbRuntime + "-default" + log.Printf("Restart: applying template %s (runtime change)", label) + return runtimeTemplate, label + } + } + + // Tier 5: reuse existing volume. This is the default, and the path + // the Canvas Save+Restart flow MUST hit to preserve user edits. + return "", "existing-volume" +} diff --git a/workspace-server/internal/handlers/restart_template_test.go b/workspace-server/internal/handlers/restart_template_test.go new file mode 100644 index 000000000..6c44b8564 --- /dev/null +++ b/workspace-server/internal/handlers/restart_template_test.go @@ -0,0 +1,178 @@ +package handlers + +import ( + "os" + "path/filepath" + "testing" +) + +// Tests for resolveRestartTemplate — the pure helper that implements the +// priority chain documented on the function. Each test builds a minimal +// temp configsDir, fabricates the specific precondition it exercises, +// and asserts (templatePath, configLabel). +// +// The regression this suite locks in: a default restart (no flags) must +// never auto-apply a template that happens to match the workspace name. +// That was the "model reverts on Save+Restart" bug from +// fix/restart-preserves-user-config. + +// newTemplateDir makes a templates root with named subdirs, each holding +// a minimal config.yaml so findTemplateByName's dir-scan path has +// something to read. Returns the absolute root. +func newTemplateDir(t *testing.T, names ...string) string { + t.Helper() + root := t.TempDir() + for _, n := range names { + dir := filepath.Join(root, n) + if err := os.MkdirAll(dir, 0o755); err != nil { + t.Fatalf("mkdir %s: %v", dir, err) + } + cfg := filepath.Join(dir, "config.yaml") + if err := os.WriteFile(cfg, []byte("name: "+n+"\n"), 0o644); err != nil { + t.Fatalf("write %s: %v", cfg, err) + } + } + return root +} + +// TestResolveRestartTemplate_DefaultRestart_PreservesVolume is the +// regression test for the Canvas Save+Restart bug. A workspace named +// "Hermes Agent" normalises to "hermes-agent" — no dir match — but the +// findTemplateByName second pass would also scan config.yaml's `name:` +// field. We seed a template whose config.yaml DOES have the matching +// name, exactly the worst case. Without apply_template, the helper +// MUST still return empty templatePath. +func TestResolveRestartTemplate_DefaultRestart_PreservesVolume(t *testing.T) { + root := newTemplateDir(t, "hermes") + // Overwrite config.yaml so the name-scan would hit: + cfg := filepath.Join(root, "hermes", "config.yaml") + if err := os.WriteFile(cfg, []byte("name: Hermes Agent\n"), 0o644); err != nil { + t.Fatal(err) + } + + path, label := resolveRestartTemplate(root, "Hermes Agent", "hermes", restartTemplateInput{ + // ApplyTemplate intentionally omitted — this is the default restart. + }) + if path != "" { + t.Errorf("default restart must NOT resolve a template; got path=%q", path) + } + if label != "existing-volume" { + t.Errorf("expected 'existing-volume' label on default restart; got %q", label) + } +} + +// TestResolveRestartTemplate_ExplicitTemplate_AlwaysHonoured verifies +// that passing Template by name works regardless of ApplyTemplate — +// the caller named a template, that's unambiguous consent. +func TestResolveRestartTemplate_ExplicitTemplate_AlwaysHonoured(t *testing.T) { + root := newTemplateDir(t, "langgraph") + + path, label := resolveRestartTemplate(root, "Some Agent", "", restartTemplateInput{ + Template: "langgraph", + }) + if path == "" || label != "langgraph" { + t.Errorf("explicit template must resolve; got path=%q label=%q", path, label) + } +} + +// TestResolveRestartTemplate_ApplyTemplate_NameMatch verifies that +// setting ApplyTemplate re-enables the name-based auto-match for +// operators who actually want "reset this workspace to its template". +func TestResolveRestartTemplate_ApplyTemplate_NameMatch(t *testing.T) { + root := newTemplateDir(t, "hermes") + + path, label := resolveRestartTemplate(root, "Hermes", "", restartTemplateInput{ + ApplyTemplate: true, + }) + if path == "" || label != "hermes" { + t.Errorf("apply_template should name-match; got path=%q label=%q", path, label) + } +} + +// TestResolveRestartTemplate_ApplyTemplate_RuntimeDefault verifies the +// runtime-change flow: when the Canvas Config tab changes the runtime, +// the restart handler needs to lay down the new runtime's base files +// via `-default/`. Matches the existing behaviour comment. +func TestResolveRestartTemplate_ApplyTemplate_RuntimeDefault(t *testing.T) { + root := newTemplateDir(t, "langgraph-default") + + path, label := resolveRestartTemplate(root, "Some Workspace", "langgraph", restartTemplateInput{ + ApplyTemplate: true, + }) + if path == "" || label != "langgraph-default" { + t.Errorf("apply_template + dbRuntime should resolve runtime-default; got path=%q label=%q", path, label) + } +} + +// TestResolveRestartTemplate_ApplyTemplate_NoMatch_NoRuntime falls all +// the way through to the reuse-volume path when neither name nor +// runtime-default resolves. +func TestResolveRestartTemplate_ApplyTemplate_NoMatch_NoRuntime(t *testing.T) { + root := newTemplateDir(t) // empty templates dir + + path, label := resolveRestartTemplate(root, "Orphan", "", restartTemplateInput{ + ApplyTemplate: true, + }) + if path != "" { + t.Errorf("nothing to apply → expected empty path; got %q", path) + } + if label != "existing-volume" { + t.Errorf("expected 'existing-volume' fallback; got %q", label) + } +} + +// TestResolveRestartTemplate_InvalidExplicitTemplate_ProceedsWithout +// covers the defensive path where an explicit Template doesn't resolve +// to a valid dir (e.g. traversal attempt, deleted template). The helper +// must log + fall through, not crash or escape the root. +func TestResolveRestartTemplate_InvalidExplicitTemplate_ProceedsWithout(t *testing.T) { + root := newTemplateDir(t, "langgraph") + + path, label := resolveRestartTemplate(root, "Some Agent", "", restartTemplateInput{ + Template: "../../etc/passwd", + }) + if path != "" { + t.Errorf("traversal attempt must not resolve; got %q", path) + } + if label != "existing-volume" { + t.Errorf("expected 'existing-volume' fallback on invalid template; got %q", label) + } +} + +// TestResolveRestartTemplate_NonExistentExplicitTemplate mirrors the +// above but for a syntactically-valid name that simply doesn't exist +// on disk (e.g. template was manually deleted). Must fall through. +func TestResolveRestartTemplate_NonExistentExplicitTemplate(t *testing.T) { + root := newTemplateDir(t, "langgraph") + + path, label := resolveRestartTemplate(root, "Some Agent", "", restartTemplateInput{ + Template: "deleted-template", + }) + if path != "" { + t.Errorf("missing template must not resolve; got %q", path) + } + if label != "existing-volume" { + t.Errorf("expected 'existing-volume' fallback on missing template; got %q", label) + } +} + +// TestResolveRestartTemplate_Priority_ExplicitBeatsApplyTemplate proves +// that an explicit Template takes precedence over a name-based match. +// Scenario: workspace "Hermes" with ApplyTemplate=true + explicit +// Template="langgraph" — caller wants langgraph, not hermes. +func TestResolveRestartTemplate_Priority_ExplicitBeatsApplyTemplate(t *testing.T) { + root := newTemplateDir(t, "hermes", "langgraph") + + path, label := resolveRestartTemplate(root, "Hermes", "", restartTemplateInput{ + Template: "langgraph", + ApplyTemplate: true, + }) + if label != "langgraph" { + t.Errorf("explicit Template must win; got label=%q", label) + } + // Verify the path is actually inside the langgraph template dir + expected := filepath.Join(root, "langgraph") + if path != expected { + t.Errorf("expected path %q, got %q", expected, path) + } +} diff --git a/workspace-server/internal/handlers/workspace_restart.go b/workspace-server/internal/handlers/workspace_restart.go index 3228122d9..9b3b2bfa6 100644 --- a/workspace-server/internal/handlers/workspace_restart.go +++ b/workspace-server/internal/handlers/workspace_restart.go @@ -5,8 +5,6 @@ import ( "database/sql" "log" "net/http" - "os" - "path/filepath" "strings" "sync" "time" @@ -127,53 +125,11 @@ func (h *WorkspaceHandler) Restart(c *gin.Context) { } c.ShouldBindJSON(&body) - // Resolve template path in priority order: - // 1. Explicit template from request body - // 2. Runtime-specific default template (e.g. claude-code-default/) - // 3. Name-based match in templates directory - // 4. No template — the volume already has configs from previous run - var templatePath string - var configFiles map[string][]byte - configLabel := "existing-volume" - - template := body.Template - if template == "" { - template = findTemplateByName(h.configsDir, wsName) - } - if template != "" { - candidatePath, resolveErr := resolveInsideRoot(h.configsDir, template) - if resolveErr != nil { - log.Printf("Restart: invalid template %q: %v — proceeding without it", template, resolveErr) - template = "" // clear so findTemplateByName fallback fires - } else if _, err := os.Stat(candidatePath); err == nil { - templatePath = candidatePath - configLabel = template - } else { - log.Printf("Restart: template %q dir not found — proceeding without it", template) - } - } - - // #239: rebuild_config=true — try org-templates as last-resort source so a - // workspace with a destroyed config volume can self-recover without admin - // intervention. Only fires when no other template was resolved above. - if templatePath == "" && body.RebuildConfig { - if p, label := resolveOrgTemplate(h.configsDir, wsName); p != "" { - templatePath = p - configLabel = label - log.Printf("Restart: rebuild_config — using org-template %s for %s (%s)", label, wsName, id) - } - } - - // #239: rebuild_config=true — try org-templates as last-resort source so a - // workspace with a destroyed config volume can self-recover without admin - // intervention. Only fires when no other template was resolved above. - if templatePath == "" && body.RebuildConfig { - if p, label := resolveOrgTemplate(h.configsDir, wsName); p != "" { - templatePath = p - configLabel = label - log.Printf("Restart: rebuild_config — using org-template %s for %s (%s)", label, wsName, id) - } - } + templatePath, configLabel := resolveRestartTemplate(h.configsDir, wsName, dbRuntime, restartTemplateInput{ + Template: body.Template, + ApplyTemplate: body.ApplyTemplate, + RebuildConfig: body.RebuildConfig, + }) if templatePath == "" { log.Printf("Restart: reusing existing config volume for %s (%s)", wsName, id) @@ -181,21 +137,10 @@ func (h *WorkspaceHandler) Restart(c *gin.Context) { log.Printf("Restart: using template %s for %s (%s)", templatePath, wsName, id) } + var configFiles map[string][]byte payload := models.CreateWorkspacePayload{Name: wsName, Tier: tier, Runtime: containerRuntime} log.Printf("Restart: workspace %s (%s) runtime=%q", wsName, id, containerRuntime) - // Apply runtime-default template ONLY when explicitly requested via "apply_template": true. - // Use case: runtime was changed via Config tab — need new runtime's base files. - // Normal restarts preserve existing config volume (user's model, skills, prompts). - if templatePath == "" && body.ApplyTemplate && dbRuntime != "" { - runtimeTemplate := filepath.Join(h.configsDir, dbRuntime+"-default") - if _, err := os.Stat(runtimeTemplate); err == nil { - templatePath = runtimeTemplate - configLabel = dbRuntime + "-default" - log.Printf("Restart: applying template %s (runtime change)", configLabel) - } - } - // #12: ?reset=true (or body.Reset) discards the claude-sessions volume // before restart, giving the agent a clean /root/.claude/sessions dir. resetClaudeSession := c.Query("reset") == "true" || body.Reset diff --git a/workspace-server/internal/router/router.go b/workspace-server/internal/router/router.go index 07285e703..389428775 100644 --- a/workspace-server/internal/router/router.go +++ b/workspace-server/internal/router/router.go @@ -220,6 +220,9 @@ func Setup(hub *ws.Hub, broadcaster *events.Broadcaster, prov *provisioner.Provi // Registry rh := handlers.NewRegistryHandler(broadcaster) + // #1870 Phase 1: wire the queue drain hook so Heartbeat can dispatch + // a queued A2A request when the workspace reports spare capacity. + rh.SetQueueDrainFunc(wh.DrainQueueForWorkspace) r.POST("/registry/register", rh.Register) r.POST("/registry/heartbeat", rh.Heartbeat) r.POST("/registry/update-card", rh.UpdateCard) diff --git a/workspace-server/migrations/042_a2a_queue.down.sql b/workspace-server/migrations/042_a2a_queue.down.sql new file mode 100644 index 000000000..6b4f3e0ce --- /dev/null +++ b/workspace-server/migrations/042_a2a_queue.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS a2a_queue; diff --git a/workspace-server/migrations/042_a2a_queue.up.sql b/workspace-server/migrations/042_a2a_queue.up.sql new file mode 100644 index 000000000..edbef685f --- /dev/null +++ b/workspace-server/migrations/042_a2a_queue.up.sql @@ -0,0 +1,53 @@ +-- #1870 Phase 1: TASK-level queue for A2A delegations that hit a busy target. +-- +-- Before: when the target workspace's HTTP handler errors (agent busy +-- mid-synthesis — single-threaded LLM loop), a2a_proxy_helpers.go returns +-- 503 with a Retry-After hint, the caller logs activity_type='delegation' +-- status='failed' and moves on. Delegations silently dropped; fan-out +-- storms from leads reach ~70% drop rate. +-- +-- After: same failure triggers an INSERT into a2a_queue with priority=TASK. +-- Workspace's next heartbeat (up to 30s later) drains the queue if capacity +-- allows. Proxy returns 202 Accepted with {"queued": true, "queue_id", ...} +-- instead of 503, caller logs as dispatched-queued. +-- +-- Phase 2 will add INFO (TTL) and CRITICAL (preempt) levels. This table's +-- priority column is wide enough for all three from day one — no migration +-- churn on next phase. + +CREATE TABLE IF NOT EXISTS a2a_queue ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id uuid NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE, + caller_id uuid, + priority smallint NOT NULL DEFAULT 50, -- 100=CRITICAL, 50=TASK, 10=INFO + body jsonb NOT NULL, + method text, + idempotency_key text, + enqueued_at timestamptz NOT NULL DEFAULT now(), + dispatched_at timestamptz, + completed_at timestamptz, + expires_at timestamptz, -- TTL, for future INFO level + attempts integer NOT NULL DEFAULT 0, + status text NOT NULL DEFAULT 'queued' -- queued | dispatched | completed | dropped | failed + CHECK (status IN ('queued','dispatched','completed','dropped','failed')), + last_error text +); + +-- Primary drain-query index: pick oldest highest-priority queued item for a +-- workspace. Partial index on status='queued' keeps the hot path tiny. +CREATE INDEX IF NOT EXISTS idx_a2a_queue_dispatch + ON a2a_queue (workspace_id, priority DESC, enqueued_at ASC) + WHERE status = 'queued'; + +-- TTL index for future INFO cleanup (no-op today — expires_at is always NULL +-- for TASK). Still worth creating now so Phase 2 doesn't need a migration. +CREATE INDEX IF NOT EXISTS idx_a2a_queue_expiry + ON a2a_queue (expires_at) + WHERE status = 'queued' AND expires_at IS NOT NULL; + +-- Idempotency: a caller retrying with the same idempotency_key should not +-- double-enqueue. Partial unique index only on active queue entries so +-- completed/dropped entries don't block future legitimate re-uses. +CREATE UNIQUE INDEX IF NOT EXISTS idx_a2a_queue_idempotency + ON a2a_queue (workspace_id, idempotency_key) + WHERE idempotency_key IS NOT NULL AND status IN ('queued','dispatched');