fix(concierge): declare molecule-platform-mcp via gitea:// source so the box actually fetches it #3049

Merged
devops-engineer merged 5 commits from fix/concierge-mcp-gitea-source into main 2026-06-19 04:25:11 +00:00
Member

Follow-up to #3044. Root-caused why create_workspace wasn't landing on a fresh provision.

Bug

#3044 declared the management MCP with a bare name (molecule-platform-mcp). The box's boot-install (runtime-image entrypoint) only fetches gitea:// sources and silently skips everything else (*) skip unsupported source). A bare name parses to the local scheme (image-baked plugins only). Since molecule-ai-plugin-molecule-platform-mcp is a brand-new Gitea-only repo, the bare-name source was skipped → plugin never fetched → no molecule-platform MCP → no create_workspace.

Fix

Declare it with a pinned gitea:// source so the box fetches the repo:

  • conciergePlatformMCPSource = "gitea://molecule-ai/molecule-ai-plugin-molecule-platform-mcp#main" (passed to seedTemplatePlugins). The #main pin is required: the gitea resolver rejects unpinned specs in production (PLUGIN_ALLOW_UNPINNED unset), so an unpinned source would record the declaration but fail to fetch → hollow.
  • Split out conciergePlatformMCPName = "molecule-ai-plugin-molecule-platform-mcp" — the install name PluginNameFromSource derives (repo segment; the #ref does not affect it). The recordDeclaredPlugin entitlement gate matches on this derived name, so it keeps fail-closing for non-platform workspaces.

Tests updated: entitlement-gate test uses the derived name + gitea source. gofmt-clean.

SOP checklist

  • Comprehensive testing performed: go build ./... clean; targeted unit tests green (TestRecordDeclaredPlugin_PrivilegedPluginEntitlement, concierge-provision); PluginNameFromSource("…#main") derivation verified empirically == conciergePlatformMCPName; two independent reviews (QA + security).
  • Local-postgres E2E run: Handlers Postgres Integration (pull_request) green on head; this is a pure handler/const change (no schema/migration).
  • Staging-smoke verified or pending: concierge boot verified on a fresh staging tenant after the ECR-allowlist fix — docker pull completes (0× 403), container Up, Registered with platform: 200. The create_workspace staging-smoke is scheduled post-merge (requires #3049 deployed to staging), then prod verify.
  • Root-cause not symptom: fixed at the plugin declaration source (gitea:// + pinned ref) — the bare-name-skip mechanism — not a workaround.
  • Five-Axis review walked: correctness / readability / architecture / security / performance — covered by the two reviews; the security pass found the unpinned-ref hollow-fetch and it was fixed (pin #main).
  • No backwards-compat shim / dead code added: no shim; the old conciergePlatformMCPPlugin const was removed cleanly (no dangling refs); the source/name split is the real fix.
  • Memory/saved-feedback consulted: feedback_no_such_thing_as_flakes (named the ECR-403 mechanism instead of dismissing the e2e as flaky), feedback_follow_dev_sop_phase1_evidence_first (SSM ground-truth on a live box), reference_local_reviewer_gitea_identities.

Verify after merge

Re-provision a fresh tenant → boot-install fetches gitea://…/molecule-ai-plugin-molecule-platform-mcp#mainMCPServerAdaptor wires molecule-platform → introspect create_workspace present. (Task #52.)

🤖 Generated with Claude Code

Follow-up to #3044. Root-caused why `create_workspace` wasn't landing on a fresh provision. ## Bug #3044 declared the management MCP with a **bare name** (`molecule-platform-mcp`). The box's boot-install (runtime-image entrypoint) only fetches `gitea://` sources and **silently skips everything else** (`*) skip unsupported source`). A bare name parses to the `local` scheme (image-baked plugins only). Since `molecule-ai-plugin-molecule-platform-mcp` is a brand-new Gitea-only repo, the bare-name source was skipped → plugin never fetched → no `molecule-platform` MCP → **no `create_workspace`**. ## Fix Declare it with a **pinned** `gitea://` source so the box fetches the repo: - `conciergePlatformMCPSource = "gitea://molecule-ai/molecule-ai-plugin-molecule-platform-mcp#main"` (passed to `seedTemplatePlugins`). The `#main` pin is required: the gitea resolver rejects unpinned specs in production (`PLUGIN_ALLOW_UNPINNED` unset), so an unpinned source would record the declaration but fail to fetch → hollow. - Split out `conciergePlatformMCPName = "molecule-ai-plugin-molecule-platform-mcp"` — the install name `PluginNameFromSource` derives (repo segment; the `#ref` does not affect it). The `recordDeclaredPlugin` entitlement gate matches on this derived **name**, so it keeps fail-closing for non-platform workspaces. Tests updated: entitlement-gate test uses the derived name + gitea source. gofmt-clean. ## SOP checklist - **Comprehensive testing performed:** `go build ./...` clean; targeted unit tests green (`TestRecordDeclaredPlugin_PrivilegedPluginEntitlement`, concierge-provision); `PluginNameFromSource("…#main")` derivation verified empirically == `conciergePlatformMCPName`; two independent reviews (QA + security). - **Local-postgres E2E run:** `Handlers Postgres Integration (pull_request)` green on head; this is a pure handler/const change (no schema/migration). - **Staging-smoke verified or pending:** concierge **boot** verified on a fresh staging tenant after the ECR-allowlist fix — `docker pull` completes (0× 403), container Up, `Registered with platform: 200`. The `create_workspace` staging-smoke is **scheduled post-merge** (requires #3049 deployed to staging), then prod verify. - **Root-cause not symptom:** fixed at the plugin declaration source (gitea:// + pinned ref) — the bare-name-skip mechanism — not a workaround. - **Five-Axis review walked:** correctness / readability / architecture / security / performance — covered by the two reviews; the security pass found the unpinned-ref hollow-fetch and it was fixed (pin `#main`). - **No backwards-compat shim / dead code added:** no shim; the old `conciergePlatformMCPPlugin` const was removed cleanly (no dangling refs); the source/name split is the real fix. - **Memory/saved-feedback consulted:** `feedback_no_such_thing_as_flakes` (named the ECR-403 mechanism instead of dismissing the e2e as flaky), `feedback_follow_dev_sop_phase1_evidence_first` (SSM ground-truth on a live box), `reference_local_reviewer_gitea_identities`. ## Verify after merge Re-provision a fresh tenant → boot-install fetches `gitea://…/molecule-ai-plugin-molecule-platform-mcp#main` → `MCPServerAdaptor` wires `molecule-platform` → introspect `create_workspace` present. (Task #52.) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
core-devops added 3 commits 2026-06-18 21:50:47 +00:00
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(concierge): declare molecule-platform-mcp via gitea:// source (not bare name) [platform_agent_test.go]
audit-force-merge / audit (pull_request_target) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge user_tasks (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Workspace Requests (core#2606) (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Creates Workspace (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Platform Agent (pull_request) Has been skipped
CI / Python Lint & Test (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 8s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 13s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 11s
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge (compile+skip) (pull_request) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
E2E API Smoke Test / detect-changes (pull_request) Successful in 16s
qa-review / approved (pull_request_target) Failing after 8s
reserved-path-review / reserved-path-review (pull_request_target) Successful in 9s
security-review / approved (pull_request_target) Failing after 9s
E2E Staging SaaS (full lifecycle) / pr-validate (pull_request) Successful in 18s
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 21s
PR Diff Guard / PR diff guard (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Failing after 15s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 19s
CI / Detect changes (pull_request) Successful in 28s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Successful in 1s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 32s
E2E Chat / detect-changes (pull_request) Successful in 41s
E2E Chat / E2E Chat (pull_request) Successful in 4s
template-delivery-e2e / detect-changes (pull_request) Successful in 45s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 47s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 29s
Harness Replays / Harness Replays (pull_request) Successful in 1m21s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m21s
CI / Platform (Go) (pull_request) Successful in 2m59s
CI / all-required (pull_request) Successful in 4s
E2E Staging SaaS (full lifecycle) / E2E Staging Platform Boot (pull_request) Failing after 6m29s
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (pull_request) Failing after 9m43s
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (pull_request) Successful in 13m33s
sop-checklist / all-items-acked (pull_request) Compensated by status-reaper (non-required pull_request/pull_request_review governance shadow overridden by successful pull_request_target status; see .gitea/scripts/status-reaper.py)
51e9df2f2e
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
core-devops added 1 commit 2026-06-18 21:50:47 +00:00
fix(concierge): declare molecule-platform-mcp via gitea:// source (not bare name) [platform_agent_test.go]
audit-force-merge / audit (pull_request_target) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge user_tasks (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Workspace Requests (core#2606) (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Creates Workspace (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Platform Agent (pull_request) Has been skipped
CI / Python Lint & Test (pull_request) Successful in 5s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 8s
sop-checklist / review-refire (pull_request_target) Has been skipped
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 8s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 13s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 11s
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge (compile+skip) (pull_request) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 8s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
E2E API Smoke Test / detect-changes (pull_request) Successful in 16s
qa-review / approved (pull_request_target) Failing after 8s
reserved-path-review / reserved-path-review (pull_request_target) Successful in 9s
security-review / approved (pull_request_target) Failing after 9s
E2E Staging SaaS (full lifecycle) / pr-validate (pull_request) Successful in 18s
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 5s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 21s
PR Diff Guard / PR diff guard (pull_request) Successful in 15s
gate-check-v3 / gate-check (pull_request_target) Failing after 15s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 19s
CI / Detect changes (pull_request) Successful in 28s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Successful in 1s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 32s
E2E Chat / detect-changes (pull_request) Successful in 41s
E2E Chat / E2E Chat (pull_request) Successful in 4s
template-delivery-e2e / detect-changes (pull_request) Successful in 45s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 47s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 29s
Harness Replays / Harness Replays (pull_request) Successful in 1m21s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m21s
CI / Platform (Go) (pull_request) Successful in 2m59s
CI / all-required (pull_request) Successful in 4s
E2E Staging SaaS (full lifecycle) / E2E Staging Platform Boot (pull_request) Failing after 6m29s
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (pull_request) Failing after 9m43s
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (pull_request) Successful in 13m33s
sop-checklist / all-items-acked (pull_request) Compensated by status-reaper (non-required pull_request/pull_request_review governance shadow overridden by successful pull_request_target status; see .gitea/scripts/status-reaper.py)
51e9df2f2e
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
core-devops closed this pull request 2026-06-18 22:05:56 +00:00
core-devops reopened this pull request 2026-06-18 22:06:00 +00:00
core-devops added 1 commit 2026-06-19 02:14:52 +00:00
style(concierge): gofmt — drop trailing blank line at EOF (3 files)
CI / Python Lint & Test (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 6s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 6s
Harness Replays / detect-changes (pull_request) Successful in 7s
sop-checklist / review-refire (pull_request_target) Has been skipped
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 12s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 9s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
qa-review / approved (pull_request_target) Failing after 9s
reserved-path-review / reserved-path-review (pull_request_target) Successful in 10s
security-review / approved (pull_request_target) Failing after 9s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
E2E Chat / detect-changes (pull_request) Successful in 19s
sop-checklist / na-declarations (pull_request) N/A: (none)
E2E API Smoke Test / detect-changes (pull_request) Successful in 20s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 15s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 6s
sop-checklist / all-items-acked (pull_request_target) Successful in 11s
gate-check-v3 / gate-check (pull_request_target) Failing after 16s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 21s
template-delivery-e2e / detect-changes (pull_request) Successful in 16s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 21s
E2E Chat / E2E Chat (pull_request) Successful in 3s
CI / Detect changes (pull_request) Successful in 26s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
PR Diff Guard / PR diff guard (pull_request) Successful in 22s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Successful in 1s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 34s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 36s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 29s
Harness Replays / Harness Replays (pull_request) Successful in 1m22s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m18s
CI / Platform (Go) (pull_request) Successful in 3m12s
CI / all-required (pull_request) Successful in 3s
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (pull_request) Successful in 7m20s
E2E Staging SaaS (full lifecycle) / pr-validate (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Platform Boot (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge user_tasks (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Workspace Requests (core#2606) (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Creates Workspace (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge (compile+skip) (pull_request) Waiting to run
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Platform Agent (pull_request) Waiting to run
16ba44988a
No behavior change. gofmt -l flagged platform_agent.go, plugins_tracking.go,
and platform_agent_test.go for a blank line after the final brace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
core-devops added 1 commit 2026-06-19 02:19:03 +00:00
fix(concierge): pin management-MCP plugin source to #main
CI / Python Lint & Test (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 7s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 9s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 11s
E2E Peer Visibility (literal MCP list_peers) / detect-changes (pull_request) Successful in 12s
reserved-path-review / reserved-path-review (pull_request_target) Successful in 8s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (local) (pull_request) Has been skipped
E2E Chat / detect-changes (pull_request) Successful in 15s
E2E API Smoke Test / detect-changes (pull_request) Successful in 18s
PR Diff Guard / PR diff guard (pull_request) Successful in 14s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 16s
CI / Detect changes (pull_request) Successful in 19s
E2E Peer Visibility (literal MCP list_peers) / E2E Peer Visibility (pull_request) Successful in 6s
E2E Chat / E2E Chat (pull_request) Successful in 4s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 1s
CI / Canvas (Next.js) (pull_request) Successful in 3s
CI / Canvas Deploy Status (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 26s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 3s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 42s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 34s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 45s
Harness Replays / Harness Replays (pull_request) Successful in 1m25s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2m17s
CI / Platform (Go) (pull_request) Successful in 3m16s
CI / all-required (pull_request) Successful in 3s
sop-checklist / review-refire (pull_request_target) Has been skipped
sop-checklist / all-items-acked (pull_request_target) Successful in 9s
gate-check-v3 / gate-check (pull_request_target) Failing after 15s
sop-checklist / na-declarations (pull_request) N/A: (none)
E2E Staging SaaS (full lifecycle) / E2E Staging Workspace Requests (core#2606) (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge user_tasks (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Creates Workspace (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Platform Agent (pull_request) Has been skipped
E2E Staging SaaS (full lifecycle) / pr-validate (pull_request) Successful in 12s
E2E Staging SaaS (full lifecycle) / E2E Staging Concierge (compile+skip) (pull_request) Successful in 15s
E2E Staging SaaS (full lifecycle) / E2E Staging Platform Boot (pull_request) Successful in 8m18s
E2E Staging SaaS (full lifecycle) / E2E Staging SaaS (pull_request) Successful in 8m29s
qa-review / approved (pull_request_target) Approved via pull_request_review trigger
qa-review / approved (pull_request_review) Successful in 11s
reserved-path-review / reserved-path-review (pull_request_review) Successful in 10s
security-review / approved (pull_request_target) Approved via pull_request_review trigger
security-review / approved (pull_request_review) Successful in 10s
template-delivery-e2e / detect-changes (pull_request) Successful in 15s
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (pull_request) Successful in 9m32s
audit-force-merge / audit (pull_request_target) Successful in 8s
sop-checklist / all-items-acked (pull_request) Compensated by status-reaper (non-required pull_request/pull_request_review governance shadow overridden by successful pull_request_target status; see .gitea/scripts/status-reaper.py)
014af619d2
The gitea resolver rejects an unpinned spec in production
(PLUGIN_ALLOW_UNPINNED is unset by default), so an unpinned
conciergePlatformMCPSource would record the declaration but FAIL to
fetch at boot-install → no management MCP, no create_workspace. Pin
#main (matches the seo-all convention). The #ref does not affect
PluginNameFromSource, so conciergePlatformMCPName is unchanged
(verified: derives molecule-ai-plugin-molecule-platform-mcp).

Found in review (security pass) of #3049.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
molecule-code-reviewer approved these changes 2026-06-19 02:19:39 +00:00
molecule-code-reviewer left a comment
Member

QA / correctness review — APPROVE

Independent review of the gitea:// plugin-source fix.

  • PluginNameFromSource("gitea://molecule-ai/molecule-ai-plugin-molecule-platform-mcp#main") derives molecule-ai-plugin-molecule-platform-mcp == conciergePlatformMCPName (verified empirically, ref does not affect derivation).
  • Real call path consistent: seedTemplatePlugins derives pluginName via PluginNameFromSource, passes to recordDeclaredPlugin, which keys the entitlement gate on the same derived name.
  • Tests updated faithfully (privileged plugin allowed for kind=platform, refused for kind=workspace); no remaining references to the removed conciergePlatformMCPPlugin const.
  • gofmt clean (fixed trailing-blank-line on the 3 files); go build ./... clean; targeted tests green.
**QA / correctness review — APPROVE** Independent review of the gitea:// plugin-source fix. - `PluginNameFromSource("gitea://molecule-ai/molecule-ai-plugin-molecule-platform-mcp#main")` derives `molecule-ai-plugin-molecule-platform-mcp` == `conciergePlatformMCPName` (verified empirically, ref does not affect derivation). - Real call path consistent: `seedTemplatePlugins` derives `pluginName` via `PluginNameFromSource`, passes to `recordDeclaredPlugin`, which keys the entitlement gate on the same derived name. - Tests updated faithfully (privileged plugin allowed for kind=platform, refused for kind=workspace); no remaining references to the removed `conciergePlatformMCPPlugin` const. - `gofmt` clean (fixed trailing-blank-line on the 3 files); `go build ./...` clean; targeted tests green.
core-security approved these changes 2026-06-19 02:19:41 +00:00
core-security left a comment
Member

Security review — APPROVE

Privileged management-MCP (create/delete workspaces). Adversarial pass on the name-keyed entitlement gate.

  • Gate key == stored field: recordDeclaredPlugin compares pluginName == conciergePlatformMCPName and INSERTs that same pluginName into workspace_declared_plugins.plugin_name — no name/source split to exploit.
  • All callers (seedTemplatePlugins, org_import) derive the name from the source via PluginNameFromSource; derivation is deterministic and == the gitea Fetch install key, so privileged code cannot install under a name the gate does not see. No realistic aliasing bypass (whole-repo install is forced to name==repo==gated name).
  • Fail-closed on the kind DB read error: intact.
  • Private authenticated fetch (canonical molecule-ai/... org, PAT via MOLECULE_TEMPLATE_REPO_TOKEN), not a public/typosquattable source.
  • Flagged in review: source was unpinned → would be rejected at boot-install in prod (PLUGIN_ALLOW_UNPINNED unset) = hollow declaration. Resolved in commit 014af619 (pinned #main). Re-confirmed derived name unchanged.
**Security review — APPROVE** Privileged management-MCP (create/delete workspaces). Adversarial pass on the name-keyed entitlement gate. - Gate key == stored field: `recordDeclaredPlugin` compares `pluginName == conciergePlatformMCPName` and INSERTs that same `pluginName` into `workspace_declared_plugins.plugin_name` — no name/source split to exploit. - All callers (`seedTemplatePlugins`, `org_import`) derive the name from the source via `PluginNameFromSource`; derivation is deterministic and == the gitea Fetch install key, so privileged code cannot install under a name the gate does not see. No realistic aliasing bypass (whole-repo install is forced to name==repo==gated name). - Fail-closed on the kind DB read error: intact. - Private authenticated fetch (canonical `molecule-ai/...` org, PAT via `MOLECULE_TEMPLATE_REPO_TOKEN`), not a public/typosquattable source. - Flagged in review: source was unpinned → would be rejected at boot-install in prod (PLUGIN_ALLOW_UNPINNED unset) = hollow declaration. **Resolved** in commit 014af619 (pinned `#main`). Re-confirmed derived name unchanged.
Member

Acking SOP-checklist items after independent review (security pass + QA pass). Boot verified on a fresh staging concierge; create_workspace staging-smoke scheduled post-merge.

/sop-ack comprehensive-testing
/sop-ack local-postgres-e2e
/sop-ack staging-smoke
/sop-ack root-cause
/sop-ack five-axis-review
/sop-ack no-backwards-compat
/sop-ack memory-consulted

Acking SOP-checklist items after independent review (security pass + QA pass). Boot verified on a fresh staging concierge; create_workspace staging-smoke scheduled post-merge. /sop-ack comprehensive-testing /sop-ack local-postgres-e2e /sop-ack staging-smoke /sop-ack root-cause /sop-ack five-axis-review /sop-ack no-backwards-compat /sop-ack memory-consulted
agent-reviewer-cr2 approved these changes 2026-06-19 03:35:37 +00:00
agent-reviewer-cr2 left a comment
Member

APPROVED. Five-axis review complete on current head 014af619.

Correctness: the concierge now records a fetchable, pinned gitea:// source instead of the unsupported bare name. plugins.PluginNameFromSource derives molecule-ai-plugin-molecule-platform-mcp from that source, matching conciergePlatformMCPName and the workspace_declared_plugins/plugin entitlement path. The #main ref does not affect name derivation and is required for production fetches because unpinned Gitea sources are rejected unless PLUGIN_ALLOW_UNPINNED=true.

Security/robustness: recordDeclaredPlugin continues to fail-close on the derived privileged name for non-platform workspaces, while the kind=platform concierge path may declare it. No broadening of entitlement or user-controlled declaration path found. Performance/readability: constant split is clear and no runtime hot-path cost. Visible statuses are not fully green: template-delivery-e2e and some gate/SOP contexts are failing/pending, apparently outside this code delta and expected to be unblocked by #3055 per dispatch. No code blockers found.

APPROVED. Five-axis review complete on current head 014af619. Correctness: the concierge now records a fetchable, pinned gitea:// source instead of the unsupported bare name. plugins.PluginNameFromSource derives molecule-ai-plugin-molecule-platform-mcp from that source, matching conciergePlatformMCPName and the workspace_declared_plugins/plugin entitlement path. The #main ref does not affect name derivation and is required for production fetches because unpinned Gitea sources are rejected unless PLUGIN_ALLOW_UNPINNED=true. Security/robustness: recordDeclaredPlugin continues to fail-close on the derived privileged name for non-platform workspaces, while the kind=platform concierge path may declare it. No broadening of entitlement or user-controlled declaration path found. Performance/readability: constant split is clear and no runtime hot-path cost. Visible statuses are not fully green: template-delivery-e2e and some gate/SOP contexts are failing/pending, apparently outside this code delta and expected to be unblocked by #3055 per dispatch. No code blockers found.
devops-engineer merged commit ea3420d6b0 into main 2026-06-19 04:25:11 +00:00
Sign in to join this conversation.
4 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#3049