Add external-reference diffusers-directory support to the existing Pumas model-library system without creating parallel registries, importers, validators, or runtime-routing contracts.
- Backend metadata/schema changes for external-reference directory-root assets
- Backend import flow for external diffusers directories
- Asset validation and validation-state persistence
- Execution descriptor contract for runtime consumers
- Reconciliation, reindex, and delete/unregister changes needed to keep external assets reliable
- API and frontend read-surface updates required to expose
storage_kind,bundle_format, and validation health - Regression protection for existing file-based import, indexing, resolution, and delete behavior
- SDXL-specific decomposition or executable submodel support
- LoRA, ControlNet, refiner, or adapter composition
- App mapping support for external-reference bundles
- New standalone registry/database for external assets
- New dependency contract separate from the existing dependency-resolution system
- New runtime backend-selection field parallel to
recommended_backendandruntime_engine_hints
Pumas currently assumes the executable model asset is either a file or a library-owned directory whose runtime path can be reduced to a primary file. Diffusers bundles break that assumption because the executable unit is the bundle root directory. A correct implementation must preserve existing model-library durability and indexing behavior while adding external-reference support as a first-class asset shape.
- Reuse the current metadata-backed model-library + SQLite index architecture in
pumas-core. - Preserve stable
model_idgeneration from library-owned registry artifacts. - Keep backend as the source of truth for import validation and external-asset health.
- Do not create overlapping validation semantics with the dependency-resolution contract.
- Prevent external-reference assets from entering existing app-mapping flows.
- Respect current cross-layer verification requirements from the testing standards.
- Keep module changes decomposed enough to avoid overloading
importer.rsandlibrary.rs.
- Milestone one supports only
storage_kind=external_reference,bundle_format=diffusers_directory, andtask_type_primary=text-to-image. source_pathandentry_pathare equal for milestone one, but both are persisted separately.- Execution descriptor behavior in milestone one is fail-hard for
degradedandinvalidasset validation states. - Dependency-resolution data is reused from the current dependency contract rather than redefined.
- Existing
ModelMetadatapersistence and indexing flow - Existing model-library reconciliation flow
- Existing dependency-resolution contract and APIs
- Existing RPC model surfaces and frontend type contracts
- Documentation updates for affected model-library modules
ModelMetadatapersisted fields and effective metadata projectionsModelImportResult- New execution-descriptor DTO and RPC surface
- Existing list/get/search model surfaces
- Existing frontend API types for model metadata display
- Per-model
metadata.json models.dbindexedmetadata_jsonprojection- Library-owned registry directories under the model library root
- Reconciliation currently adopts metadata-missing model directories and stages partial downloads. External-reference assets must not be mistaken for orphans or partial downloads.
- Validation refresh after startup/reindex must update current-state-only
validation_stateandvalidation_errorsatomically with metadata/index updates. - Import and revalidate flows must be idempotent so restart/reindex does not duplicate registry artifacts or drift
model_id. - Lifecycle ownership:
- Import flow creates the registry artifact and initial validation result.
- Reconciliation/reindex refreshes persisted asset validation state.
- Delete/unregister removes library-owned artifacts only for
external_reference. - Execution descriptor resolution reads persisted health and fails hard for non-
validassets in milestone one.
| Risk | Impact | Mitigation |
|---|---|---|
| External support is implemented as a second registry path | High | Extend ModelMetadata, save_metadata, index_model_dir, and existing RPC surfaces instead of adding a separate asset store |
| Asset validation and dependency validation use the same labels without distinction | High | Name and document asset-level validation fields separately in metadata and execution descriptor; reuse dependency contract as a nested payload only |
| Existing file-based imports regress due to shared importer changes | High | Add a dedicated external-directory import path and regression tests for current file and in-place imports |
| Reconciliation treats external-reference assets as orphans or missing-file models | High | Gate orphan/adoption and reclassification logic on persisted storage_kind and registry-artifact invariants |
| Delete flow removes user-owned bundle contents | High | Branch delete/unregister behavior on storage_kind inside existing ModelLibrary delete semantics |
| External assets leak into app mapping | Medium | Add an explicit mapping exclusion for storage_kind=external_reference and test it |
importer.rs and library.rs become oversized catch-all modules |
Medium | Extract focused modules for external asset validation and execution descriptor orchestration |
- None at plan creation time.
- Reason: Contract semantics, milestone scope, and acceptance criteria are now specific enough to sequence implementation safely.
- Revisit trigger: The team decides degraded assets should be executable in milestone one or wants app mapping in scope.
- External-reference diffusers bundles are represented as normal library models with extended metadata, not as a separate registry system.
- Import, validation, indexing, reconciliation, and delete/unregister behavior are integrated into existing model-library flows.
- Runtime consumers obtain bundle execution data only through the new execution descriptor contract.
- Existing file-based model behavior remains unchanged and covered by regression verification.
- Documentation and module READMEs reflect the new contract and lifecycle.
Goal: Define the new asset shape within existing model-library contracts and document how it integrates with current systems.
Tasks:
- Extend
ModelMetadataand related Rust/TS contracts withsource_path,entry_path,storage_kind,bundle_format,pipeline_class,import_state, asset-levelvalidation_state, and asset-levelvalidation_errors - Define explicit asset-level enum/value semantics distinct from dependency validation semantics
- Add execution-descriptor DTOs and versioning policy at the contract layer
- Update
model_librarydocumentation to state the new external-reference invariants, mapping exclusion, and execution-descriptor contract - Record facade-preservation note: preserve existing model-library public surfaces where possible and add new capability via append-only contracts
Verification:
- Contract type additions compile across Rust and frontend type layers
- Documentation updates reflect actual persisted and consumer-facing semantics
- Review confirms no duplicate top-level backend-routing field is introduced
Status: Completed on 2026-03-08
Goal: Add a dedicated external-directory import path that creates a library-owned registry artifact while preserving external bundle layout.
Tasks:
- Add a focused external-asset import module/service rather than extending copy-based import logic inline
- Implement registry-artifact creation under the library root with stable
model_idderivation - Update
ModelImportResultto returnmodel_idand status only - Ensure existing copy import and existing in-place import continue to use current behavior unchanged
- Update module READMEs for any new or substantially changed backend directories
Verification:
- Unit tests cover successful external-directory registration without copying or renaming bundle contents
- Regression tests cover existing file import and existing in-place import behavior
- Restart/reindex preserves
model_idand registry artifact stability
Status: Completed on 2026-03-08
Goal: Integrate asset validation into current backend-owned metadata and reconciliation flows without adding a parallel health subsystem.
Tasks:
- Add a dedicated diffusers-directory validator module with deterministic path and component checks
- Persist current-state-only asset
validation_stateandvalidation_errors - Integrate validation refresh into startup/reindex/reconciliation flow
- Gate orphan adoption, partial-download handling, and reclassification logic so external-reference assets are not misclassified
- Define asset-health update behavior when the external directory is moved, deleted, or becomes incomplete
Verification:
- Unit tests cover valid, degraded, and invalid asset validation outcomes
- Integration tests cover restart/reindex producing stable
model_id,entry_path, andvalidation_state - Acceptance check verifies metadata/index output reflects validation degradation after external asset drift
Status: Completed on 2026-03-08
Goal: Introduce one runtime-facing execution descriptor that reuses current metadata and dependency systems and displaces primary-file-first routing for bundle assets.
Tasks:
- Add
resolve_model_execution_descriptor(model_id)to the backend/RPC surface - Compose the descriptor from persisted metadata plus existing dependency-resolution output
- Enforce milestone-one fail-hard behavior for
degradedandinvalidexternal assets - Update torch and other runtime-facing consumers to avoid
primary_filerouting for external-reference bundles - Keep existing
primary_filesurfaces for file-based models only where still valid
Verification:
- Integration tests verify
validexternal assets return bundle-rootentry_path - Integration tests verify
degradedandinvalidexternal assets fail hard - Cross-layer acceptance check verifies producer metadata -> execution descriptor -> consumer-visible output consistency
Status: Completed on 2026-03-08
Goal: Expose external-reference status to operators while explicitly blocking unsupported flows.
Tasks:
- Extend list/get/search surfaces to expose
storage_kind,bundle_format, and assetvalidation_state - Update frontend types and metadata display surfaces for external assets
- Add explicit mapping exclusion for external-reference assets in existing mapping flows
- Update delete/unregister behavior and operator-facing wording for external ownership
- Add targeted documentation for operator-visible semantics and blocked app mapping
Verification:
- UI/API contract tests verify operator-visible metadata fields
- Integration tests verify external-reference assets are excluded from mapping previews/apply flows
- Integration tests verify delete/unregister remove only library-owned registry artifacts
Status: In progress
Update during implementation:
- 2026-03-08: Plan created against current Rust/Electron codebase after reviewing import, metadata, dependency, reconciliation, delete, and runtime-routing paths for duplication risk.
- 2026-03-08: Added external diffusers bundle metadata contracts, dedicated external bundle validation/import flow, runtime execution descriptor resolution, safe external-reference delete semantics, and mapping exclusion for external assets.
- 2026-03-08: Exposed backend/RPC/frontend API surfaces for external diffusers registration and execution descriptor resolution. Full frontend directory-import UX remains deferred.
- Commit after each milestone or smaller logical slice is complete and verified.
- Keep metadata/schema, runtime-routing, and UI/operator-surface changes in separate reviewable commits when possible.
- Follow commit format/history cleanup rules from
COMMIT-STANDARDS.md.
| Owner/Agent | Scope | Output Contract | Handoff Checkpoint |
|---|---|---|---|
| None | None | None | Revisit only if backend contract work and frontend/operator-surface work can proceed independently without coupling risk |
- The team changes milestone-one execution policy for
degradedassets - App mapping for external-reference assets is brought into scope
- Metadata changes require a SQLite schema projection change beyond current
metadata_jsonusage - The chosen registry-artifact location cannot preserve stable
model_idbehavior - Runtime consumers require a different compatibility policy than append-only execution descriptor changes
- Prefer a metadata-extension approach over any sidecar asset database. Why: it preserves the current source-of-truth model-library architecture, reduces migration risk, and keeps reconcile/index behavior unified. Impact: lower implementation risk, no added registry subsystem.
- Extract focused modules for external asset validation and execution descriptor orchestration instead of growing
importer.rsandlibrary.rsfurther. Why: it aligns with file-size and responsibility standards and makes long-term maintenance safer. Impact: slightly more upfront refactor work, lower future drift.
- Milestone 1: external-asset metadata enums/fields, execution descriptor DTO, and contract documentation.
- Milestone 2: dedicated external diffusers registration path that creates a library-owned registry artifact without copying bundle contents.
- Milestone 3: backend-owned diffusers validation plus persisted validation refresh through index/query/descriptor flows.
- Milestone 4: runtime execution descriptor plus torch consumer routing off the descriptor instead of primary-file-first logic.
- Milestone 5 (partial): external-reference mapping exclusion, delete safety, and API/type exposure for operator-facing metadata.
- The backend/API capability is implemented ahead of a dedicated frontend directory-import workflow.
- Reason: the existing UI import path is file-centric and would need additional metadata-entry UX to register external bundles cleanly.
- Follow-up trigger: when the team is ready to add a directory picker and external-bundle review/import dialog in the frontend.
- Add a dedicated frontend directory-import flow for external diffusers bundles.
- Consider richer operator-visible metadata presentation for external-reference health in the metadata modal/list views.
cargo test -p pumas-library model_library:: --manifest-path rust/Cargo.tomlcargo test -p pumas-library model_library::mapper::tests::test_preview_mapping_skips_external_reference_assets --manifest-path rust/Cargo.tomlcargo test -p pumas-rpc --manifest-path rust/Cargo.toml --no-runnpm run check:typesinfrontend/still fails on pre-existing unrelated TypeScript issues inModelMetadataModal.tsxanduseManagedApps.test.ts.
- Module README updated:
docs/plans/README.md - ADR added/updated: N/A
- PR notes completed per
templates/PULL_REQUEST_TEMPLATE.md: N/A
This plan is intentionally scoped to execution decisions, integration points, and risk controls. Expand detail only when implementation uncovers a re-plan trigger.