Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
47 changes: 47 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Bug report
description: Report a reproducible MoDiff backend or runtime defect.
title: "[Bug] "
labels:
- bug
body:
- type: markdown
attributes:
value: |
Do not include Hugging Face tokens, private media, personal paths, or exploit details. Report security issues through the private process in `SECURITY.md`.
- type: checkboxes
attributes:
label: Before filing
options:
- label: I searched existing issues and tested the current supported branch.
required: true
- label: This is not a security vulnerability or a request for help with an unsupported third-party runtime.
required: true
- type: textarea
attributes:
label: Problem
description: Explain what is wrong and why it matters.
validations:
required: true
- type: textarea
attributes:
label: Minimal reproduction
description: Provide the smallest graph, command, or code sample that reproduces the issue without private data.
render: shell
validations:
required: true
- type: textarea
attributes:
label: Expected and actual behavior
validations:
required: true
- type: textarea
attributes:
label: Environment
description: Include the MoDiff commit, OS, Python version, accelerator profile, and sanitized preflight output.
validations:
required: true
- type: textarea
attributes:
label: Sanitized logs
description: Include the shortest relevant traceback. Remove tokens, URLs with credentials, media, prompts, and local paths.
render: text
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Feature request
description: Propose a focused change within MoDiff's Hugging Face Diffusers runtime boundary.
title: "[Feature] "
labels:
- enhancement
body:
- type: textarea
attributes:
label: Motivation
description: Describe the user problem before describing an implementation.
validations:
required: true
- type: textarea
attributes:
label: Proposed user experience
description: Show how a user would invoke and understand the feature.
validations:
required: true
- type: textarea
attributes:
label: Diffusers support
description: Link the relevant official Diffusers or Modular Diffusers API/model documentation and explain how the proposal stays inside that execution boundary.
validations:
required: true
- type: textarea
attributes:
label: Alternatives and compatibility
description: Note existing MoDiff patterns, graph/API compatibility, dependencies, hardware needs, and migration concerns.
validations:
required: true
- type: textarea
attributes:
label: Validation plan
description: List focused unit, contract, integration, documentation, and live-model checks as applicable.
validations:
required: true
24 changes: 19 additions & 5 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@

-

## Scope And Human Review

- Agreed scope / linked issue or discussion:
- Human self-review completed; every changed line and generated artifact is understood: yes / no
- AI assistance used (tool and role), or `none`:
- Follow-up work deliberately left out of this change:

## Checks

- [ ] `uv lock --check`
- [ ] `uv pip check`
- [ ] `uv run python -m modiff.preflight --json --check-port 8088 --fail-on-error`
- [ ] `uv run python -m unittest discover -s tests -v`
- [ ] `uvx --from ruff==0.12.7 ruff check . --select E9,F`
- [ ] `uv pip check --python .venv/bin/python` (use `.venv/Scripts/python.exe` on Windows)
- [ ] `./.venv/bin/python -m modiff.preflight --json --check-port 8088 --fail-on-error`
- [ ] `./.venv/bin/python -m pytest -q`
- [ ] `bash -n run.sh` when a POSIX shell is available
- [ ] Exact command results and any skipped checks are recorded below.

## Validation Results

- Commands and results:
- Checks skipped, with reason:
- Live accelerator/model evidence, or `not claimed`:

## Compatibility, Security, And Proof

- [ ] Existing graph, HTTP, WebSocket, storage, and `mellon` import compatibility is preserved or the migration is described.
- [ ] Current graph, HTTP, WebSocket, storage, and Python package contracts are preserved or deliberately migrated with tests.
- [ ] Client-facing changes include the matching MoDiff-client change and bundled-client update plan.
- [ ] File access, custom code, model loading, tokens, origins, and request-size implications were reviewed where relevant.
- [ ] Unit/contract, registry, live backend, accelerator, and real model-generation evidence are reported separately.
Expand Down
47 changes: 47 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: CI
on: [push, pull_request]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
with: { version: '0.11.26' }
- run: uvx --from ruff==0.12.7 ruff check . --select E9,F
- run: bash -n install.sh run.sh scripts/with-runtime-env.sh

backend:
strategy:
matrix:
include:
- os: ubuntu-latest
python: '3.12'
managed-python: ./.venv/bin/python
- os: windows-latest
python: '3.12'
managed-python: ./.venv/Scripts/python.exe
- os: macos-14
python: '3.12'
managed-python: ./.venv/bin/python
runs-on: ${{ matrix.os }}
timeout-minutes: 35
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with: { python-version: '${{ matrix.python }}' }
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
with: { version: '0.11.26' }
- run: python -m modiff.install --accelerator cpu --backend-only --non-interactive --json
- run: uv pip install --python ${{ matrix.managed-python }} -r requirements/test.txt
- run: uv pip check --python ${{ matrix.managed-python }}
- run: ${{ matrix.managed-python }} -m modiff.preflight --json --check-port 8088 --fail-on-error
- run: ${{ matrix.managed-python }} -m pytest -q
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,42 @@ config.ini
artifacts/
.pytest_cache/
.ruff_cache/
*.egg-info/

