# AGENTS.md Tool-agnostic agent guidance for the `ltx2.3-AIO-generator` repo. If you're driving Claude Code, Cursor, Aider, Codex, or anything else with file-edit + shell access, **start here**. This file is the authoritative project rulebook. - `CLAUDE.md` — Claude-specific extensions and the full gotchas catalogue (what & why). - `SKILLS.md` — process / how-to (debugging, deployment, when to commit, useful one-liners). - `README.md` — public-facing project intro (different audience). --- ## TL;DR — the seven rules 1. **Mayank Gupta is sole author on every commit.** No agent co-author trailers. No "generated with…" footers. No `--author=` flag. Strip any tool-suggested attribution. 2. **Backend is ComfyUI in library mode.** We call `comfy.execution.PromptExecutor` directly with our parameterized workflow JSONs. We do NOT subprocess ComfyUI and we do NOT swap to a different inference engine. 3. **Six mode workflows live in `workflows/` as user-exported API-format JSON.** Do not hand-edit. The user re-exports from the ComfyUI editor when the master changes; `python tools/extract_modes.py --master ... --out workflows` regenerates the six mode files. 4. **Models live in the HF cache.** Local: `~/.cache/huggingface/hub` symlinked into `comfyui/models//`. Spaces: build-time `preload_from_hub` + runtime mirror to `~/hf-cache-rw/`. Never commit `*.safetensors`, `*.gguf`, `*.bin`, `*.pt`. 5. **Don't pin `spaces` in `requirements.txt`.** HF Spaces' ZeroGPU build injects its own version; pinning causes pip-resolve failure. 6. **HF Space deploys from `main`. Local default branch is `master`.** Push with `git push space master:main` — bare `git push space master` creates an orphan remote branch that does NOT trigger a deploy. 7. **VRAM is ComfyUI's job.** The only `empty_cache()` calls live in `backend.py`'s try/finally. Don't sprinkle them elsewhere. If you can't satisfy any of these without changing architectural shape, **ask the user before proceeding.** --- ## Project shape Single-process Gradio 5.50 app, flat top-level Python layout, ~3.5 k LOC excluding the ComfyUI submodule. ComfyUI itself is vendored as a git submodule locally and runtime-cloned into `~/comfyui` on HF Spaces. ``` app.py Gradio Blocks entry · _bootstrap · _on_generate · header drawer backend.py ComfyUILibraryBackend · @spaces.GPU · _execute_workflow · duration estimator modes.py MODE_REGISTRY + per-mode parameterize_fn + node-id constants models.py MODEL_REGISTRY · walk_workflow_for_models · ensure_models_for_mode ui.py render_status · _render_idle · mode-form layout primitives workflow.py load_template · set_input helpers workflows/ Six API-format mode JSONs — DO NOT hand-edit assets/ Seed input placeholders for cold-start staging tools/ extract_modes.py — regenerate workflows/ from a master export docs/superpowers/ Spec + plan + brainstorm artifacts (per feature) tests/ L1 + L2 + L3; GPU smoke gated by --gpu comfyui/ Submodule (local) / runtime clone target (Spaces) ``` Same code path everywhere. The only branching is in `_bootstrap()` (cache-mirror dance on Spaces; plain symlink locally) and the `@spaces.GPU` decorator (identity off Spaces). --- ## Locked architecture decisions These came out of 100+ commits of iteration. Do not relitigate. | Decision | Why | Code reference | |---|---|---| | ComfyUI library mode (no subprocess) | Direct executor access; shared Python process for model lifecycle and progress reporting | `backend.ComfyUILibraryBackend.__init__` | | Six API-format workflow JSONs | API format (`{node_id: {class_type, inputs}}`) is what `PromptExecutor` + `walk_workflow_for_models` consume. Editor format silently fails. | `workflows/*.json` | | Workflow parameterization via patches | The user owns workflow shape via ComfyUI editor exports; we only patch leaf inputs. Never hand-edit JSON. | `modes.parameterize_fn` | | Custom nodes pinned to SHAs (not branches) | Reproducible builds; `git clone --branch ` is unsupported — we use a `_git_clone()` init+fetch+checkout helper | `app.CUSTOM_NODES_PINNED`, `app._git_clone` | | HF cache → `comfyui/models//` symlinks | Avoids duplicate weight copies; HF cache stays the single source of truth | `models.symlink_hf_cache_to_comfy_layout` | | `_mirror_preload_hf_cache()` on Spaces | preload_from_hub files are owned by the build user (root-ish); the runtime user (uid 1000) can't write to them. Hardlink blobs + copy refs into a writable mirror under `~/hf-cache-rw/`. | `app._mirror_preload_hf_cache` | | `_comfy_dir()` per-platform | `~/comfyui` on Spaces (writable HOME); `/comfyui` locally. Both `app.py` and `backend.py` must agree. | `app._comfy_dir`, `backend._comfy_dir` | | `@spaces.GPU(duration=callable)` applied module-level | Runtime decoration isn't detected by ZeroGPU's startup analyzer. Static decorator + dynamic-duration callable is the supported pattern. | `backend._execute_workflow` | | Per-call duration estimator | A one-size-fits-all 600 s caps everything in the slow queue lane. Estimator reads frames + mode + preset + cold-cache buffer, clamps `[60, 900] s`. | `backend._duration_for` | | Auto-retry once at 2× on timeout | `"GPU task aborted"` is the queue-eviction signal; one retry catches transient busy queues. | `app._on_generate` | | `allowed_paths=[output_dir]` on launch | Gradio 5 refuses files outside cwd / temp / `allowed_paths`. ComfyUI writes to `~/comfyui/output/...` on Spaces — outside the app cwd. | `app.app.launch(...)` | | Header `z-index: 15` default / `60` elevated | HF injects `#huggingface-space-header` at fixed z-index 20. Default keeps our header below it (HF widget visible); drawer-open bumps above the scrim. | `_CUSTOM_CSS` `.aio-header` | | Click-outside dismisser in `gr.Blocks(head=…)` | Gradio strips `