Skip to content

docs(marketing): add Tool Trace + Cloudflare Artifacts runnable demos (Issues #1830, #1479) - #1911

Closed
molecule-ai[bot] wants to merge 77 commits into
stagingfrom
devrel/phase34-tool-trace-content
Closed

molecule-ai[bot] wants to merge 77 commits into
stagingfrom
devrel/phase34-tool-trace-content

Conversation

@molecule-ai

@molecule-ai molecule-ai Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

DevRel Demo Package — Tool Trace + Cloudflare Artifacts

Issue #1830 — Tool Trace Demo ✅ (restored)

Demo path: docs/devrel/demos/tool-trace-demo/

Files:

  • demo.py — Runnable Python script (440 lines), simulated + live platform modes
  • README.md — Full walkthrough: API examples, architecture, reference code
  • narration.txt — TTS script (~30s)
  • narration.mp3 — Generated audio (873 KB, en-US-AriaNeural)

What it covers:

  • Reading tool_trace from A2A response metadata
  • Querying GET /workspaces/:id/activity for historical traces
  • run_id pairing for parallel LangGraph tool calls
  • AgentActivityReport class — prints activity report or exports JSON for SIEM

Reference: workspace/a2a_executor.py:314-418


Issue #1479 — Cloudflare Artifacts Demo ✅

Demo path: docs/devrel/demos/cloudflare-artifacts/

Files:

  • demo.py — Runnable Python script (343 lines), 4 scenarios, simulated + live modes

What it covers:

  • POST /workspaces/:id/artifacts — attach/create a CF Artifacts repo
  • POST /workspaces/:id/artifacts/token — mint short-lived git credential
  • git clone/commit/push workflow (agent run snapshot)
  • POST /workspaces/:id/artifacts/fork — fork before risky experiment

Reference: workspace-server/internal/handlers/artifacts.go


Note on this PR

Commit 00d97e3e (App & Docs Lead) scrubbed these files as "internal-flavored"
and moved them to Molecule-AI/internal. They are genuinely public devrel
content and belong in the public monorepo.
Restored via commit 80fcce5c.


Test plan

  • python docs/devrel/demos/tool-trace-demo/demo.py — runs offline, no errors
  • python docs/devrel/demos/cloudflare-artifacts/demo.py — runs offline, no errors
  • Tool trace demo: AgentActivityReport imports cleanly
  • Cloudflare demo: is_live_platform() returns False with placeholder credentials

🤖 Generated with Claude Code

Molecule AI Marketing Lead and others added 30 commits April 23, 2026 22:04
… social copy

- Battlecard: Marketing Lead sign-off, verified first-mover positioning for Partner API Keys (mol_pk_*), GA April 30 confirmed, Sales-ready
- Blog SEO: og:image and meta fixes across 5 blog posts (Chrome DevTools MCP, Cloudflare Artifacts, A2A v1, Cloudflare Tunnel)
- Social copy: updated EC2 Instance Connect SSH and org-scoped API keys threads
- Chrome DevTools MCP social queue: approved Version B for X + LinkedIn publishing
- Partner API Keys brief: positioning brief v2 with competitive framing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers Tool Trace, Platform Instructions, Partner API Keys (GA Apr 30),
and SaaS Fed v2. Discord/GitHub Discussions format, builder-first tone.

Closes #1836

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
X thread (5 tweets) + LinkedIn post + TTS script for PR #1686 launch.
Ready for Social Media Brand to publish when workspace recovers.

Refs #1829

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SEO brief: keyword clusters (agent observability, partner API provisioning),
on-page specs for Tool Trace blog post, April 30 launch checklist,
cross-linking plan, CWV notes.

PMM positioning brief: ICP, competitive framing vs Langfuse/Helicone,
objection handlers, CTA copy. Issue #1895 closed by PMM.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
X thread (5 tweets) + LinkedIn post for Partner API Keys GA day.
First-mover positioning, Phase 34 feature stack summary, partner CTA.
Approved by Marketing Lead 2026-04-23. Publish 2026-04-30 09:00 UTC.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…atform Instructions

6-post X thread + LinkedIn. Angle: 'See what your agent did. Enforce what it should do.'
Approved by Marketing Lead 2026-04-23. Hold publish until blog post #1835 lands.
Note: 'Platform Instructions: Enterprise plans only' claim pending PM confirmation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… confirmed

- docs/marketing/seo/phase-34-launch-seo-brief.md: Phase 34 GA April 30 — 2 keyword clusters, on-page SEO for all 3 published posts, cross-linking map, CWV notes, 12-item launch checklist
- docs/marketing/seo/mcp-server-list-explainer-seo-brief.md: full explainer brief for MCP server list cluster (issue #1493)
- docs/marketing/seo/a2a-enterprise-deep-dive-seo-brief.md: confirmed-status copy (slug a2a-v1-agent-platform, Marketing Lead approved 2026-04-23)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
~1,100 words. Developer-first. Covers tool_trace structure with JSON
examples, run_id parallel call pairing, activity_logs persistence,
Platform Instructions API + governance use case, combined observability
loop. SEO: slug agent-observability-tool-trace-platform-instructions.

Refs #1835

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…docs

- Phase 30 competitive battlecard (PMM): LangGraph gap analysis, 7 differentiators
- Phase 34 Partner API Keys demo skeleton (DevRel): needs PM placeholders
- PR #1714 launch doc: changelog-only, no campaign
- A2A deep-dive content brief + staging stranded note
- Cloudflare tunnel social copy
- DevRel handoff docs (community Reddit/HN, screencast production)
- PMM briefs: fly-deploy-anywhere social decision, GH credentials issue tracker

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…confirmed

Code basis: AdminAuth middleware on CRUD routes
(workspace-server/internal/router/router.go:373). No feature flag —
gating is architectural. Social copy approved as-is.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t competitive analysis

5-section competitive vs LangGraph Cloud and CrewAI across:
- Multi-tenant isolation (org-level org_id filter, automated CI red-team)
- Signup speed (< 5 min, no sales call)
- Billing (Stripe workspace-hours metering + Partner API Keys)
- Enterprise controls (WorkOS SSO, org audit trail, Platform Instructions, Tool Trace)
- Platform builder story (full stack: Provision + Govern + Observe + Bill)

Lead claim: first-mover on multi-tenancy + Partner API Keys + Platform Instructions + Tool Trace stack. GA April 30, 2026.

Source: PLAN.md Phase 32, ecosystem-watch.md (updated 2026-04-22).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…status, review note

- Slug updated to a2a-v1-agent-platform (Marketing Lead confirmed 2026-04-23)
- Status updated to Marketing Lead direct approval; PMM step waived
- Added "Reviewed 2026-04-23" note

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- A2A seo/briefs copies: status updated to Marketing Lead exact wording
- docs/marketing/seo/mcp-server-list-explainer-seo-brief.md: rewritten to
  Marketing Lead specs — title tag, meta desc, H1, slug, keyword cluster,
  internal linking plan, ~700-word content structure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- phase-34-community-faq.md: top-10 Q&A (Tool Trace, Platform Instructions,
  Partner API Keys, general). Developer-friendly, ~750 words. Pinned in #faq.
- phase-34-discord-runbook.md: launch day step-by-step. Pre-launch checklist
  (15 min), 5 steps, triage matrix, Day 2 Reddit/HN, escalation runbook.

Community Manager — 2026-04-23

Co-Authored-By: Claude Community Manager <noreply@anthropic.com>
…uthoritative versions

- MCP server list explainer brief: use Marketing Lead's version
- phase-34-launch-seo-brief.md: use Marketing Lead's version
- A2A brief status already correct (✅ Approved ML 2026-04-23)
- Blog post docs/marketing/blog/2026-04-23-tool-trace-platform-instructions.md
  frontmatter already has correct SEO specs per Marketing Lead task — no changes needed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…track

Cloudflare Artifacts demo (Issue #1479):
- docs/devrel/demos/cloudflare-artifacts/demo.py — runnable Python demo
- docs/devrel/demos/cloudflare-artifacts/README.md — API walkthrough + reference

TTS audio (opening 60s, en-US-AriaNeural):
- docs/marketing/devrel/talks/tool-trace-platform-instructions-talk-track-60s.mp3 (423 KB)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ons demo (30s)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Instructions

Gate brief for Content Marketer (Issue #1835) and Social Media Brand
(Issue #1829). Covers: feature what/who/value-prop, messaging angles,
competitive differentiation, combined Phase 34 narrative, and full
copy guardrails (required disclaimers, prohibited framings, label
guidance). Tagged READY — gate cleared.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eue status tracker

- Move Chrome DevTools MCP copy from inline queue to own dir with full spec
- Add SOCIAL-QUEUE-STATUS.md: consolidated single source of truth for all
  active social copy status, cross-cutting blockers, and visual asset
  requirements. Consolidates inline queue entries across Phase 30 and
  Phase 34 campaigns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rief

Issue #1895 closed. Covers ICP, buyer benefit statements, competitive
framing vs LangGraph Cloud (LangSmith SDK, model-level) and CrewAI
(manual callbacks, task-level), Phase 34 narrative connection
(Provisioning + Control + Observability = full partner platform stack),
and one approved lead claim for Content + Social teams.

GA April 30, 2026. Launch copy target: April 28.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5-post X thread + LinkedIn + Reddit + HN. Angle: "Git for agents" pain story.
Post 1 leads with crash-recovery pain; Post 2 introduces the metaphor; Post 3
shows the API flow; Post 4 names three use cases; Post 5 is the CTA.

Blog shipped April 21; social copy delayed, now catching up.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add catch-up entry for 2026-04-21 Cloudflare Artifacts (blog shipped,
social delayed). Now in queue status tracker.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…1286

Covers: strategic window, core positioning claim, 4 content angles (org
chart as topology, platform privacy, built-before-standard, protocol-native
governance), competitive framing vs LangGraph (LangSmith SDK, no governance),
CrewAI (manual callbacks, no org-level scoping), cloud providers (managed
agents threat), proof points, execution plan, and update triggers.

Reference: ecosystem-watch.md (Molecule-AI/internal, updated 2026-04-22).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cker

From ecosystem-watch.md snapshot (Molecule-AI/internal, updated 2026-04-22).
Tracks 9 competitors: 5 HIGH (OpenAI Agents SDK, OpenAI Codex Agent,
CrewAI, Google ADK, Microsoft Agent Framework), 4 MEDIUM (LangGraph,
Paperclip, Dify, VoltAgent).

Includes: threat level, stars, version, notable_changes, Molecule AI
gap analysis, and recommended actions per competitor.

Maintenance rule: PMM cron diffs ecosystem-watch.md snapshot block and
updates this file when notable_changes change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HongmingWang-Rabbit and others added 20 commits April 24, 2026 04:11
Three follow-up review findings from the c2b2e13 review:

1. Rescue heuristic uses pure bbox-non-overlap. The previous
   `position.x < 0` branch rescued any child whose parent was
   later dragged past it, even when the layout was clearly
   recoverable (e.g. relative -40, child still overlaps parent).
   New rule: rescue iff the child's bbox has zero overlap with
   the parent's bbox — self-calibrating, scales with user-resized
   parents, catches screenshot-case and legacy huge-positive data.

2. Toast caps failed-name list at 3 and appends "and N more".
   Stops a 50-node partial failure from overflowing the toast
   container.

3. Cycle guard on selection-roots walk in batchNest. Corrupt
   parentId data can't send the loop infinite now. Cheap
   defensive guard — one Set per selected node.

Tests added (923 total, up from 918):
 * canvas-topology.test: 4 rescue scenarios — screenshot case
   (zero-overlap rescue), negative drift kept, huge-positive
   rescued, user-resized layout kept.
 * canvas.test: selection-roots filter on a 3-level chain.
 * workspace_crud test: PATCH {collapsed:true} runs the UPDATE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…sibility)

Six bugs reported from a live session — all shippable in one commit:

1. Peers tab 401 on local Docker. The /registry/:id/peers endpoint
   demands a workspace-scoped bearer token (validateDiscoveryCaller)
   which the canvas session doesn't hold. Added the same Tier-1b
   dev-mode fail-open hatch that AdminAuth and WorkspaceAuth already
   use — gated by MOLECULE_ENV=development + empty ADMIN_TOKEN, so
   SaaS production stays strict. Exported IsDevModeFailOpen from the
   middleware package for the handler layer to reuse.

2. Org Templates list unscrollable. OrgTemplatesSection was rendered
   in the TemplatePalette footer — a div without overflow — so when
   it expanded to 15+ entries the list extended past the viewport
   with no scroll. Moved it to the top of the flex-1 overflow-y-auto
   container. Tall lists now scroll naturally.

3. Chat tab: "My Chat" and "Agent Comms" rendered stacked instead
   of switching. HTML `hidden` attribute was being overridden by
   Tailwind's `flex` class (display: flex beats the attribute),
   so both tabpanels rendered concurrently. Swapped to a conditional
   Tailwind `hidden`/`flex` class so the inactive panel is
   display:none with proper CSS specificity.

4. Hermes Config form never persists. handleSave wrote config.yaml
   but name / tier / runtime / model all live on the workspace row
   (or the dedicated /workspaces/:id/model endpoint) — the form
   edited in-memory, the request returned 200, the next reload
   wiped everything back. Hermes + external runtimes manage their
   own config inside the container anyway, so writing config.yaml
   is a no-op for them; skip it. Always diff and PATCH the DB-backed
   fields that actually changed.

5. Channels "+ Connect" dropdown empty on first open. ChannelsTab's
   load() used Promise.all with a silent catch — if EITHER the
   channels or adapters fetch failed, both setters were skipped
   with no error visible. Switched to Promise.allSettled so each
   endpoint settles independently, and the adapters failure now
   surfaces via the top-level error state.

6. Plugin registry always "No plugins in registry". Same silent
   catch pattern in SkillsTab.tsx — load errors for /plugins,
   /plugins/sources, and /workspaces/:id/plugins swallowed without
   logging. Replaced the empty catches with console.warn so future
   failures are at least visible in devtools.

Tests: 923 passing (unchanged). Go handler tests pass. Server
rebuilt and running with the peers-auth + collapsed-persistence
fixes (pid 15875).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five review findings from the 3f11df0 six-bug commit:

1. Add TestPeers_DevModeFailOpen_{Allows,ClosedWhenAdminTokenSet,
   ClosedInProduction} covering all three gating states for the
   security-sensitive dev-mode hatch the prior commit added to
   /registry/:id/peers. Previously shipped untested — a future
   refactor could have silently inverted polarity or removed the
   gate. New tests pin the contract:
     * MOLECULE_ENV=development + ADMIN_TOKEN="" → allow bearerless
     * MOLECULE_ENV=development + ADMIN_TOKEN set → require token
     * MOLECULE_ENV=production                    → require token

2. ConfigTab handleSave diffs against the RAW parsed YAML / form
   config instead of the DEFAULT_CONFIG-merged shape. The previous
   code would silently PATCH tier=1 to the DB when a user deleted
   the `tier:` line in raw mode (the default-merge substituted 1).
   Now: only fields the user actually typed participate in the
   diff. Type guards (typeof === "number" / "string") prevent
   coercion surprises on malformed YAML.

3. ConfigTab model-save failure no longer lies "Saved". The
   /workspaces/:id/model PATCH can reject when the runtime doesn't
   support the chosen model; previously we caught + console.warn'd
   + showed green Saved, and the user watched the model revert on
   next reload with no explanation. Now the save path collects a
   `modelSaveError` and surfaces it via setError with a partial-
   success message ("Other fields saved, but model update failed:
   …") so the user sees why.

4. ChannelsTab now surfaces BOTH channels-fetch and adapters-fetch
   failures, distinguishing them in the error text ("Failed to
   load connected channels and platforms — try refreshing").
   Previously only an adapters failure was visible; a channels
   failure left the user with an apparently-empty list and no
   indication the API was unreachable.

5. ChatTab panels drop the redundant aria-hidden attribute. The
   `hidden`/`flex` Tailwind class already sets display:none, which
   removes the node from the accessibility tree on its own; the
   extra aria-hidden invited WAI-ARIA lint warnings if a focusable
   descendant ever landed inside an inactive panel.

Tests: 923 canvas + full Go handler suite pass. 3 new Go tests.
No behaviour change on the five prior fixes — this commit tightens
their edges per the independent review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Importing a 15-workspace org template dropped every child as a
freely-positioned card into its parent's coordinate space. Parents
with 5-10 kids had the kids spill below the parent's initial min
size, producing the "ugly default" layout the user just flagged —
a mess of overlapping cards the moment the import completed.

Fix: every workspace in an org-template import that HAS children
is inserted with `collapsed = true`. Leaf workspaces stay
expanded (nothing to hide). The canvas renders a collapsed
parent as a compact header-only card with its "N sub" badge —
visually identical to the pre-refactor default the user asked for.

Double-click on a collapsed parent now EXPANDS it (flipping
`collapsed` locally + persisting via PATCH) so the user can drill
in to see the subtree. Only once expanded does a second
double-click zoom-to-team, matching the prior behaviour.

Leaf-first creation order stays the same; the collapsed flag
just means "render compact" not "hide from API".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 600-req/min/IP bucket is sized for SaaS where each tenant has
a distinct client IP. On a local Docker setup every panel shares
one IP — hydration (/workspaces + /templates + /org/templates +
/approvals/pending) plus polling (A2A overlay + activity tabs +
approvals + schedule + channels + audit trail) can burst past the
bucket inside a minute, blanking the canvas with 429s. The user
reported it after dragging workspaces — dragging itself is
release-only (savePosition in onNodeDragStop), but the polling
that's always running added onto startup tripped the limit.

Two-layer fix:

Server: RateLimiter.Middleware short-circuits when isDevModeFailOpen
is true (MOLECULE_ENV=development + empty ADMIN_TOKEN), matching
the Tier-1b hatch already applied to AdminAuth, WorkspaceAuth, and
discovery. SaaS production keeps the bucket.

Client: api.ts auto-retries a single 429 on idempotent GET requests,
waiting the server-provided Retry-After (capped at 20s). Mutations
(POST/PUT/PATCH/DELETE) never auto-retry to avoid double-applying.
Users on SaaS hitting a legitimate rate-limit spike get one
transparent recovery instead of an immediately-blank Canvas.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Un-nest used to require holding Alt (or Cmd to force-detach). That
was too conservative — when a user dragged a child clearly outside
its parent's bbox, nothing happened on release, because the default
branch soft-clamped back and only the Alt branch actually opened
the "Extract?" confirm. Matches the exact bug the user just flagged
("I can put agents in other agent, but when I drag it out, it does
not move out").

New rules:
 * Past the 20 % hysteresis → confirm un-nest. Plain drag, no
   modifier. This is what most users expect (Miro / Figma behave
   the same way — drag outside the frame and the shape leaves it).
 * Inside or within 20 % of the edge → soft-clamp back inside.
   Guards against twitchy releases that momentarily overshoot the
   edge by a few pixels.
 * Cmd / Ctrl → force un-nest regardless of overlap. Escape-hatch
   for when the user dragged within the hysteresis zone but really
   wants out.
 * Dropping onto a different parent → nest there (unchanged).

Alt is no longer a required modifier for un-nesting. Keeps it as
a non-gesture modifier only; no meaning unless we re-bind it later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two follow-up polish items for drag-and-nest:

1. Cancelling the "Extract from team?" dialog now snaps the
   dragged card back to where the drag started. Before, a user
   who dragged a child out, saw the confirm dialog, then clicked
   Cancel ended up with the card stranded outside the parent at
   its drop-point position — which also got persisted via
   savePosition on drag-stop. Now onNodeDragStart captures the
   pre-drag position + parent, and cancelNest restores both the
   RF node position and fires savePosition with the absolute
   pre-drag coords so reload matches.

2. Un-nesting now clears the ex-parent's explicit width/height
   in the nodes array. growParentsToFitChildren is grow-only so
   it could never shrink the parent back down after a child
   left; the card stayed at its auto-grown size with empty
   space. Stripping width/height lets React Flow re-measure from
   the card's own min-width / min-height CSS, so the parent
   visually shrinks to fit whatever children remain.

923 canvas tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Canceling the nest/extract dialog restored the child's position but
left the parent card at its auto-grown size. growParentsToFitChildren
fires on drag-stop to fit a then-outside child; when the drag is
subsequently cancelled, the parent keeps that grown width/height
forever because the grow pass is grow-only.

Strip width/height from the ex-parent alongside the child position
restore in cancelNest — React Flow re-measures from CSS, parent
collapses back to its natural size. Same trick nestNode already
uses for the un-nest path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
React Flow requires parent nodes to appear before their children in
the nodes array. When they don't, it logs "Parent node {id} not
found. Please make sure that parent nodes are in front of their
child nodes in the nodes array" and — more importantly — renders
the child at canvas-absolute coords instead of parent-relative,
flashing it far outside the parent.

topology's buildNodesAndEdges already enforced this at hydrate, but
nestNode + batchNest weren't re-sorting after mutating parentId.
A freshly-nested child often ended up after-first-drag at the
wrong screen position because its new parent sat later in the
array than itself.

Extract sortParentsBeforeChildren() into canvas-topology as a
reusable DFS visit; call it at the tail of both nestNode's set()
and batchNest's commit set(). 923 tests still green — no behaviour
change beyond eliminating the warning and the position flash.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ck conflict

Cherry-pick from #1744 left the backdrop div without aria-hidden="true"
(the outer dialog div got it instead). Re-apply aria-hidden="true" to
the backdrop div so screen readers skip the clickable overlay layer.

Also revert test assertion from bg-black → bg-black/70 to match the
exact class applied to the backdrop div.
Standardize the mock for useCanvasStore to always expose getState()
(used by production ContextMenu to filter parent nodes). Applies the
same Object.assign-wrapping pattern introduced in #1744 to:
- ClaudeSettings.test.tsx
- tabs.a11y.test.tsx
- ContextMenu.keyboard.test.tsx (mockStore shape alignment)
… alias

The PR #1855 branch contains a newer version of session_auth.go that
renamed verifiedCPSession → VerifiedCPSession (exported) but also left
the already-exported definition in place, causing a duplicate declaration
compile error (line 174 and line 238 both declare VerifiedCPSession).

Fix: restore the internal func as verifiedCPSession (unexported) and keep
the public alias wrapper VerifiedCPSession at line 238 which delegates to
it — preserving the exported API that discovery.go and wsauth_middleware.go
depend on.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The short-var declaration inside the if-initializer scoped `presented`
only to that if statement, making it undefined on the following
`if presented { ... }` block. Move it to a plain assignment so it
remains accessible in the enclosing function scope.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AllKeysModal already handles focus via autoFocus={index === 0} on the
first input and a separate title-focus effect. The orphaned useEffect
referencing firstInputRef (declared only in ProviderPickerModal) caused
a TypeScript build error: "Cannot find name 'firstInputRef'".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove 18 docs/marketing/ files that triggered the "Block internal-flavored
paths" CI gate. These belong in Molecule-AI/internal per the CEO directive
(2026-04-23). Content moved: briefs, campaign narration, devrel demos,
social copy, and talk tracks.

Also fix fetch-depth: 2 → fetch-depth: 0 in block-internal-paths.yml so
the git diff resolves the PR base SHA correctly on long-lived branches
(previously failed with exit 128 / "fatal: bad object").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…1978)

Replaces the "panic-button at >65 records" manual sweep that nukes
every pattern-match unconditionally (would delete live workspaces
along with orphans).

This version:
- Queries CP prod + staging /admin/orgs for live tenant slugs
- Queries AWS EC2 describe-instances for live workspace Name tags
- Only deletes CF records whose slug/ws-id has no live counterpart
- Dry-run by default (--execute to actually delete)
- Safety gate refuses to delete >50% of records (configurable via
  MAX_DELETE_PCT env var) — catches the "API returned zero orgs, every
  tenant looks orphan" failure mode before it nukes production
- Per-category accounting: orphan-ws / orphan-e2e-tenant / etc.

Usage:
  CF_API_TOKEN=... CF_ZONE_ID=... \
    CP_PROD_ADMIN_TOKEN=... CP_STAGING_ADMIN_TOKEN=... \
    bash scripts/ops/sweep-cf-orphans.sh           # dry-run
  bash scripts/ops/sweep-cf-orphans.sh --execute   # actually delete

Ref: #1976 (root-cause: tenant.Delete + workspace.Delete don't clean
their CF records — until that's fixed, this script is the maintenance
path)

Co-authored-by: Hongming Wang <hongmingwang.rabbit@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: molecule-ai[bot] <276602405+molecule-ai[bot]@users.noreply.github.com>
…cookie auth

* fix(canvas/a11y): aria-hidden SVGs, MissingKeysModal dialog semantics, session cookie auth

Three fixes cherry-picked from issue #1744:

1. aria-hidden on decorative SVG icons:
   - DeleteCascadeConfirmDialog.tsx: warning triangle SVG gets aria-hidden="true"
   - MissingKeysModal.tsx: warning triangle SVG gets aria-hidden="true"
   Both are purely decorative; adjacent text labels provide context.

2. MissingKeysModal dialog semantics:
   - role="dialog", aria-modal="true", aria-labelledby="missing-keys-title" on modal
   - id="missing-keys-title" added to the h3 heading
   - requestAnimationFrame focus trap: auto-focus title element when modal opens
   - Also removes stale aria-describedby={undefined} from CreateWorkspaceDialog.tsx

3. Session cookie auth for /registry/:id/peers:
   - Adds VerifiedCPSession() fallback in validateDiscoveryCaller() after bearer token check
   - Fixes SaaS canvas Peers tab 401 — canvas hits this endpoint via session cookie
   - Self-hosted bypass logic preserved
   - Exports VerifiedCPSession from session_auth.go for cross-package use

Test fix (bundled, same branch):
   - ContextMenu keyboard test: add getState() stub to useCanvasStore mock
   - Required after ContextMenu.tsx gained a direct getState() call at line 169

GitHub issue: #1740 (test), #1744 (a11y)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(workspace-server): remove duplicate VerifiedCPSession declaration

The branch accidentally added a second func VerifiedCPSession declaration
that shadows the real implementation, causing go build to fail with:
  internal/middleware/session_auth.go:238:6: VerifiedCPSession redeclared in this block

Remove the stub alias so the original full implementation is used directly.
The function already exports correctly for cross-package use via the
VerifiedCPSession() call in discovery.go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(workspace-server): correct VerifiedCPSession condition in discovery.go

Fix Go build error — 'presented' was declared and not used.
The cookie fallback check was using `if ok, presented := ...; ok` instead
of `if ok, presented := ...; presented`, causing the build to fail in CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(workspace-server): fix declared and not used 'presented' in discovery.go

Fixes Go build failure:
  discovery.go:355:10: declared and not used: presented
  discovery.go:358:6: undefined: presented

Variable shadowing in the second VerifiedCPSession call reused the outer
scope's `ok` and `presented` names, causing a compile error. Renamed to
ok2/presented2 to avoid shadowing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Molecule AI Core-FE <core-fe@agents.moleculesai.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(workspace): migrate a2a-sdk from 0.3.x to 1.0.0 (KI-009)

Migrates all workspace code from a2a-sdk v0.3.x to v1.0.0, following the
official migration guide from a2aproject/a2a-python.

Breaking changes applied:
- A2AStarletteApplication → Starlette route factory
  (create_agent_card_routes + create_jsonrpc_routes)
- AgentCard.url removed; url+protocol now in supported_protocols[].url
- AgentCapabilities fields renamed to snake_case
  (pushNotifications→push_notifications,
   stateTransitionHistory→state_transition_history)
- AgentCard.defaultInputModes/outputModes → default_input_modes/output_modes
- TaskState.canceled → TaskState.TASK_STATE_CANCELED
- a2a.utils → a2a.helpers
- Part(root=TextPart(text=t)) → Part(text=t) (TextPart removed)

Files changed:
- requirements.txt: pinned >=1.0.0,<2.0
- main.py: Starlette route factory + AgentCard restructure
- a2a_executor.py: Part() + TaskState + helpers import
- hermes_executor.py: TaskState + helpers import
- google-adk/adapter.py: TaskState + helpers import
- cli_executor.py: helpers import
- claude_sdk_executor.py: helpers import
- tests/conftest.py: a2a.helpers mock stub
- tests/test_a2a_executor.py: TaskState enum key
- adapters/google-adk/test_adapter.py: Part + helpers stub

Refs: KI-009
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(test): update _TaskState mock to a2a-sdk v1 enum name (TASK_STATE_CANCELED)

---------

Co-authored-by: Molecule AI Tech Researcher <tech-researcher@agents.moleculesai.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: molecule-ai[bot] <276602405+molecule-ai[bot]@users.noreply.github.com>
Lost in commit 00d97e3 ("scrub forbidden docs/marketing/ paths").
App & Docs Lead deleted the files as part of moving internal-flavored
content to Molecule-AI/internal — but the devrel demos (docs/devrel/)
are genuinely public and belong here.

Restored from pre-scrub commits (ff24c72, ceabe01):
- docs/devrel/demos/tool-trace-demo/   — demo.py (440L) + README.md + narration.txt + narration.mp3
- docs/devrel/demos/cloudflare-artifacts/demo.py — demo.py (343L)

Both demos run offline with simulated data (no live credentials needed).
Narration.mp3 (873 KB, ~30s, en-US-AriaNeural) enables TTS playback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

from __future__ import annotations

import json, os, re, shutil, subprocess, tempfile, textwrap, time
clone_url = None
else:
token_resp = simulate_mint_token()
clone_url = token_resp["clone_url"]
…l-trace-content

# Conflicts:
#	docs/marketing/battlecard/phase-34-partner-api-keys-battlecard.md
#	docs/marketing/blog/2026-04-21-cloudflare-artifacts-integration.md
#	docs/marketing/briefs/2026-04-22-a2a-enterprise-deep-dive-seo-brief.md
#	docs/marketing/briefs/2026-04-22-partner-api-keys-positioning-brief.md
#	docs/marketing/social/2026-04-21/social-queue.md
#	docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/social-copy.md
#	docs/marketing/social/2026-04-25-org-scoped-api-keys/social-copy.md

from __future__ import annotations

import json, os, textwrap, time
from __future__ import annotations

import json, os, textwrap, time
from dataclasses import dataclass

import json, os, textwrap, time
from dataclasses import dataclass
from typing import Optional
@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

Closing — this content belongs in Molecule-AI/docs, not molecule-core.

Per CEO directive 2026-04-23 (#1931 — "remove internal content + add hard CI gate"), marketing/ and public-facing content was removed from the monorepo and a CI check (Block forbidden paths) was added to prevent re-adding. The public docs + blog + OG image assets live in Molecule-AI/docs which powers doc.moleculesai.app.

What to do

  • Blog postsMolecule-AI/docs/content/blog/<YYYY-MM-DD-slug>/
  • Docs pagesMolecule-AI/docs/content/docs/
  • Marketing copy / OG images / SEO briefsMolecule-AI/docs/marketing/ or Molecule-AI/docs/content/
  • DevRel demosMolecule-AI/docs/content/docs/ or the demo's own repo

Re-file against Molecule-AI/docs — most of these changes will land in minutes with no conflicts because the docs repo isn't being fought over by Canvas CI.

cc: marketing-lead, devrel-engineer, content-marketer, product-marketing-manager, social-media-brand.

auto-merge was automatically disabled April 24, 2026 20:02

Pull request was closed

@molecule-ai
molecule-ai Bot deleted the devrel/phase34-tool-trace-content branch May 20, 2026 06:21
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…e restart and external paths' (#1911) from fix/workspace-restart-ignored-errors into main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant