Add RFC-0014: Cross-workspace MLflow asset copying for fork-and-iterate workflows - #51
Al-Pragliola wants to merge 2 commits into
Conversation
…te workflows (#1) * Add RFC-0014: Cross-workspace MLflow asset copying for fork-and-iterate workflows Signed-off-by: Alessio Pragliola <seth.pro@gmail.com>
| --- | ||
| start_date: 2026-09-02 | ||
| mlflow_issue: TBD | ||
| rfc_pr: https://github.com/Al-Pragliola/rfcs/pull/1 |
There was a problem hiding this comment.
Could you update this to the current PR?
mprahl
left a comment
There was a problem hiding this comment.
I had reviewed this internally previously, so just forwarding my approval here.
|
|
||
| The unique target identity lets detach resolve the relationship from workspace, name, and the route's resource type. The association and lineage identifiers remain internal; they are not exposed in requests or resource responses. | ||
|
|
||
| The target index supports search joins filtered by destination workspace, resource type, and `SYNC` relationship. The unique target constraint supports exact destination-identity lookups. |
There was a problem hiding this comment.
Any concerns with order by and pagination across multiple index joins? I think worst case some data could be omitted if data in one table mutates but probably fine since the page could be refreshed / query made again so more of a minor concern.
There was a problem hiding this comment.
Yes, concurrent changes could cause items to move between pages. That’s why the RFC limits the no-duplicates/no-omissions guarantee to an unchanged result set. We still need consistent ordering across native and synced assets, with a stable tie-breaker, before applying pagination. Otherwise, results could be incorrect even without concurrent changes
| forked_prompt = client.fork_prompt( | ||
| prompt, | ||
| target_workspace="team-search", | ||
| target_name="support-assistant-team", | ||
| ) | ||
| ``` |
There was a problem hiding this comment.
Am I correct in assuming that all fork_xyz APIs take the same args (resource id, target_workspace, target_name) ? If so could we make the client more minimal like so:
fork(resource_type, resource_id, tgt_wspc, tgt_name)
... same for sync/copy/detach
?
There was a problem hiding this comment.
You’re right that the signatures have the same shape across asset types. One detail: the proposal takes the source object rather than an ID, so its workspace and name travel together.
I was leaning toward methods like fork_prompt because they make the expected input and return type clear and are easy to discover in the client. We can still share the implementation underneath. A generic fork would be useful for code handling several resource types, though.
My preference is to keep the typed methods, but I’m open to consolidating them.. wdyt @mprahl ?
| | Operation | Destination content | Relationship to source | | ||
| | :--- | :--- | :--- | | ||
| | Sync | Read-only, live view of source metadata | `SYNC` | | ||
| | Fork | Editable snapshot | `FORK` | | ||
| | Copy | Editable snapshot | None | | ||
| | Detach | Materializes current synced content in place, or preserves existing fork content | Removes the `SYNC` or `FORK` relationship | |
There was a problem hiding this comment.
Some meta questions:
- Can a forked resource be forked? Also can a resource be forked to any N number of other workspaces?
- Can the same resource be forked, synced, and copied at the same time, or only one state at a time is allowed?
- Seems like destination workspace users can discover where the resource was synced or forked from, but can target workspace users tell where their resource was forked to? Can they break a link from their end?
There was a problem hiding this comment.
-
Yes to both. A fork can be forked again: if B forks A, makes changes, and C forks B, C gets B’s current content and its source relationship points to B. One source can also be forked into multiple workspaces.
-
Yes, the same source can be synced, forked, and copied to different destinations at the same time. These aren’t exclusive states on the source. Each destination identity can have at most one incoming relationship; independent copies have none.
-
On the source side, the proposal doesn’t currently include an API to list or individually detach outgoing links. It handles dependents when deleting the source, but I’d suggest leaving general link management outside the initial scope. Detaching would preserve destination content: a fork keeps its data, and a sync becomes a snapshot that stops receiving updates. Independent copies aren’t tracked.
Do you think we should spell out these cases in the RFC?
| | Copy | Editable snapshot | None | | ||
| | Detach | Materializes current synced content in place, or preserves existing fork content | Removes the `SYNC` or `FORK` relationship | | ||
|
|
||
| `SYNC` stores a relationship without creating destination asset or version rows. `FORK` and `COPY` materialize destination metadata. Sync and fork fail if the destination identity is already occupied by a native asset or another link, including a sync to the same source. Ordinary asset creation also rejects names occupied by links. These name checks and destination creation must be atomic so concurrent requests cannot create duplicate identities. |
There was a problem hiding this comment.
Will this still mean that only READ in the destination workspace is needed to access the resource, especially in the (READ, resource_name) case?
I think the auth model could be updated to use target_workspace from the link to handle these cases but wanted to check if this scenario is covered otherwise.
There was a problem hiding this comment.
Yes, that’s the intent, including READ on a specific destination resource. Authorization should use target_workspace and target_name from the link, without requiring source access.
Do you think we should state this explicitly in the RFC’s authorization section?
Teams maintaining approved AI assets in a shared workspace need a supported way to reuse them in team workspaces, customize them, and promote approved changes back.
This RFC proposes cross-workspace sharing and copying for prompts, registered models, and MCP server registry entries through the MLflow UI, Python SDK, and REST APIs.
The proposal supports four operations:
Operations cover the complete asset and its version history. Replacing an existing destination requires explicit confirmation and permission to update and delete its contents. Source deletion preserves dependent content, with explicit detachment required for synced assets.
Model artifact references are preserved without copying the underlying files. MCP access bindings are excluded and configured separately in the destination.
The RFC includes user journeys, API and SDK contracts, authorization rules, storage design, and lifecycle behavior.