Skip to content

[Feature] Backend: member-first Studio APIs with stable published service per member #325

@AbigailDeng

Description

@AbigailDeng

Summary

Introduce a real member backend model for Studio so each member has a stable, backend-generated publishedServiceId, and Studio can bind workflow / script / gagent implementations to that member-owned published service instead of falling back to the scope default service.

Why

Studio is already trying to present a member-first lifecycle (Build / Bind / Invoke / Observe), but the current backend contract is still mostly scope-first:

  • PUT /api/scopes/{scopeId}/binding defaults to the scope default service when ServiceId is omitted.
  • Studio currently does not have a real backend member entity to anchor identity.
  • serviceId is still leaking into places where the product model really wants memberId.

That prevents the correct product behavior:

  • Create member should support workflow / script / gagent.
  • Every member should own one stable published service.
  • Bind should mean: publish the current member revision to that member's service.
  • serviceId should be a published contract, not a substitute for memberId.

Required backend scope

1. Introduce a real member model

Add a backend-owned TeamMember / StudioMember model (naming can follow the domain conventions) with at least:

  • memberId
  • scopeId
  • displayName
  • description?
  • implementationKind
  • implementationRef
  • publishedServiceId
  • lifecycleStage
  • createdAt
  • updatedAt

Notes:

  • memberId is the stable identity.
  • publishedServiceId is the stable published contract surface.
  • workflowId / scriptId / gagentTypeName are implementation refs, not the member identity.

2. Backend-generated stable publishedServiceId

When a member is created, backend should generate and persist a stable publishedServiceId.

Requirements:

  • generated by backend, not frontend
  • generated once at member creation time
  • never recomputed from mutable display name on read
  • rename-safe
  • ordinary users do not need to type or manage it

Recommended rule:

  • derive from immutable memberId (optionally with a readable slug prefix)
  • store the generated value directly on the member record

3. Member-centric Studio APIs

Add member-centric APIs for Studio:

  • POST /api/scopes/{scopeId}/members
  • GET /api/scopes/{scopeId}/members
  • GET /api/scopes/{scopeId}/members/{memberId}
  • PUT /api/scopes/{scopeId}/members/{memberId}/binding
  • GET /api/scopes/{scopeId}/members/{memberId}/binding

POST /members should support creating members with:

  • implementationKind = workflow
  • implementationKind = script
  • implementationKind = gagent

and return at least:

  • memberId
  • displayName
  • implementationKind
  • publishedServiceId
  • lifecycleStage
  • initial implementation ref when available

4. Member binding behavior

PUT /members/{memberId}/binding should:

  1. load the member
  2. resolve that member's stable publishedServiceId
  3. publish the current implementation revision to that service
  4. return binding/contract metadata for Studio

This should support all three implementation kinds:

  • workflow
  • script
  • gagent

Reuse existing backend capabilities

The new member-centric path should reuse existing capabilities instead of rebuilding service binding logic from scratch.

Already reusable:

  • current scope binding command already supports explicit ServiceId
  • current scope binding command already supports:
    • workflow
    • script
    • gagent
  • existing service-level invoke / revisions / runs / bindings endpoints can remain the runtime/governance surface behind the member layer

So the main missing backend work is:

  • stable member identity
  • stable member-owned published service mapping
  • member-centric API surface
  • binding orchestration through that mapping

Acceptance criteria

  • Backend has a first-class member model with persistent memberId and publishedServiceId
  • Creating a member supports workflow / script / gagent
  • publishedServiceId is backend-generated, stable, and rename-safe
  • Studio can list members from backend without inferring them from workflow files or published services
  • Member binding publishes to the member's own stable published service, not the scope default service
  • Binding supports workflow, script, and gagent members
  • serviceId is no longer required as a user-facing input for ordinary Studio member binding
  • Legacy scope-first binding endpoints can remain available for other surfaces, but Studio is no longer blocked on them as its primary contract

Non-goals

  • frontend UI redesign in this issue
  • full team router redesign in this issue
  • removing all legacy scope-level runtime endpoints immediately

Migration / compatibility notes

Suggested compatibility approach:

  • keep existing scope-first endpoints for legacy/runtime surfaces
  • introduce member-first endpoints in parallel
  • let Studio migrate to the new member-first APIs
  • provide a compatibility/bootstrap path for existing members/scope-bound assets where needed

Related docs

  • docs/design/2026-04-22-team-member-first-prd.md
  • docs/design/2026-04-22-studio-member-lifecycle-spec.md
  • docs/design/2026-04-21-studio-workflow-member-lifecycle-prd.md

One-line outcome

After this issue, Studio should be able to treat member as the only primary object, with workflow / script / gagent as implementation types and published service as the member's stable publish surface.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions