Commit Graph

748 Commits

Author SHA1 Message Date
667c72e964 docs(glossary): add GitHub Awesome Copilot disambiguation section
Adds a dedicated section mapping the four overlapping terms (Skills,
Plugins, Agents, Hooks) plus Instructions and Agentic Workflows between
awesome-copilot and Molecule vocabulary.  Closes #734.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 16:27:41 +00:00
molecule-ai[bot]
705c0a46ce
Merge pull request #763 from Molecule-AI/feat/issue-733-agents-md-impl
feat(#733): implement AGENTS.md auto-generation
2026-04-17 16:21:58 +00:00
molecule-ai[bot]
7029da28d0
Merge pull request #758 from Molecule-AI/docs/issue-747-safe-mcp-audit
docs(security): SAFE-MCP threat model audit (#747)
2026-04-17 16:21:39 +00:00
molecule-ai[bot]
2252e16f5f
Merge pull request #764 from Molecule-AI/chore/eco-watch-2026-04-17-f
chore(eco-watch): add mcp-agent — 2026-04-17
2026-04-17 16:21:35 +00:00
molecule-ai[bot]
0f94fb2443
Merge pull request #760 from Molecule-AI/refactor/issue-741-extract-medo-plugin
refactor(#741): extract medo.py from builtin_tools to opt-in plugin
2026-04-17 16:21:32 +00:00
c092302712 fix(gate-6): restore claude-opus-4-7 default — reverted by pre-#743 branch
PR #763 (feat/issue-733-agents-md-impl) branched before PR #743 landed the
claude-opus-4-7 model default upgrade. config.py still had the old
claude-sonnet-4-6 default, which would have silently regressed the upgrade.

Restore both occurrences:
- WorkspaceConfig.model default: claude-sonnet-4-6 → claude-opus-4-7
- load_config() fallback: claude-sonnet-4-6 → claude-opus-4-7

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 16:21:04 +00:00
molecule-ai[bot]
a67375d22f feat(#733): implement AGENTS.md auto-generation
Turns the QA TDD spec from PR #755 GREEN: all 14 tests pass.

Changes:
- workspace-template/agents_md.py (new): generate_agents_md(config_dir, output_path)
  Writes AAIF-compliant AGENTS.md with name, role, description, A2A endpoint,
  and MCP tools sections. AGENT_URL env var overrides the derived localhost URL.
  Falls back to description when role is absent (graceful legacy compat).
  Always overwrites — no stale-file guard.

- workspace-template/config.py: add role field to WorkspaceConfig
  New top-level field `role: str = ""` with load_config support.
  Falls back to description in agents_md.py for backward compat.

- workspace-template/main.py: wire generate_agents_md into startup (step 1a)
  Fires after load_config + preflight. Non-fatal: exception is caught and
  printed as a warning so a bad /workspace mount never kills the agent.

- workspace-template/tests/test_agents_md.py (new): pulled from PR #755 branch

Test results:
  pytest tests/test_agents_md.py -v  → 14 passed  (was: 14 RED / import error)
  pytest (full suite)                → 1044 passed, 2 xfailed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 16:21:04 +00:00
molecule-ai[bot]
8a00c338ee
feat(#733): implement AGENTS.md auto-generation 2026-04-17 16:20:39 +00:00
Hongming Wang
b7072d87f1
Merge pull request #751 from Molecule-AI/feat/issue-744-a2a-topology-overlay
feat(canvas): A2A topology overlay with animated delegation edges
2026-04-17 09:15:10 -07:00
Molecule AI Research Lead
ac2e443a1b chore(eco-watch): add mcp-agent — 2026-04-17
lastmile-ai/mcp-agent (7.4k★, Apache-2.0) implements Anthropic's Building
Effective Agents patterns + OpenAI Swarm as composable MCP workflow primitives.
Direct workspace-template overlap; companion mcp-eval useful for #747 audit.
GH #762 filed for TR evaluation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 16:09:37 +00:00
molecule-ai[bot]
c14f9f04d9
refactor(#741): extract medo.py from builtin_tools to plugins/molecule-medo
The Baidu MeDo hackathon integration was sitting in builtin_tools/ as dead
code — not imported by any loader but shipped with every workspace image,
misleadingly suggesting it was a core builtin.

Changes:
- Move builtin_tools/medo.py → plugins/molecule-medo/skills/medo-tools/scripts/medo.py
  (git detects this as a rename — no code changes, identical tool surface)
- Add plugins/molecule-medo/plugin.yaml (manifest: name, version, runtimes, tags)
- Add plugins/molecule-medo/skills/medo-tools/SKILL.md (frontmatter + setup docs)
- Move workspace-template/tests/test_medo.py → plugins/molecule-medo/tests/test_medo.py
  (update _MEDO_PATH to resolve from plugin root; add conftest.py for langchain mock)
- Update .gitignore: change /plugins/ blanket ignore to /plugins/* so this plugin
  can be tracked until it gets its own standalone repo

Acceptance criteria met:
- builtin_tools/medo.py removed from core
- plugins/molecule-medo/ created with identical tool surface (9/9 tests pass)
- cd workspace-template && pytest → 1021 passed, 2 xfailed (no regression)
- MEDO_API_KEY was never in default provisioning (.env.example / config.py clean)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 16:03:50 +00:00
molecule-ai[bot]
4f7c458775
docs(security): add SAFE-MCP audit for issue #747 2026-04-17 15:59:40 +00:00
molecule-ai[bot]
5633aa2734
Merge pull request #650 from Molecule-AI/feat/issue-624-slack-ci-alerts
feat(infra): Slack CI/build-break notifications for DevOps (#624)
2026-04-17 15:58:33 +00:00
molecule-ai[bot]
d1415b9824
Merge pull request #749 from Molecule-AI/spike/issue-742-managed-agents-executor
spike(#745): Anthropic Managed Agents executor evaluation
2026-04-17 15:58:27 +00:00
molecule-ai[bot]
c8038479e4
Merge pull request #748 from Molecule-AI/chore/eco-watch-2026-04-17-e
chore(eco-watch): add Mastra + SAFE-MCP — 2026-04-17
2026-04-17 15:57:59 +00:00
Hongming Wang
ee88b88502
Merge pull request #738 from Molecule-AI/feat/issue-730-memory-inspector-panel
feat(canvas): MemoryInspectorPanel — workspace KV memory inspector (#730)
2026-04-17 08:47:40 -07:00
Hongming Wang
f28b3922f9
Merge pull request #743 from Molecule-AI/feat/issue-727-opus-4-7-default
feat: upgrade default workspace model to claude-opus-4-7
2026-04-17 08:47:27 -07:00
Hongming Wang
e8c1f7a268
Merge pull request #739 from Molecule-AI/test/issue-684-adminauth-bearer-scope-v2
test(security): route-specific regression tests for #684 admin auth fix
2026-04-17 08:47:23 -07:00
Hongming Wang
ede7cf19af
Merge pull request #737 from Molecule-AI/fix/issue-684-admin-token-env
fix(infra): wire ADMIN_TOKEN placeholder to close issue #684 (PR #729)
2026-04-17 08:47:19 -07:00
Hongming Wang
df0d4c46af
Merge pull request #735 from Molecule-AI/chore/eco-watch-2026-04-17-d
chore(eco-watch): add goose/AAIF + github/awesome-copilot — 2026-04-17
2026-04-17 08:47:16 -07:00
molecule-ai[bot]
c11792b861
feat(canvas): A2A topology overlay with animated delegation edges (issue #744)
- New A2ATopologyOverlay component polls /activity fan-out every 60s and
  writes directed edges to a2aEdges store slice (separate from topology edges)
- buildA2AEdges aggregates delegate rows per source→target pair; violet-500
  animated edge when last call <5 min ago, blue-500 static otherwise
- Toolbar toggle persists to localStorage (molecule:show-a2a-edges)
- Canvas.tsx merges a2aEdges into allEdges via useMemo; pointerEvents:none
  on all edge elements keeps nodes draggable
- 24 new unit tests across pure function, helper, and component suites
- Fix Canvas.a11y and Canvas.pan-to-node store mocks (missing A2A fields)

Closes #744

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:45:34 +00:00
molecule-ai[bot]
08f8be820a
spike(#745): evaluate Anthropic Managed Agents as third executor option
Adds `spike/issue-742-managed-agents-executor/` with:
- `demo.py`: standalone Python script that authenticates to the Managed Agents
  beta API, provisions an environment + agent, starts a session, runs two
  conversational turns (with cross-turn state recall verification), and prints
  cold-start and per-turn latency measurements.
- `README.md`: full integration assessment covering provisioner changes needed,
  A2A routing conflict (primary blocker — sessions have no addressable URL),
  cost model, API gaps table, and a no-ship recommendation with a 3-week effort
  estimate if we proceeded anyway.

Recommendation: no-ship for primary executor. Revisit as a batch/cron worker
in Phase H once Molecule's MCP server is feature-complete.

Closes #745. References #742.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:43:21 +00:00
Molecule AI Research Lead
891fb366ca chore(eco-watch): add Mastra + SAFE-MCP — 2026-04-17
Mastra (22k★, TypeScript, YC, v1.0 Jan 2026) — TypeScript-native agent
framework with built-in evals + MCP client; potential workspace-template
adapter candidate (GH #746 dispatched to TR).
SAFE-MCP (LF + OpenID Foundation, Apr 2026) — ATT&CK-style MCP threat
taxonomy; GH #747 filed to audit molecule-mcp-server's 87 tools + plugin
install pathway against the 80+ documented techniques.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:40:59 +00:00
Molecule AI Backend Engineer
ebfafb9139 feat: upgrade default workspace model to claude-opus-4-7 (#727)
Replace the anthropic:claude-sonnet-4-6 default across config, handlers,
env example, and litellm proxy config. All tests updated to match the new
default; sonnet-4-6 alias kept in litellm_config.yml for pinned workspaces.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:30:57 +00:00
Molecule AI QA Engineer
7aeaf3c07c test(security): route-specific #684 regression — three vulnerable admin routes
The BE's tests (AdminTokenSet_*, FailOpen_*) validated the core AdminAuth
contract on /admin/secrets. These table-driven additions pin the same contract
on the three routes explicitly named in the #684 security report, each with
three scenarios: workspace token rejected, correct ADMIN_TOKEN accepted, no
bearer rejected.

Routes covered:
  GET /admin/liveness
  GET /admin/github-installation-token
  GET /approvals/pending

When ADMIN_TOKEN is set (tier 2), ValidateAnyToken is never called — the
env-var comparison short-circuits before any DB lookup. The mock sets only
HasAnyLiveTokenGlobal and nothing else; an extra DB expectation would itself
be a test bug (calling it proves the middleware regressed to tier 3).

All 18 TestAdminAuth_684* tests pass. Full go test ./... is green across all
15 platform packages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:25:41 +00:00
molecule-ai[bot]
cff3794371
feat(canvas): add MemoryInspectorPanel for workspace KV memory (issue #730)
Builds MemoryInspectorPanel.tsx — a focused inspector for per-workspace
platform memory entries. Replaces MemoryTab in the SidePanel "memory" tab.

- GET /workspaces/:id/memory loads entries (flat MemoryEntry[] — confirmed
  with Backend Engineer: fields are key/value/version/expires_at/updated_at,
  no scope, write verb is POST not PATCH)
- Empty state: "No memory entries yet" with icon
- Click entry -> expand -> show JSON value, version badge, relative timestamp
- Edit flow: textarea pre-filled with JSON.stringify(value), Save calls POST
  with if_match_version for optimistic concurrency, optimistic update with
  rollback on 409/error, invalid-JSON guard
- Delete flow: button -> ConfirmDialog -> optimistic removal -> DELETE call
- Refresh button re-fetches entries
- 665 tests pass (43 files), next build clean, 'use client' check passes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:24:53 +00:00
aa38fc55ed fix(infra): wire ADMIN_TOKEN env placeholder to close issue #684 (PR #729)
Backend Engineer's PR #729 introduces ADMIN_TOKEN — when set, only that value
is accepted on /admin/* and /approvals/* routes, replacing the vulnerable
workspace-bearer fallback. Without the env var wired into deployments the fix
is code-only and the vulnerability stays open in every running instance.

Changes:
- `docker-compose.yml`: adds ADMIN_TOKEN env var to the platform service
  (blank default = backward-compat fallback, i.e. still vulnerable until set).
  NOTE: docker-compose.infra.yml has no platform service — the platform lives
  only in the full-stack docker-compose.yml, so that is the correct file.
- `.env.example`: documents ADMIN_TOKEN with generation instructions and a
  clear warning that it must be set to close #684.
- `infra/scripts/setup.sh`: prints a visible warning when ADMIN_TOKEN is unset
  so operators know the vulnerability is still open in that deployment.
- `CLAUDE.md`: adds ADMIN_TOKEN to the env vars reference section.

No Go code changed — go build ./... passes clean.

Part of fix for #684 / PR #729

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:21:35 +00:00
Hongming Wang
00ef832e33
Merge pull request #729 from Molecule-AI/fix/issue-684-adminauth-bearer-scope
fix(auth): AdminAuth rejects workspace bearer tokens when ADMIN_TOKEN is set (#684)
2026-04-17 08:17:11 -07:00
Molecule AI Research Lead
82493148ab chore(eco-watch): add goose/AAIF + github/awesome-copilot — 2026-04-17
goose donated to Linux Foundation AAIF (alongside MCP + AGENTS.md) — AGENTS.md
standard could become workspace-template interop requirement (GH #733).
awesome-copilot (30k★) is a direct terminology-collision risk: Skills/Plugins/
Agents/Hooks all overlap with Molecule vocab at different meanings (GH #734).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:15:59 +00:00
Molecule AI Backend Engineer
6259e69b42 fix(auth): tighten AdminAuth to reject workspace bearer tokens when ADMIN_TOKEN is set (#684)
Blast-radius isolation gap: AdminAuth called ValidateAnyToken which
accepted any live workspace bearer token. A compromised workspace agent
could present its own token to GET /admin/github-installation-token and
steal the platform's GitHub App credential, or hit /approvals/pending to
enumerate cross-workspace approvals.

Fix: introduce a dedicated admin credential tier via ADMIN_TOKEN env var.
When set, AdminAuth verifies the bearer against that secret exclusively
(crypto/subtle constant-time comparison). Workspace tokens are rejected
outright — no DB lookup occurs. When ADMIN_TOKEN is not set the previous
behaviour is preserved as a deprecated backward-compat fallback (tier 3)
so existing deployments without the env var don't break immediately.

Credential tiers (evaluated in order):
  1. Fail-open — no live tokens globally (fresh install / pre-Phase-30)
  2. ADMIN_TOKEN match — env var set, bearer must equal it exactly
  3. Fallback (deprecated) — any valid workspace token (ADMIN_TOKEN unset)

Operators should set ADMIN_TOKEN=<openssl rand -base64 32> to fully close
the blast-radius gap. Tier 3 will be removed in a future release.

Fixes #684.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:08:54 +00:00
Hongming Wang
ae7df68d5f
Merge pull request #728 from Molecule-AI/fix/issue-722-scheduler-null-next-run
fix(scheduler): prevent NULL next_run_at from permanently dropping schedules
2026-04-17 06:47:01 -07:00
molecule-ai[bot]
b83ddc7dff
fix(scheduler): prevent NULL next_run_at from permanently dropping schedules (#722)
Three bugs caused enabled schedules to silently disappear from the fire query
(which requires next_run_at IS NOT NULL AND next_run_at <= now()):

Bug 1 - fireSchedule() and recordSkipped(): when ComputeNextRun returned an
error, nextRunPtr stayed nil and UPDATE SET next_run_at = $2 wrote NULL.
Fix: change to COALESCE($2, next_run_at) so the existing DB value is preserved
when $2 is NULL, and log the error explicitly.

Bug 2 - org importer (handlers/org.go): nextRun, _ := ComputeNextRun(...)
silently discarded the error. A bad cron expression would pass time.Time{}
(zero value) to the INSERT. Fix: surface the error, log it, and skip the
schedule INSERT via continue.

Bug 3 - no startup repair: schedules already NULL'd by the pre-fix binary
would never recover. Fix: Start() now calls repairNullNextRunAt() once on
boot, recomputing next_run_at for every enabled schedule with a NULL value.

Tests: TestFireSchedule_ComputeNextRunError, TestRecordSkipped_ComputeNextRunError,
TestRepairNullNextRunAt_RepairsRows, TestRepairNullNextRunAt_DBError_NoPanic,
TestOrgImport_ScheduleComputeError (all pass).

Fixes #722

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:34:28 +00:00
Molecule AI Research Lead
277a33c4fd chore(eco-watch): add opencode + pydantic-ai — 2026-04-17
- anomalyco/opencode (145k★, v1.4.7): largest open-source coding agent;
  provider-agnostic (Claude/OpenAI/Google/local); build+plan dual-mode;
  no A2A/multi-agent → conversion path for users who need org layer.
  Filed GH #720 (workspace template adapter eval). MEDIUM threat.

- pydantic/pydantic-ai (~16.4k★): Python framework with native A2A + MCP
  + HITL + durable execution; FastAPI-style DX; potential first-class
  Molecule A2A peer with zero shim. Filed GH #721 (adapter eval). LOW threat.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:19:19 +00:00
molecule-ai[bot]
c53bf6eebd
Merge pull request #719 from Molecule-AI/fix/issue-697-validate-token-removed-workspace
fix(wsauth): add removed-workspace JOIN to ValidateToken (#697)
2026-04-17 12:50:52 +00:00
molecule-ai[bot]
f632a25308
Merge pull request #718 from Molecule-AI/docs/fix-auth-701
docs(platform-api): Breaking Changes for PR #701 — auth + UUID + field validation
2026-04-17 12:48:57 +00:00
Hongming Wang
87f2b9abb7
Merge pull request #696 from Molecule-AI/fix/issue-682-684-683-auth-token-fixes
fix(security): metrics auth, token revocation hardening, A2A false-negative (#682 #683 #689)
2026-04-17 05:47:08 -07:00
molecule-ai[bot]
059644bc37
fix(wsauth): add removed-workspace JOIN to ValidateToken (#697)
Defense-in-depth: workspace-scoped ValidateToken now rejects tokens
belonging to workspaces with status='removed' at the DB layer, even
when revoked_at IS NULL. Mirrors the same guard added to ValidateAnyToken
in #696. Updated all test mock patterns (workspace_test, a2a_proxy_test,
secrets_test, admin_test_token_test, middleware) to match the new JOIN query.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:46:27 +00:00
molecule-ai[bot]
36bc374172
docs(platform-api): Breaking Changes section for PR #701 auth + validation
Updates docs/api-protocol/platform-api.md:
- Add ## Breaking Changes section with full before/after table for PR #701
  (PATCH wsAuth, templates AdminAuth, UUID validation, field length/char limits)
- PATCH /workspaces/:id row: add WorkspaceAuth note + validation details
- GET /templates: add AdminAuth note
- GET /org/templates: add row with AdminAuth note
- Migration steps for E2E scripts and automation callers

Source PR: #701 (SHA 63212130) — fix(security): input validation, route auth, UUID safety

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:44:11 +00:00
molecule-ai[bot]
043d3f83d7
Merge pull request #709 from Molecule-AI/test/issue-685-686-687-688-regression
test(security): regression suite for input validation fixes (#685 #686 #687 #688)
2026-04-17 12:43:38 +00:00
Molecule AI Research Lead
a72617ee93 chore(eco-watch): add cognee — hybrid vector+graph agent memory engine
topoteretes/cognee (v1.0.1.dev1, 16.1k★, Apache-2.0): hybrid vector+graph
knowledge engine with remember/recall/forget/improve API. Ships native Hermes
Agent support and MCP plugin — directly overlaps with Molecule's agent_memories
and workspace-template-hermes. Evaluation tracked in GH #717.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:41:52 +00:00
Molecule AI QA Engineer
5dbac3a5ee test(security): regression suite for input validation fixes (#685 #686 #687 #688)
30 test cases covering all four security fixes from PR #701:

  #686 — AdminAuth gate on GET /templates and GET /org/templates:
    - NoAuth returns 401 when tokens are enrolled
    - FreshInstall fails open (bootstraps correctly)

  #687 — UUID path param validation:
    - URL-encoded traversal (..%2f..%2fetc%2fpasswd) → 400
    - Non-UUID strings (not-a-uuid, ws-123, XSS payloads) → 400
    - Valid UUIDs pass through (regression check)

  #688 — Field length limits:
    - name=256, role=1001, model=101 chars → 400
    - Exact-boundary values (255/1000/100) → pass (off-by-one guard)

  #685 — YAML injection via newline/CR:
    - Newline in name, CR in role → 400
    - YAML multi-field injection payload "agent\nrole: injected" → 400

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:37:13 +00:00
molecule-ai[bot]
63212130e3
Merge pull request #701 from Molecule-AI/fix/issue-685-686-687-688-input-validation
fix(security): input validation, route auth, UUID safety (#685 #686 #687 #688)
2026-04-17 12:32:03 +00:00
Molecule AI Backend Engineer
993d39a74e fix(wsauth): restore ValidateAnyToken removed-workspace JOIN (#682 defense-in-depth), restore ADR-001 blast-radius docs
- ValidateAnyToken: add JOIN on workspaces with AND w.status != 'removed'
  so tokens belonging to deleted workspaces cannot be replayed against
  admin endpoints even before the token row is explicitly revoked.

- tokens_test.go: update ValidateAnyToken regexp patterns to match new
  JOIN query; add TestValidateAnyToken_RemovedWorkspaceRejected.

- wsauth_middleware_test.go: update validateAnyTokenSelectQuery constant
  to match JOIN query; add TestAdminAuth_RemovedWorkspaceToken_Returns401
  to pin the AdminAuth removed-workspace rejection at the middleware layer.

- ADR-001: restore full blast-radius endpoint table (15 affected admin
  routes), explicit risk statement ("full platform takeover"), current
  mitigations, and Phase-H remediation plan (schema, middleware, bootstrap
  flow, migration path). Tracking issue: #710.
2026-04-17 12:25:44 +00:00
Hongming Wang
bd09c58af7
Merge pull request #708 from Molecule-AI/fix/e2e-test-token-bootstrap
fix(router): remove AdminAuth from test-token — unblocks E2E CI bootstrap
2026-04-17 05:17:12 -07:00
molecule-ai[bot]
f1b2a2f8a6
fix(security): rebase #685-688 onto main — preserve wsAuth PATCH, add yamlSpecialChars
- Rebased onto 15a850ea (main HEAD, post-#692 IDOR fix)
- PATCH /workspaces/:id remains under wsAuth group (not open router)
- Added validateWorkspaceID (uuid.Parse check) in Get/Update/Delete
- Added validateWorkspaceFields: rejects \n\r in all fields,
  yamlSpecialChars {}[]|>*&! in name/role only, enforces max lengths
- Template endpoints (GET /templates, GET /org/templates) now require AdminAuth
- Replaced stale in-handler sensitiveUpdateFields gate tests with
  TestWorkspaceUpdate_SensitiveField_AuthEnforcedByMiddleware

Closes #685 #686 #687 #688
2026-04-17 12:13:44 +00:00
Molecule AI Research Lead
469b392122 chore(eco-watch): add Cloudflare Agents — edge agent runtime with auto-hibernation
cloudflare/agents (v0.11.2, 4.8k★): TypeScript framework on CF Workers/Durable
Objects with persistent state, cron scheduling, MCP (server+client), HITL
workflows, and auto-hibernation (zero idle cost). Near-complete overlap with
Molecule workspace lifecycle primitives; no A2A or org hierarchy.

Auto-hibernation pattern → filed as GH #711 (auto-pause idle workspaces).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:11:06 +00:00
molecule-ai[bot]
70db163898
fix(router): restore admin/schedules/health route; add ADR-001 for #684 2026-04-17 12:03:34 +00:00
molecule-ai[bot]
96c06b0174
fix(security): revert #684 schema migration, restore /admin/schedules/health, add ADR-001
Required changes from security auditor before PR #696 can merge:

1. REVERT #684 (token_type schema migration):
   - Remove migration 029_token_type.{up,down}.sql
   - Revert wsauth/tokens.go — remove IssueAdminToken, token_type constants,
     restore HasAnyLiveTokenGlobal and ValidateAnyToken to pre-#684 behavior
   - Revert admin_test_token.go to use IssueToken (not IssueAdminToken)
   - Revert associated tests to pre-#684 patterns
   Path B: formal risk acceptance documented in ADR-001.

2. RESTORE /admin/schedules/health route (regression fix):
   - Add platform/internal/handlers/admin_schedules_health.go (from PR #671)
   - Add platform/internal/handlers/admin_schedules_health_test.go (from PR #671)
   - Wire GET /admin/schedules/health via AdminAuth in router.go

3. ADD ADR-001 (platform/docs/adr/ADR-001-admin-token-scope.md):
   - Documents #684 as known risk with Phase-H remediation plan
   - Phase-H tracking issue: Molecule-AI/molecule-core#710
2026-04-17 12:01:12 +00:00
rabbitblood
784376f19f fix(router): remove AdminAuth from test-token — unblocks E2E bootstrap
#612 added AdminAuth to GET /admin/workspaces/:id/test-token, breaking
the chicken-and-egg bootstrap that E2E tests rely on:

1. POST /workspaces creates first workspace (fail-open, no tokens)
2. Provision generates a workspace auth token → inserts into DB
3. AdminAuth now sees a live token → requires auth on ALL routes
4. E2E calls test-token to get its first admin bearer → 401
5. All subsequent E2E calls fail → EVERY open PR CI blocked

The test-token handler already has its own production guard
(TestTokensEnabled returns false when MOLECULE_ENV=prod). That's
sufficient — AdminAuth was defence-in-depth but broke the only
bootstrap path in dev/CI environments.

This has been blocking CI for 6+ cycles, stalling 4 PRs (#650,
#651, #696, #701) and masking as 'flaky E2E Postgres timeout'
until root-cause analysis this cycle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 04:50:14 -07:00
molecule-ai[bot]
a77520c452
fix(security): add token_type column — workspace tokens rejected by AdminAuth (#684)
Security Auditor confirmed: ValidateAnyToken accepted any live workspace
token, meaning a workspace agent bearer could satisfy AdminAuth and reach
/bundles/import, /events, /org/import, /settings/secrets, etc.

Fix: add token_type TEXT ('workspace' | 'admin') to workspace_auth_tokens.

Migration 029:
- ALTER workspace_id DROP NOT NULL (admin tokens have no workspace scope)
- ADD COLUMN token_type TEXT NOT NULL DEFAULT 'workspace'
- ADD CONSTRAINT token_type_check (IN 'workspace', 'admin')
- ADD CONSTRAINT scope_check (workspace tokens MUST have workspace_id;
  admin tokens MUST have workspace_id = NULL)

Code changes:
- IssueToken: explicitly inserts token_type = 'workspace'
- IssueAdminToken (new): inserts NULL workspace_id + token_type = 'admin'
- ValidateAnyToken: now filters WHERE token_type = 'admin' — workspace
  tokens unconditionally fail
- HasAnyLiveTokenGlobal: counts only admin tokens
- admin_test_token.go: GetTestToken calls IssueAdminToken (#684)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:47:31 +00:00