# Installer-managed downloads, toolchains, journals, and diagnostics.
.modiff/

custom/*
!custom/.gitkeep
!custom/Example/
#!custom/Example/**

data/*
!data/model-artifact-catalog.json
!data/graphs/
!data/workflow-library-manifest.json
data/graphs/*
!data/graphs/modiff/
!data/graphs/modiff/**
!data/graphs/modular_diffusers/
!data/graphs/modular_diffusers/**
!data/graphs/studio/
!data/graphs/studio/**
!data/graphs/experimental/
!data/graphs/experimental/**
#!data/.gitkeep

web/user/*
!web/user/ExampleField.js

# The client resolves Gallery bytes from a pinned public Hugging Face Dataset.
# Offline snapshots are local caches and must not be mirrored into source Git.
web/template-gallery/

.venv
.venv.next/
.venv.previous/
.venv.failed/
venv
.cursorrules
__pycache__
Expand Down
36 changes: 36 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# MoDiff Backend Agent Instructions

These rules apply to AI-assisted work in this repository. `CONTRIBUTING.md` is the complete contributor guide; read it together with `SECURITY.md` and the relevant document under `docs/` before editing.

## Scope And Runtime Boundary

- Keep each change focused on a diagnosed problem. Trace the existing call path and tests before editing, and remove incidental generated files from the diff.
- Hugging Face Diffusers and Modular Diffusers are MoDiff's only supported model-execution layer. Do not add an alternate graph executor, hosted inference provider, independent Transformers application, or another model driver.
- Supporting libraries used by Diffusers and ordinary deterministic media processing are not alternate drivers. They must remain narrowly scoped, documented, and covered by tests.
- Never enable arbitrary remote Python code, mutable model revisions, or custom model execution implicitly. Trust-sensitive behavior requires an explicit operator choice and an immutable revision.
- Prefer existing module, graph, configuration, error, and test patterns. Do not create a parallel workflow representation or model-loading path.

## Diffusers And Modular Diffusers

- Keep the reviewed Diffusers revision pinned in the executable installation contract and update its compatibility test when changing it.
- Use Diffusers loaders, pipelines, components, schedulers, adapters, and offload hooks instead of reimplementing upstream behavior.
- Modular blocks should declare inputs, outputs, and dependencies clearly, avoid hidden cross-block state, and remain composable through `init_pipeline`.
- Keep model-specific differences explicit and small. Put reusable behavior in the existing shared Diffusers modules rather than copying it into another pipeline.
- Prefer `safetensors`; document and test any unavoidable unsafe deserialization or remote-code boundary.

## Security And Data

- Treat every HTTP, WebSocket, filesystem, archive, URL, model-repository, and workflow boundary as untrusted input.
- Mutations must not use `GET`. Resolve filesystem targets before access, reject traversal and symlink escapes, and keep request sizes finite.
- The supported server boundary is a trusted single user on `127.0.0.1`; do not weaken that default or imply that CORS is authentication.
- Never commit `config.ini`, tokens, local paths, generated outputs, model caches, qualification workspaces, virtual environments, logs, or template media.
- Public template media belongs in the configured public Hugging Face Dataset repository. Keep only its versioned source descriptor, hashes, and documentation in Git.

## Quality And Evidence

- Add a regression test that fails for the original defect and covers related instances of the same pattern.
- Keep public interfaces, errors, configuration, and non-obvious invariants documented. Examples must be runnable and must not require private files.
- Distinguish static inspection, unit/contract tests, HTTP smoke tests, and live model output. Never present one proof level as another.
- Report the exact commands and results you ran. A human maintainer remains responsible for understanding every changed line and reviewing generated content.

Run the focused tests while iterating, then use the complete backend gate documented in `CONTRIBUTING.md`. For changes that affect the client contract, also run the compatible MoDiff Client gate and its relevant browser tests.
47 changes: 26 additions & 21 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,34 @@

MoDiff is an experimental local backend with a separately maintained frontend bundle. Contributions should preserve the local-only security boundary, existing graph/API compatibility, and reproducible dependency state.

Before starting, read [SECURITY.md](SECURITY.md) and [docs/modiff-backend-namespace.md](docs/modiff-backend-namespace.md).
Before starting, read [SECURITY.md](SECURITY.md) and the relevant guide in [docs/README.md](docs/README.md).

## Development setup

Use Python 3.12 and the committed lockfile:
Use Python 3.12 and create the same managed CPU profile used by baseline CI:

```bash
uv sync --frozen
uv run python -m modiff.preflight --json --check-port 8088 --fail-on-error
./install.sh --accelerator cpu --backend-only
uv pip install --python .venv/bin/python -r requirements/test.txt
./scripts/with-runtime-env.sh ./.venv/bin/python -m modiff.preflight --json --check-port 8088 --fail-on-error
```

Install only the extras required for the code path being changed. For example:
On Windows PowerShell, use the corresponding managed commands:

```bash
uv sync --frozen --extra quantization --extra spandrel
```powershell
.\install.ps1 -Accelerator cpu -BackendOnly
uv pip install --python .venv/Scripts/python.exe -r requirements/test.txt
.\.venv\Scripts\python.exe -m modiff.preflight --json --check-port 8088 --fail-on-error
```

Choose the qualified accelerator profile relevant to a hardware-specific change and report that validation separately. Do not use `uv sync` or `uv run`: the project is intentionally `uv`-unmanaged because the installer, not the generic resolver, owns the executable Torch profile.

Do not commit `config.ini`, `.env` files, model caches, generated outputs, local logs, virtual environments, or test caches.

## Backend conventions

- Put canonical backend implementation in `modiff/`. Keep `mellon/` limited to thin compatibility wrappers.
- Preserve existing HTTP/WebSocket field names and legacy graph fallbacks unless a deliberate migration includes client changes and compatibility tests.
- Put backend framework implementation in `modiff/` and built-in node implementations in `modules/`.
- Preserve current HTTP/WebSocket and graph-storage contracts unless a deliberate migration includes client changes and contract tests.
- Keep hardware probes non-fatal and retain CPU fallback when CUDA or MPS discovery fails.
- Treat file access, custom-module installation, remote code, token handling, and mutating routes as security-sensitive changes.
- Avoid importing the full model registry from lightweight diagnostics such as preflight.
Expand All @@ -51,32 +56,32 @@ Add focused tests for registry visibility, constructor safety, field contracts,

## Dependency changes

`pyproject.toml` and `uv.lock` are one change surface. After intentional metadata edits:
The selected file under `requirements/profiles/`, `pyproject.toml`, and `modiff/compatibility/accelerators.v1.json` jointly define the executable runtime contract. Keep direct wheel URLs hash-verified, keep remote source dependencies pinned to immutable revisions, and retain the exact reviewed Diffusers commit. After an intentional dependency or profile edit, rebuild the relevant managed profile:

```bash
uv lock
uv lock --check
uv sync --frozen
uv pip check
./install.sh --accelerator cpu --backend-only --repair
uv pip check --python .venv/bin/python
```

Commit the updated lockfile. Keep platform markers and optional extras explicit, and update the README/configuration guidance when an install profile changes. If the manual pip fallback is affected, update the matching requirements file too.
Use the corresponding accelerator instead of `cpu` when the change affects CUDA, ROCm, or MPS. Update the compatibility manifest and public installation guidance only when the evidence supports the claim. MoDiff deliberately has no `uv.lock`; do not generate one or describe the top-level requirements files as a cross-platform lock.

## Validation

The baseline backend checks are:

```bash
uv lock --check
uv pip check
uv run python -m modiff.preflight --json --check-port 8088 --fail-on-error
uv run python -m unittest discover -s tests -v
uvx --from ruff==0.12.7 ruff check . --select E9,F
uv pip check --python .venv/bin/python
./scripts/with-runtime-env.sh ./.venv/bin/python -m modiff.preflight --json --check-port 8088 --fail-on-error
./scripts/with-runtime-env.sh ./.venv/bin/python -m pytest -q
```

The wrapper applies the installed accelerator profile's process environment before Python imports Torch. On Windows, run `.venv/Scripts/python.exe` directly in the equivalent commands.

On a host with Git Bash or a POSIX shell:

```bash
bash -n run.sh
bash -n run.sh scripts/with-runtime-env.sh
```

Before reporting a live smoke test, confirm port `8088` is free or intentionally reuse the running process. A file-level inspection is not evidence that a model workflow completed; distinguish unit/contract tests, registry import checks, live backend HTTP checks, and real model-generation proof.
Expand All @@ -90,7 +95,7 @@ When a change affects the client/backend contract:
1. Update and validate the client source.
2. Run `npm ci` and `npm run check` in MoDiff-client.
3. Mirror the contents of its generated `dist/` directory into this repository's `web/` directory, deleting stale generated bundle files while preserving backend-owned `web/user/` custom fields.
4. Verify that `/`, `/assets/index.js`, and `/template-gallery/manifest.json` are served by a fresh backend.
4. Verify that `/` and `/assets/index.js` are served by a fresh backend. Verify `/template-gallery/manifest.json` only for an explicit offline/local Gallery build; a remote-asset build intentionally omits that directory and route.
5. Include the matching backend and client commit identifiers in the change description when the repositories are published separately.

See [README.md](README.md#updating-the-bundled-client) for exact-mirror examples.
Expand Down
Loading
Loading