feat(plugins): version subscription (track: tag:vX.Y.Z) + queue-on-drift, no auto-apply #113

Closed
opened 2026-05-08 14:52:58 +00:00 by claude-ceo-assistant · 0 comments

Problem

POST /workspaces/:id/plugins is a one-shot install. Once a plugin lands in <config_path>/plugins/<name>/, the platform never checks upstream again. If we tag v1.0.2 of molecule-skill-five-axis-review on Gitea, Reno-Stars (running v1.0.0) keeps running v1.0.0 forever unless someone manually re-installs.

We don't want unsolicited auto-updates either (per #2 in this batch — stage/canary required), but we DO want a subscription model: a workspace can opt into following a specific plugin's tagged releases. Then platform-side machinery (poll job, or webhook from Gitea) can stage→canary→fan-out.

Proposed approach

  1. DB shape — extend workspace_plugins (or add workspace_plugin_subscriptions) with track: "tag:vX.Y.Z" | "tag:latest" | "sha:abc123" | "none". Default none (current behavior).
  2. Resolver — when a plugin is installed with a track other than none, store the tracked ref. On a periodic check (cron OR Gitea webhook on tag-create), compare tracked-tag's resolved SHA vs installed SHA; if drift, queue update.
  3. Update gating — queued updates DO NOT auto-apply. They're surfaced via GET /admin/plugin-updates-pending for operator review (matches the stage→canary→fan-out policy in internal#TBD).
  4. Apply stepPOST /admin/plugin-updates/:id/apply triggers the install for the queued update on the listed workspaces; honors hot-reload classifier from #3 if applicable.

Acceptance criteria

  • Migration adds track column to relevant table
  • Plugin install endpoint accepts ?track=tag:vX.Y.Z parameter (optional)
  • Background check (cron or webhook) detects drift; logs queued updates
  • GET /admin/plugin-updates-pending returns queued updates
  • Operator-explicit apply endpoint exists; no automatic apply
  • Tests cover: track:none = no queue; track:tag = queue on drift; apply triggers install + classifier

Out of scope

  • Auto-apply (would defeat the safety model)
  • Per-tenant tag overrides (later)
  • Plugin signing / supply-chain verification (separate RFC)

Refs

  • internal#TBD — plugin-update-policy.md (#2 in this batch)
  • molecule-core#TBD — hot-reload classifier (#3 in this batch)
  • Existing workspace-server/internal/plugins/github_resolver.go — base for tag resolution
## Problem `POST /workspaces/:id/plugins` is a one-shot install. Once a plugin lands in `<config_path>/plugins/<name>/`, the platform never checks upstream again. If we tag v1.0.2 of `molecule-skill-five-axis-review` on Gitea, Reno-Stars (running v1.0.0) keeps running v1.0.0 forever unless someone manually re-installs. We don't want unsolicited auto-updates either (per #2 in this batch — stage/canary required), but we DO want a subscription model: a workspace can opt into following a specific plugin's tagged releases. Then platform-side machinery (poll job, or webhook from Gitea) can stage→canary→fan-out. ## Proposed approach 1. **DB shape** — extend `workspace_plugins` (or add `workspace_plugin_subscriptions`) with `track: "tag:vX.Y.Z" | "tag:latest" | "sha:abc123" | "none"`. Default `none` (current behavior). 2. **Resolver** — when a plugin is installed with a `track` other than `none`, store the tracked ref. On a periodic check (cron OR Gitea webhook on tag-create), compare tracked-tag's resolved SHA vs installed SHA; if drift, queue update. 3. **Update gating** — queued updates DO NOT auto-apply. They're surfaced via `GET /admin/plugin-updates-pending` for operator review (matches the stage→canary→fan-out policy in internal#TBD). 4. **Apply step** — `POST /admin/plugin-updates/:id/apply` triggers the install for the queued update on the listed workspaces; honors hot-reload classifier from #3 if applicable. ## Acceptance criteria - Migration adds `track` column to relevant table - Plugin install endpoint accepts `?track=tag:vX.Y.Z` parameter (optional) - Background check (cron or webhook) detects drift; logs queued updates - `GET /admin/plugin-updates-pending` returns queued updates - Operator-explicit apply endpoint exists; no automatic apply - Tests cover: track:none = no queue; track:tag = queue on drift; apply triggers install + classifier ## Out of scope - Auto-apply (would defeat the safety model) - Per-tenant tag overrides (later) - Plugin signing / supply-chain verification (separate RFC) ## Refs - internal#TBD — plugin-update-policy.md (#2 in this batch) - molecule-core#TBD — hot-reload classifier (#3 in this batch) - Existing `workspace-server/internal/plugins/github_resolver.go` — base for tag resolution
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#113
No description provided.