App UI Extension Model v1¶
Purpose¶
Define how app-specific UI integrates into the GPUaaS platform shell.
This document exists to answer: 1. what the platform shell owns, 2. what app extensions own, 3. which extension points exist today, 4. how metadata-driven and component-driven apps differ, 5. what remains unfinished before this can be called a final plugin model.
This is the standalone contract for app UI integration. It complements, but does not replace:
- doc/architecture/Example_App_Developer_Reference_Workflow_v1.md
- doc/architecture/Build_an_App_for_GPUaaS_v1.md
- doc/architecture/External_App_Team_Integration_Guide_v1.md
Decision Summary¶
- GPUaaS owns the platform shell and generic operator workflow.
- Apps extend that shell through structured extension points, not by replacing the whole UI.
- The shell must support both:
- metadata-only apps
- component-driven apps
- Platform-owned inputs such as allocation, service account, and access credential selection should be reusable shell primitives.
- The public API remains the source of truth. UI extensions are a presentation and workflow layer over that contract.
- App builders need a coherent in-product developer/documentation experience so extension behavior, shell behavior, and API usage are understandable without leaving the product shell unnecessarily.
Shell Ownership¶
The platform shell owns: - catalog routing and inventory pages - generic deploy modal shell - generic instance detail page shell - generic lifecycle actions - generic member and member-operation history - shared picker primitives for platform-owned resources - session/project context - generic error handling and action banners
The shell should stay responsible for: - common navigation - common cards and layout - common loading and empty states - orchestration around public API calls for platform-owned concepts - developer/documentation shell entry points for app builders
App Extension Ownership¶
App extensions own:
- runtime-specific deploy fields when metadata alone is not enough
- runtime-specific instance summary panels
- runtime-specific day-2 action panels
- runtime-specific help text and operator hints
- app-specific mapping from deploy inputs to placement_intent or related app contract fields
App extensions should not own: - authentication/session handling - direct access to hidden backend routes - replacement of the whole page shell - generic audit/history presentation for platform-owned resources - bespoke documentation navigation that bypasses the shared developer area
Extension Shapes¶
The shell currently supports two extension shapes.
1. Metadata-only app¶
Use this when the app can be described by:
- required platform-owned inputs
- deploy summary/help text
- optional mapping from selected inputs to placement_intent
Current examples in code:
- ollama
- mlflow
- open-webui
Metadata-only apps can already drive: - no additional deploy inputs - single-allocation deploy input - multi-allocation deploy input - service-account selection/creation - access-credential selection/creation
2. Component-driven app¶
Use this when the app needs: - runtime-specific deploy form sections beyond shared shell primitives - runtime-specific instance panels - richer operator controls than the generic shell can infer
Current example in code:
- slurm-reference
This is the right shape for clustered or scheduler-style apps where: - the runtime summary is domain-specific - worker lifecycle controls are domain-specific - the operator workflow is more complex than a single declarative form
Current Implemented Extension Points¶
The current web shell has these implemented extension points:
Deploy metadata¶
Extension metadata can currently describe:
- allocation cardinality
- none
- single
- multiple
- whether a bootstrap access credential is required
- whether an operator service account is optional or required
- deploy summary/help strings
- binding tags for access-credential attachment
- how selected allocation inputs map into placement_intent
Deploy component hook¶
An extension may provide a custom deploy component when metadata is insufficient.
Current use: - Slurm custom deploy fields
Instance panel hook¶
An extension may provide custom runtime/action panels for the instance detail page.
Current use: - Slurm runtime summary and worker controls
Shared Platform-Owned UI Primitives¶
The shell now has reusable picker primitives for platform-owned inputs: - service account picker - access credential picker - single-allocation picker - multi-allocation picker
These are platform-owned because they operate on platform resources and should stay visually and behaviorally consistent across apps.
Rule: - if the input is a platform resource, prefer a shared shell primitive before adding app-local form controls.
How The Registry Works¶
The shell maps app identity to extension behavior through a registry keyed by:
- catalog slug
- instance runtime_backend
That registry is responsible for: - matching an app to its extension metadata - matching an app to optional custom components - exposing deploy and instance behavior to the shell
This keeps page routes from hardcoding app-specific logic directly.
Current Code Reality¶
As of this version: - the registry is real and typed - metadata-only apps are real - component-driven apps are real - shared picker primitives are real - generic instance history cards are reusable shell components
This means the extension model is no longer only a design idea. It is implemented in the web shell.
What Is Still Not Final¶
This is still not a final plugin system.
Remaining gaps: 1. the extension registry is still local code, not externally pluggable 2. there is no manifest/package model for app-provided UI bundles 3. extension metadata is still narrow and web-specific 4. tenant-scope and multi-project UI semantics are not fully modeled 5. multi-node clustered app flows are only partially represented 6. there is not yet a full standalone SDK/helper package for third-party UI extensions
So the current model should be described as: - a structured internal extension contract - good enough to guide productization - not yet the final external plugin packaging story
Guidance For App Teams¶
If your app is simple: - start as a metadata-only app - use shared shell inputs - avoid custom UI until the workflow truly needs it
If your app is complex: - use a custom deploy component and/or instance panels - keep platform-owned inputs routed through shared primitives where possible - keep app-specific logic in the extension, not scattered through page routes
Guidance For Platform Teams¶
When adding a new shared shell behavior: 1. ask whether it is genuinely reusable across more than one app class 2. if yes, add it as shared shell metadata or primitive 3. if no, keep it inside the app extension
When in doubt: - generic resource selection stays platform-owned - runtime-specific controls stay app-owned
Developer UX rule: - app teams should be able to move from docs, to API reference, to downloads, to project/service-account setup, to app deploy/operate flows without a broken shell experience or external-window dependency for core references.
Near-Term Next Steps¶
The next sensible productization steps are: 1. keep broadening metadata-only support where the shell can safely own behavior 2. avoid adding new page-local app checks 3. validate the model with more than one real app shape 4. eventually define whether this registry stays internal code or evolves into a packaged app-extension system