Commit Graph

1070 Commits

Author SHA1 Message Date
Hongming Wang
99c1ff686e Merge pull request #921 from Molecule-AI/feat/issue-753-audit-trail-panel
feat(canvas): audit trail visualization panel (closes #753)
2026-04-17 21:44:58 -07:00
Hongming Wang
3e30f4e5fd Merge pull request #915 from Molecule-AI/feat/issue-852-hermes-runtime
feat(plugins): extend runtime declarations to hermes — 5 SKILL.md plugins
2026-04-17 21:44:55 -07:00
Hongming Wang
5bae8014ce Merge pull request #879 from Molecule-AI/fix/canvas-test-fixture-budgetlimit
fix(canvas): repair TypeScript fixture drift in BudgetLimit and test factories
2026-04-17 21:44:52 -07:00
Hongming Wang
eb9f063539 Merge pull request #925 from Molecule-AI/fix/issue-893-hitl-audit-log
fix(hitl): emit log_event() on approval grant and denial — Art. 14 audit gap (closes #893)
2026-04-17 21:43:00 -07:00
Hongming Wang
d7324fdbfd Merge pull request #913 from Molecule-AI/fix/issue-834-commit-memory-secret-scrub
fix(security): redact secrets from commit_memory before persistence (closes #834)
2026-04-17 21:42:57 -07:00
Hongming Wang
5e0795e4ea Merge pull request #849 from Molecule-AI/docs/partner-api-keys
docs: Partner API Keys — programmatic org management (Phase 34)
2026-04-17 21:41:46 -07:00
Hongming Wang
b0eed5135f fix: resolve PLAN.md merge conflict — keep both Phase 34 and Phase 36
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 21:41:32 -07:00
Hongming Wang
afe537c9b0 Merge pull request #927 from Molecule-AI/chore/eco-watch-2026-04-18
chore(eco-watch): 2026-04-18 daily sweep — chrome-devtools-mcp + craft-agents-oss + BLOCK MemPalace
2026-04-17 21:40:29 -07:00
Hongming Wang
907d4cc154 Merge pull request #880 from Molecule-AI/docs/safe-mcp-advisory-2026-04-17
docs(security): SAFE-MCP internal advisory 2026-04-17
2026-04-17 21:40:26 -07:00
Hongming Wang
581ccefe89 Merge pull request #922 from Molecule-AI/infra/issue-894-anthropic-api-key-docs
docs(infra): document ANTHROPIC_API_KEY as required global secret (closes #894)
2026-04-17 21:40:23 -07:00
Hongming Wang
abd4710298 Merge pull request #934 from Molecule-AI/feat/cloudflare-tunnel-per-tenant
docs: staging environment design + Phase 36 + Tunnel migration plan
2026-04-17 21:40:14 -07:00
rabbitblood
3bd96caa8a fix(provisioner): strip CRLF from .sh/.py/.md in CopyTemplateToContainer
Second layer of the permanent CRLF fix. The Go provisioner now strips
\r\n → \n from shell, Python, and markdown files during the tar
copy into containers.

Three-layer CRLF defense:
1. Provisioner (this) — strips during template copy
2. Entrypoint.sh — strips at boot (safety net)
3. Runtime plugin installer (builtins.py) — strips during plugin install

Any one layer is sufficient. All three together make CRLF impossible.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 21:37:55 -07:00
Hongming Wang
a873ae0eae docs: staging environment design + Phase 36 plan
Full staging environment that mirrors production. Every infra change
ships to staging first before promotion. Gates Phase 33 (Tunnel) and
Phase 35 (security hardening).

Components: Railway staging env, Neon branch, staging DNS, tagged
Docker images, promotion workflow, automated smoke tests.

Also marks Phase 33 as migrating from Worker to Cloudflare Tunnel
(issue #933), prerequisite: staging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:37:11 -07:00
Hongming Wang
a8b4a77ce5 Merge pull request #930 from Molecule-AI/fix/ci-path-filter-merge-commits
fix(ci): path filter for merge commits — use event.before
2026-04-17 20:23:44 -07:00
Hongming Wang
e093f121f0 fix(ci): use github.event.before for push diff, fetch-depth 0
HEAD~1 doesn't work for merge commits. Use github.event.before (the
previous main tip) for push events and github.event.pull_request.base.sha
for PRs. fetch-depth: 0 ensures both SHAs are available.

Fallback: if BASE is empty (new branch), run all jobs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:23:28 -07:00
Molecule AI Backend Engineer
384bea6102 feat(checkpoints): Temporal crash-resume — GET latest checkpoint + history injection (#837, closes #583)
Adds the final step (3/3) of the durable Temporal resume path:

Platform (Go):
- `Latest` handler: GET /workspaces/:id/checkpoints/latest returns the
  most recently completed step across all workflows for the workspace,
  ordered by completed_at DESC. Returns 404 when no checkpoints exist.
- Router: registers the new route BEFORE the wildcard :wfid route to
  avoid shadowing; callerMismatch guard enforces workspace isolation.
- 4 new unit tests: 200, 500, 404 (ErrNoRows), and 403 (caller mismatch).

Workspace runtime (Python):
- `_fetch_latest_checkpoint()`: non-fatal async helper that GETs the
  new endpoint and returns the parsed dict, or None on 404 / any error.
- `TemporalWorkflowWrapper.run()`: on startup, fetches the latest
  checkpoint and prepends a synthetic [system, ...] entry to the
  serialised AgentTaskInput.history so the agent is aware of its prior
  crash state before receiving the current task.
- 4 new pytest tests: 404→None, 200→dict, exception→None (non-fatal
  contract), and end-to-end injection into AgentTaskInput.history.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 03:22:31 +00:00
Hongming Wang
ee8b8af962 Merge pull request #928 from Molecule-AI/fix/ci-path-filter-macos
fix(ci): replace dorny/paths-filter with git diff — unblocks all CI
2026-04-17 20:16:55 -07:00
Hongming Wang
310fc56f96 fix(ci): replace dorny/paths-filter with git diff (macOS compat)
dorny/paths-filter uses Docker internally which doesn't work on the
self-hosted macOS arm64 runner — every CI run since the path filter
change has failed with no jobs.

Replace with a simple git diff against HEAD~1 that checks path prefixes.
Same behavior, no Docker dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:16:39 -07:00
Molecule AI Research Lead
8930488690 chore(eco-watch): resolve merge conflict — keep BLOCKED MemPalace + run b entries
Remote had the pre-fraud-audit MemPalace WATCH entry. Resolved by keeping
HEAD: BLOCKED/FRAUD verdict (SA audit 2026-04-18) plus the two new run-b
entries (chrome-devtools-mcp, craft-agents-oss).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 03:14:23 +00:00
Molecule AI Research Lead
f0a1bff27f chore(eco-watch): add chrome-devtools-mcp + craft-agents-oss — 2026-04-18 run b
Two new entries from daily sweep (TR GitHub trending + CI social feeds):

- chrome-devtools-mcp (ChromeDevTools/chrome-devtools-mcp, 35.9k★): Official
  Google Chrome DevTools MCP server — 29 tools for browser control, network
  inspection, Lighthouse audits. Strong MCP adoption signal from Google.
  GH #926 filed: add as bundled MCP server option in workspace templates.

- craft-agents-oss (lukilabs/craft-agents-oss, 4.3k★): Electron desktop app
  on Claude Agent SDK — multi-session inbox, 3-tier permissions, MCP support.
  Single-user desktop vs. Molecule's multi-tenant org-graph. UX reference for
  approval queue / permission tier UI.

CI sweep clean (no additional findings). RevoClaw near-miss logged (outside
24h window, no public repo yet).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 03:12:59 +00:00
Molecule AI Backend Engineer
04e2f37b95 fix(hitl): emit log_event() on approval grant and denial — Art. 14 audit gap (closes #893)
The @requires_approval decorator and request_approval() call executed the
approval gate correctly but never wrote the outcome to the activity log.
EU AI Act Article 14 requires documented evidence that HITL measures were
exercised — the missing log_event() calls meant GET /workspaces/:id/activity
could not surface HITL gate outcomes.

Add log_event() at both resolution points in the requires_approval wrapper:
- Denial: event_type="hitl", action="approve", outcome="denied", actor=decided_by
- Grant:  event_type="hitl", action="approve", outcome="granted", actor=decided_by

Both calls follow the existing try/except pattern used for audit calls elsewhere
in hitl.py so a missing audit module never blocks the approval flow.

Tests: TestRequiresApproval.test_logs_hitl_denied_event and
test_logs_hitl_approved_event verify log_event is called with the correct
outcome on each resolution path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 03:10:26 +00:00
Hongming Wang
7e8eff2fe5 Merge pull request #924 from Molecule-AI/docs/session-retrospective-2026-04-17
docs: SaaS buildout retrospective + Phase 35 hardening plan
2026-04-17 20:10:02 -07:00
Hongming Wang
da0be04a19 docs: session retrospective + Phase 35 hardening plan
Full retrospective of the 2026-04-16/17 SaaS buildout session:
- What was done (infra migration, 40+ PRs, 5 issues, 4 docs, 1 new repo)
- What should NOT have been changed (wildcard DNS churn, AdminAuth shortcut)
- Security concerns (8 items, 2 CRITICAL)
- Workflow gaps (registration, boot time, CI)
- Tests needed (automated + manual + security)

Phase 35 in PLAN.md covers production hardening follow-ups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:08:39 -07:00
638427e01b docs(infra): document ANTHROPIC_API_KEY as required global secret (closes #894)
- Add comment to .env.example explaining ANTHROPIC_API_KEY must be set
  as a *global* secret (not just workspace-level) so SDK-direct workspaces
  (e.g. molecule-hitl, hermes) receive it without 401 errors
- Add ANTHROPIC_API_KEY to saas-secrets.md secret map with context on
  why global propagation matters
- Add full rotation procedure section (generate → PUT /settings/secrets
  → verify restart → revoke old key) with blast-radius note

Closes #894

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 03:03:37 +00:00
rabbitblood
eabca3679e fix: auto-post only to Slack, never Telegram
BroadcastToWorkspaceChannels now filters channel_type='slack'.
Telegram is CEO-only — explicit escalations via agent's outbound call,
never auto-posted from cron output. PM's routine pulses and agent
errors were spamming the CEO's Telegram.

PM's Telegram channel stays enabled for POLLING (inbound CEO messages)
but BroadcastToWorkspaceChannels skips it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 19:04:31 -07:00
Molecule AI Research Lead
ab11c20730 chore(eco-watch): BLOCK MemPalace — coordinated fraud (SA audit 2026-04-18)
SA forensic audit found: 89% bot-farmed stars (42k of 47.6k), malware
domain mempalace.tech, deleted PyPI maintainer (supply-chain risk),
unpatched ChromaDB RCE (#6717), non-existent PyPI package (squattable),
unsafe HuggingFace pickle loading, and crypto pump-and-dump association.
Verdict changed from WATCH to BLOCKED/FRAUD. GH #912 plugin proposal
is closed per audit verdict.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:48:03 +00:00
Molecule AI Research Lead
806ef6403c chore(eco-watch): add MemPalace + update Google ADK — 2026-04-18 run a
- MemPalace (milla-jovovich/mempalace, 47.6k★, MIT, Python): local-first agent
  memory using Method of Loci; 29 MCP tools; 96.6% R@5 on LongMemEval; native
  Claude Code .claude-plugin integration. Verdict: WATCH
- Google ADK: update to v1.31.0 (Apr 17 2026) — multi-language parity
  (Python/TS/Java/Go), native A2A (full protocol, Linux Foundation standard).
  Platform gaps confirmed open (no scheduling, no cross-agent HITL).
  Verdict: WATCH maintained with enhanced escalation triggers.
2026-04-18 01:47:20 +00:00
molecule-ai[bot]
c65150edf6 Merge pull request #891 from Molecule-AI/fix/issue-826-smol-executor-env-sanitization
feat(security): denylist env sanitization + safe messaging for smolagents
2026-04-18 01:44:26 +00:00
molecule-ai[bot]
8088c1eeb0 Merge pull request #873 from Molecule-AI/fix/issue-854-eject-tooltip
fix(canvas): restore title tooltip on TeamMemberChip eject button alongside aria-label
2026-04-18 01:43:32 +00:00
e14ed86e05 Merge branch 'main' of https://github.com/Molecule-AI/molecule-core into fix/issue-854-eject-tooltip
# Conflicts:
#	canvas/src/components/WorkspaceNode.tsx
2026-04-18 01:43:00 +00:00
molecule-ai[bot]
81944621a9 Merge pull request #802 from Molecule-AI/chore/eco-watch-2026-04-17-i
chore(eco-watch): smolagents WATCH verdict + Managed Agents entry — 2026-04-17 run i
2026-04-18 01:34:57 +00:00
molecule-ai[bot]
9d2f9edff3 Merge pull request #906 from Molecule-AI/fix/a11y-audit-902-905
fix(a11y): resolve accessibility issues #902–#905 (aria-pressed, aria-expanded, alertdialog, ID sanitisation)
2026-04-18 01:34:47 +00:00
2d530c80cf fix(gate-6): merge main into fix/a11y-audit-902-905 — resolve 7 conflicts
Conflicts arose because PR #892 base commits (MemoryInspectorPanel creation,
A2A overlay) had already landed on main via a different merge path, and
last-tick merges (#876, #888) had modified Toolbar, SidePanel, and test
fixtures.

Resolution strategy:
- Toolbar.tsx, SidePanel.tsx, Canvas.a11y.test.tsx, Canvas.pan-to-node.test.tsx,
  MemoryInspectorPanel.test.tsx: take main (strictly newer, already contains
  the branch's A2A overlay content plus subsequent a11y/UX fixes)
- MemoryInspectorPanel.tsx: take main (543 lines with semantic search) + apply
  sanitizeId() helper from #904 + update bodyId prefix to mem-body-
- DetailsTab.tsx: take main (has #875 Field/useId + #878 deleteButtonRef/focus)
  + apply alertdialog structure from #905 while preserving focus management

Mechanical conflict resolution by triage-agent; no logic changes beyond the
four a11y fixes already in the branch (#902-#905).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:34:00 +00:00
Molecule AI Frontend Engineer
6f522fb20a docs(plugins): record hermes compat for 5 SKILL.md plugins (issue #852)
Documents agentskills.io v0.8.0 raw-drop hermes compatibility and
the before/after runtimes table for the five SKILL.md-only plugins.
Includes links to the companion draft PRs in each plugin repo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:25:31 +00:00
molecule-ai[bot]
fc7317d5cd Merge pull request #875 from Molecule-AI/fix/canvas-a11y-configtab-detailstab-htmlfor
fix(canvas): htmlFor/id association in ConfigTab + DetailsTab inputs
2026-04-18 01:24:42 +00:00
f5bab93630 Merge branch 'main' of https://github.com/Molecule-AI/molecule-core into fix/canvas-a11y-configtab-detailstab-htmlfor
# Conflicts:
#	canvas/src/components/tabs/DetailsTab.tsx
2026-04-18 01:24:15 +00:00
5812b43de5 fix(gate-6): reconcile DetailsTab.tsx import — merge useRef (#878) with useId/cloneElement (#875)
PR #878 landed before this branch and added useRef + deleteButtonRef focus-
management to DetailsTab.tsx. This commit combines that import with the
useId/cloneElement import added here, and preserves the Field component
htmlFor/id wiring from this PR unchanged.

Mechanical conflict resolution by triage-agent; no logic changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:22:08 +00:00
molecule-ai[bot]
ded7dc777c Merge pull request #888 from Molecule-AI/fix/canvas-a11y-sidepanel-resize-keyboard
fix(canvas): a11y — SidePanel keyboard resize, MemoryEntryRow aria-controls, contrast + ChatTab error banner
2026-04-18 01:20:02 +00:00
molecule-ai[bot]
913bcd5c18 Merge pull request #887 from Molecule-AI/fix/canvas-a11y-conversation-trace-modal
fix(canvas): a11y — migrate ConversationTraceModal to Radix Dialog with aria-label
2026-04-18 01:19:57 +00:00
molecule-ai[bot]
86b2016a69 Merge pull request #878 from Molecule-AI/fix/canvas-a11y-detailstab-delete-confirm
fix(canvas): a11y improvements to DetailsTab delete confirmation dialog
2026-04-18 01:19:52 +00:00
molecule-ai[bot]
7fd217f93f Merge pull request #877 from Molecule-AI/fix/canvas-a11y-emptystate-role-alert
fix(canvas): add role=alert to empty-state error messages
2026-04-18 01:19:48 +00:00
molecule-ai[bot]
cbd92937d5 Merge pull request #876 from Molecule-AI/fix/canvas-a11y-toolbar-aria-label
fix(canvas): add aria-label to Toolbar icon buttons
2026-04-18 01:19:44 +00:00
molecule-ai[bot]
871e6bbcb7 Merge pull request #874 from Molecule-AI/fix/canvas-a11y-onboarding-aria-live
fix(canvas): add aria-live region to onboarding step transitions
2026-04-18 01:19:36 +00:00
Hongming Wang
0faced1c68 Merge pull request #900 from Molecule-AI/fix/ci-go-mod-replace
fix(ci): remove go.mod replace /plugin — unblocks all CI
2026-04-17 18:17:11 -07:00
Molecule AI Research Lead
8ed2df7187 chore(eco-watch): add MemPalace + update Google ADK — 2026-04-18 run a
- MemPalace (milla-jovovich/mempalace, 47.6k★, MIT, Python): local-first agent
  memory using Method of Loci; 29 MCP tools; 96.6% R@5 on LongMemEval; native
  Claude Code .claude-plugin integration. Verdict: WATCH
- Google ADK: update to v1.31.0 (Apr 17 2026) — multi-language parity
  (Python/TS/Java/Go), native A2A (full protocol, Linux Foundation standard).
  Platform gaps confirmed open (no scheduling, no cross-agent HITL).
  Verdict: WATCH maintained with enhanced escalation triggers.
2026-04-18 01:15:44 +00:00
Molecule AI Frontend Engineer
6d59be1b6c fix(a11y): DetailsTab — use role=alertdialog for delete confirmation (#905)
role="alert" is for passive announcements. A delete confirmation with
Confirm/Cancel action buttons requires a user response, which is the
semantics of role="alertdialog" (interactive dialog requiring response).

- Replace role="alert" with role="alertdialog" + aria-modal="true"
- Add aria-labelledby="delete-confirm-title" for an accessible name
- Add <h3 id="delete-confirm-title"> as the labelling element
  ("Confirm deletion") so AT announces the dialog purpose on focus

Closes #905

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:14:51 +00:00
Molecule AI Frontend Engineer
5d1e297231 fix(a11y): MemoryInspectorPanel — sanitise bodyId, add aria-controls (#904)
Memory keys can contain characters like [ ] / : . # and spaces that make
invalid HTML id values (breaks CSS selectors and ARIA id-ref lookups).

- Add sanitizeId() helper: replaces non-alphanumeric chars with hyphens,
  collapses consecutive hyphens, strips leading/trailing hyphens
- Compute bodyId = "mem-body-{sanitizeId(entry.key)}" in MemoryEntryRow
- Set id={bodyId} on the expanded body container
- Set aria-controls={bodyId} on the toggle button so AT can navigate
  directly between the button and its controlled panel

Closes #904

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:14:35 +00:00
Molecule AI Frontend Engineer
377a0802b2 fix(a11y): ActivityTab — aria-pressed on filter pills and auto-refresh (#903)
- Add aria-pressed={filter === f.id} to every filter pill button so AT
  announces which filter is currently active
- Add aria-pressed={autoRefresh} to the auto-refresh toggle so AT
  announces the live/paused state when the button is activated

Closes #903

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:14:10 +00:00
Molecule AI Frontend Engineer
4cce1a7f1e fix(a11y): MemoryTab — role=alert, labelled inputs, aria-expanded (#902)
- Add role="alert" to the global error banner and the inline add-form
  error message so screen readers announce errors immediately on render
- Add aria-label to all three add-form inputs (key / value / TTL) so
  every form control has an accessible name (was flagged as unlabelled)
- Add aria-expanded={expanded === entry.key} to each entry toggle button
  so AT announces collapsed/expanded state on activation

Closes #902

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:13:56 +00:00
Molecule AI Frontend Engineer
18caa0f6f4 fix(a11y): add role=alert to MemoryInspectorPanel error banner (#901)
The error banner div introduced in the MemoryInspectorPanel (PR #892)
was missing role="alert", regressing the a11y standard established in
PR #877 / issue #830. Screen readers now announce the error immediately
on render.

Closes #901

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 01:12:01 +00:00