## Table Of Contents
1. [References](#1-references)
2. [Project Reference](#2-project-reference)
1. [Project Paths](#project-paths)
2. [Command Reference](#command-reference)
3. [Dependency Surfaces](#dependency-surfaces)
4. [Environment Variables](#environment-variables)
5. [Configuration Files](#configuration-files)
6. [Model Registry](#model-registry)
7. [Public Interfaces](#public-interfaces)
8. [Figure Visual Tokens](#figure-visual-tokens)
# 1. References
Use this file when you need an exact path, command, environment variable, or
public name. Use [How-To User Guides](How-To-User-Guides.md) for procedure and
[Explanations](Explanations.md) for concepts.
# 2. Project Reference
## Project Paths
Core paths:
| Path | Role |
|---|---|
| [README.md](../README.md) | Short setup entry point and Hugging Face Space README. |
| [AGENTS.md](../AGENTS.md) | Local coding and documentation guidance for agents. |
| [pyproject.toml](../pyproject.toml) | Package metadata, dependencies, entry points, and tool configuration. |
| [justfile](../justfile) | Development commands. |
| [app.py](../app.py) | Hugging Face Space shim for the Gradio workbench. |
| [src/kneiff](../src/kneiff) | Runtime package source. |
| [src/kneiff_dev](../src/kneiff_dev) | Maintainer-only package helpers. |
| [tests](../tests) | Test suite. |
| [docs](.) | Long-form project documentation. |
| [docs/assets](assets) | Tracked generated documentation figures. |
| `assets/*.IGNORE*` | Ignored local diagram scratch files. |
| `experiments/` | Ignored local research and one-off probes. |
> [!NOTE]
> Related: use [Development: repository routing](Development.md#repository-routing)
> before adding files or moving behavior between directories.
## Command Reference
Top-level commands:
| Command | Role |
|---|---|
| `knf --help` | Show the main Kneiff command tree. |
| `knf config --help` | Show native AppRC configuration commands. |
| `knf project --help` | Show project scaffold, validation, and storage-switching commands. |
| `knf dataset --help` | Show dataset preparation commands. |
| `knf model --help` | Show model conversion and maintenance utilities. |
| `knf train --help` | Show training lifecycle commands. |
| `knf img --help` | Show local image utility, tagging, captioning, and upscaling commands. |
| `knf comfy --help` | Show ComfyUI server workflow commands. |
| `knf llm --help` | Show local LLM commands. |
| `jtp3-wrap --help` | Run the optional direct JTP-3 wrapper entry point with the same selected-tag output modes. |
Root AppRC options must appear before the command group:
| Option | Role |
|---|---|
| `--env-file PATH` | Load one explicit dotenv file before runtime config. Repeat the option to load multiple files. |
| `--env-file-overrides-os-environ`, `-o` | Let explicit dotenv values override existing process environment values for this invocation. |
| `--skip-dotenv-layers`, `-s` | Select storage without merging packaged, app-wide, storage-local, or explicit dotenv values into the process environment. |
| `--storage NAME_OR_PATH` | Select a registered storage name or storage path for this invocation. |
| `--log-level LEVEL` | Configure logging before AppRC runtime bootstrap. |
Runtimeful dataset, training, ComfyUI, and LLM actions require explicit storage
selection through `KNF_STORAGE` or `--storage`. A lone registered storage is not
auto-selected. The selected AppRC root is the project root. Explicit
`configs/*.knf.yaml` paths must remain inside it; select another project with
`--storage` before using that project's config. `knf project init` is
runtime-independent and does not accept root `--env-file`; export
`KNF_APPRC_TOML` directly when the registry path must be overridden.
Config commands:
| Command | Role |
|---|---|
| `knf config paths [--json]` | Show declared and active AppRC paths without writing files. |
| `knf --storage NAME_OR_PATH config show [--json]` | Show resolved AppRC paths, capabilities, and active storage. |
| `knf config doctor [--json]` | Check AppRC readiness and report exact setup actions. |
| `knf config setup --yes --storage-root PATH` | Create the app-wide and storage-local dotenv files non-interactively. |
| `knf --storage NAME_OR_PATH config set KEY VALUE --scope app\|storage` | Validate and write one override to the selected AppRC layer. |
| `knf --storage NAME_OR_PATH config edit` | Open the Textual TUI for AppRC dotenv overrides. |
| `knf config app init` | Create `~/.config/knf/.env.apprc-app`. |
| `knf config storage add NAME PATH --yes` | Register a persistent storage root in `~/.config/knf/knf.apprc.toml` and create its `.env.apprc-storage` file. |
| `knf config storage list` | Show registered storage roots and active-selector markers. |
| `knf config storage list --json` | Emit the storage registry as JSON. |
| `knf config storage remove NAME` | Remove a named storage entry. |
Project commands:
| Command | Role |
|---|---|
| `knf project init PATH [--name NAME] [--activation-token TOKEN --species-token TOKEN] [--git-user-name NAME] [--yes]` | Preflight, create, and validate the complete Sygred scaffold: root `vocabulary.knf.yaml`, `prompts.knf.yaml`, `default_tags.txt`, `.gitignore`, `.gitattributes`, `configs/ANIMA.knf.yaml`, `configs/F2K_9B.knf.yaml`, `SOURCE/0-FULLBODY/`, `SOURCE/2-HEAD/`, empty `HF/`/`TRAINING/`, and `.old_manifests/`; initialize a new root as a `main` Git repository with local `user.name` defaulting to `kneiff`; and register the root with AppRC, which creates `.env.apprc-storage`. Both generated configs are validated through Kneiff's export and SimpleTuner loaders but accept empty source folders. Existing project files and existing Git identity/remotes are not replaced. The command never sets Git email/global settings, creates a commit, or installs/configures Git LFS. |
| `knf project list [--json]` | Parse the resources in every registered AppRC storage and report `ready`, `invalid`, or `missing root`. |
| `knf project show [--json]` | Show the selected project root, identity, validation status, default Anima and Flux2 configs, default tags, Git files/repository state, starter source directories, and conventional resource paths. |
| `knf project validate` | Validate both fixed starter configs, starter source directories, Git/default-tag files, vocabulary, and prompt/workflow resources; then report the activation token, species token, core/project/resolved prompt counts, and workflow-override count. |
| `knf project use NAME` | Persist `KNF_STORAGE=NAME` as the app-wide fallback. A shell `KNF_STORAGE` or root `--storage` overrides it. |
Dataset commands:
| Command | Role |
|---|---|
| `knf dataset plan CONFIG...` | Print the compact CONFIG id, resolved config path, project root, source root, manifest path, export root, and export subsets for one or more configs. |
| `knf dataset describe CONFIG...` | Print dry-run export tables with per-subset counts and SimpleTuner sampling columns without writing files. |
| `knf dataset aspects CONFIG [--processes N]` | Build a caption-free geometry plan, then print each active SimpleTuner backend's deterministic aspect buckets, raw and repeat-expanded counts, physical-pruning status, effective-batch launch compatibility, and prospective safe-border repairs. It validates mapped source paths and image geometry plus configured resize, mirror, and caption-output multiplicity, but never loads a vocabulary or validates caption tags/axes. `--processes` defaults to `1` and must match the Accelerate process count. It never changes images, manifests, HF exports, or training workspaces; it only maintains `.old_manifests/_aspect_cache/.json`, which is invalidated by config, manifest, source, and repair-policy changes. Progress and the human report use stderr. Stdout is only a deduplicated newline-delimited stream of physically pruned `SOURCE/` images, suitable for `knf dataset aspects CONFIG \| knf comfy outpaint -w willy`; launch-blocking buckets are not misreported as excluded images. A later real export can still omit images with invalid caption semantics. Random aspect-crop configurations are rejected because no exact static assignment exists. |
| `knf dataset sync CONFIG...` | Sync `MANIFEST.knf.xlsx` and generated `MANIFEST.yaml` from `SOURCE/`, incrementally reconcile each config-derived dataset in `HF//`, refresh Hugging Face artifacts, and write non-mirrored export image grids when image outputs changed or the grid is missing. After a successful export, it caches an authoritative one-process safe-border repair plan and warns about `PRUNED`/`INCOMPATIBLE` buckets. It never changes `SOURCE` or `HF` pixels. |
| `knf dataset readme CONFIG...` | Rewrite export-root `README.md` files from existing metadata and optional existing SimpleTuner JSON. |
| `knf dataset sync CONFIG... --manifest-only` | Refresh only `MANIFEST.knf.xlsx` and generated `MANIFEST.yaml` using paths derived from each config. |
| `knf dataset sync CONFIG... --dry-run` | Validate and count outputs without writing files, including source/export and SimpleTuner resolution planning. |
| `knf dataset sync CONFIG... --verbose` | Show all changed-image rows and all uncapped resolution buckets instead of capped sync feedback. |
| `knf dataset sync CONFIG... --rebuild` | Delete all public export contents before writing the planned dataset outputs. |
| `knf dataset sync CONFIG... --rebuild --yes` | Confirm the destructive rebuild prompt without asking. |
| `knf dataset sync CONFIG... --exclude PATTERN` | Add a manifest exclusion glob relative to `SOURCE/`. |
| `knf dataset grid CONFIG...` | Write non-mirrored `kneiff-training-image-grid.jpg` files from existing export roots without exporting. |
| `knf dataset grid CONFIG --output PATH` | Write one training image grid to an explicit path. `--output` is rejected with multiple configs. |
For dataset commands and batch-capable training commands, `CONFIG...` can be
omitted in an interactive terminal. Kneiff opens an arrow-key picker when
multiple direct child `configs/*.knf.yaml` files exist in the active storage
root, and ambiguous typed selectors open a picker limited to matching configs.
Use Space to toggle configs, `a` to toggle all, Enter to confirm, and `q`/Esc to
cancel. Non-interactive scripts should pass explicit config paths or selectors.
Model commands:
| Command | Role |
|---|---|
| `knf model convert --family sdxl SOURCE [OUTPUT]` | Convert a local SDXL `.safetensors` or `.ckpt` checkpoint into a Diffusers directory while preserving full single-file pipeline components such as text encoders. Default `OUTPUT` is a sibling `Diffusers` directory. Existing valid Diffusers directories are reused; invalid existing output paths fail. |
ComfyUI commands:
| Command | Role |
|---|---|
| `knf comfy showcase [--lora LORA\|--training/-t [STEPS]...] [--prompts YAML] [-w WORKFLOW] [--prompt-field FIELD]` | Queue a showcase collection through a running ComfyUI API server. Omit `--prompts` to use the selected project's resolved core-plus-overlay catalog; an explicit version-1 YAML path is a standalone collection. `--lora` is a path below `$COMFY_MODELS_DIR/models/loras`; omit it in an interactive terminal to pick one. `--training` / `-t` instead opens a flat multi-picker over `.safetensors` files in direct `TRAINING/_/_simpletuner-output/` trees; optional positive `STEPS` match exact `checkpoint-` directories, and every requested step must exist. ComfyUI-native files sort first without hiding raw files. Checked files are hard-linked, or copied across filesystems, into unique `.kneiff-training` directories below `models/loras` and removed after the run. All selected LoRAs use one workflow; omitted `WORKFLOW` is inferred from the first selected path, with the full workflow picker as the TRAINING fallback. `-t` requires an interactive terminal and conflicts with `--lora`. Set `COMFY_LORAS_DIR_1` to choose the regular picker start directory. Scripts should pass `--workflow PRESET`, `--workflow auto`, or an API-format workflow JSON path. Project overrides use `workflows/showcase_.workflow.json` and take precedence over packaged presets with the same name. The command prints prompt sources, inspected workflow configuration, output paths, and aggregate progress. Individual images stay in the dated ComfyUI `SaveImage` directory. Every successful run uploads a timestamped JPEG grid into that same `output` subfolder, with prompts as columns, LoRAs as rows, and prompt labels repeated above and below with a ten-line maximum. No showcase grid is written below `TRAINING`. |
| `knf comfy upscale INPUT... [--model MODEL] [--style photoreal\|shaded\|flat] [--lora LORA --token TOKEN] [--lora-strength FLOAT] [--denoise-base FLOAT\|-d FLOAT] [--seed SEED] [-z\|--z-image] [--fast]` | Upload one image or directory of images to a running ComfyUI API server. By default, run a two-stage Krea2 quality pipeline that creates two seed branches per stage and saves four final candidates through builtin `SaveImage` under dated prefixes such as `26-06-23/260623-11_15_14-upscale-image-c1`. Built-in Krea2 defaults use `4x-UltraSharpV2.pth`, `krea2_turbo_fp8_scaled.safetensors`, `qwen3vl_4b_fp8_scaled.safetensors`, `krea2`, and `qwen_image_vae.safetensors`; matching `COMFY_*` env vars override them. `COMFY_UPSCALE_LORA` resolves through `COMFY_MODELS_DIR` and `COMFY_LORAS_DIR_1`; `COMFY_UPSCALE_LORA_TOKEN` is optional and only prepends prompt text. `--denoise-base` / `-d` replaces the formula base while keeping automatic stage adjustments. Interactive terminals open a picker when a non-explicit default/configured value is unavailable. Pass `-z` / `--z-image` for the legacy Z-Image quality workflow, or `--fast` for the single-pass `LoadImage` -> `UpscaleModelLoader` -> `ImageUpscaleWithModel` -> `SaveImage` workflow without refiner settings. |
| `knf comfy outpaint [IMAGES...] [--safe-border] [-a\|--from-pruned-aspects] [--aspects-config CONFIG] [-w willy\|stablemondai-sdg] [--seed SEED] [--url URL] [--square-fraction FLOAT]` | Extend explicit image files, or omitted-input newline-delimited `SOURCE/` stdin from `knf dataset aspects`; an empty stream succeeds. `-a` / `--from-pruned-aspects` calculates physically pruned sources in-process with `--aspects-config CONFIG` and cannot combine with image arguments or stdin. `--square-fraction` is in `(0, 1]`; its `0.25` default is gentle and `1.0` fully squares non-square inputs. Default mode uploads files to a running ComfyUI server, uses a packaged core-node masked workflow, and requires `-w` outside a terminal; its source region is restored after sampling and `Ctrl-C` cancels only prompts owned by this invocation. `--safe-border` instead runs entirely locally: it preserves EXIF-corrected source pixels, edge-extends and progressively blurs only new outer pixels, and writes collision-safe lossless PNGs below the required `COMFY_OUTPUT_DIR`. Safe mode requires neither ComfyUI nor `-w`, accepts the same three input modes, prints bare output paths to stdout, and rejects `--workflow`, `--url`, and `--seed`. |
| `knf comfy t2i solo TEXT [--pipeline krea2\|krea2-flux2\|anima-flux2] [OPTIONS]` | Generate reviewed one-character LM Studio variations from the positional scene request. An interactive terminal opens a required three-choice pipeline picker when `--pipeline` is omitted; scripts must pass it. `krea2` queues fixed `1024x1024` Krea2 finals directly. `krea2-flux2` queues Krea2 baselines then Flux2 Klein 9B cleanup candidates; `anima-flux2` does the same with one-LoRA Anima baselines. Defaults are three prompts and three images per prompt; Flux profiles also default to three cleanup candidates per baseline. CLI options can override stage models, LoRAs, strengths, counts, optional local mirror, ComfyUI URL, root seed, and participant 1 activation token for one run. |
| `knf comfy t2i duo TEXT [OPTIONS]` | Generate reviewed duo variations from the positional scene request, immediately queue all fixed `1024x1024` Anima baseline branches, wait for every baseline, then upload them into a run-specific ComfyUI input subfolder and queue all Flux2 Klein 9B distilled cleanup branches. Defaults produce nine baselines and 27 finals. CLI options can override both activation tokens, T2I and I2I models, both stage LoRAs and strengths, counts, optional local mirror, URL, and root seed for one run. |
ComfyUI progress renders on stderr only in interactive terminals. Showcase uses
one unit per eligible prompt and selected LoRA. Fast upscale and outpaint use
one unit per image; quality upscale uses six units per image for its two
intermediate and four final prompts. Redirected stdout retains its existing
plain result lines.
T2I runs use three prompt, baseline, and cleanup progress tasks. Redirected
output prints deterministic stage messages. Output paths are:
```text
//-t2i-/
├── baselines/ # Flux cleanup profiles and duo only
├── final/
└── run.knf.yaml
```
Manifest schema version 1 records the run status, composition pipeline and
selected model-stage profile, timestamps, counts,
`1024x1024` resolution, root seed, original request, raw and effective prompts,
activation-token slots, ComfyUI-visible models and LoRAs, strengths, every
job's coordinates and derived seed, prompt id, status, relative output path,
actual ComfyUI output reference, and compact error. It contains no API key,
environment dump, or absolute machine path and is not accepted as resume input.
LLM commands:
| Command | Role |
|---|---|
| `knf llm prompt "SCENE" [--model MODEL] [--draft-model MODEL] [--review-model MODEL] [--base-url URL] [--field FIELD=VALUE] [--format json\|text\|review] [--verbose] [--text] [--no-export] [--no-review] [--save-exchanges]` | Generate a two-pass image prompt through a running LM Studio OpenAI-compatible server. Human review output is the default and prints the first version, second version, and comments. `--verbose` and `--format json` print the full structured JSON payload with dataset-shaped fields, final prompts, assumptions, missing input, review issues, and model ids. `--format text` and `--text` print only copy-friendly final prompt text. User-facing JSON and review text are saved below `.llm_promptgen/results/` in the selected storage by default; `--no-export` suppresses them. Repeat `--field` to force manifest-compatible values from the selected project vocabulary, such as `character=Character_Token`, `view=rear_view`, or `pose_body=standing,leaning`. `--save-exchanges` writes raw debug transcripts below `.llm_promptgen/` unless `KNF_PROMPTGEN_EXCHANGE_DIR` overrides the location. |
The former `--export` opt-in is removed. Result export is storage-backed and on
by default; use `--no-export` for terminal-only output.
Packaged Comfy workflow policy:
- Store Comfy graphs as API-format JSON templates below `src/kneiff/infer/comfy/resources/workflows/**`.
- Python may patch placeholders, remove optional nodes, and rewire dynamic edges, but full Comfy graphs should live in packaged templates unless a documented exception is needed.
- Packaged `KSampler` nodes must set `control_after_generate` to `fixed` so seed reproduction survives optimization passes.
- `--debug-write-workflows DIR` writes fully patched executable workflows for inspection.
Packaged workflow and project resource starter files:
| Path | Role |
|---|---|
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_anima.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_anima.workflow.json) | `anima` preset API workflow template with Kneiff placeholders for LoRA name, prompt, negative prompt, filename prefix, and seed. It passes the 50-step baseline latent through a seed-43, 30-step, CFG 4, `dpmpp_2m_sde_gpu`, beta, 0.4-denoise refiner before decoding. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_anima-novafurryam.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_anima-novafurryam.workflow.json) | `anima-novafurryam` preset API workflow template using the selected LoRA and Nova Furry AM v3.0 ANIMA model with the same baseline settings as `anima`. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_pony.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_pony.workflow.json) | `pony` preset API workflow template using the selected LoRA and Pony prompt-field default. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-willy.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-willy.workflow.json) | `noob-willy` preset API workflow template using the selected LoRA, RescaleCFG 0.5, the resolved NOOB negative prompt, and 50-step, CFG 5.5, Euler ancestral, beta sampling. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-chenkin.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-chenkin.workflow.json) | `noob-chenkin` preset API workflow template using the selected LoRA, NOOB prompt-field default, and 60-step beta `res_multistep` sampling. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-base.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-base.workflow.json) | `noob-base` preset API workflow template using the selected LoRA, NOOB prompt-field default, and 50-step beta Euler sampling. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-nova.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-nova.workflow.json) | `noob-nova` preset API workflow template using the selected LoRA, NOOB prompt-field default, and 60-step beta `res_multistep` sampling. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-scrimblosauce.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-scrimblosauce.workflow.json) | `noob-scrimblosauce` preset API workflow template using the selected LoRA, NOOB prompt-field default, and 70-step Karras `uni_pc` sampling. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-stablemondai-sdg.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_noob-stablemondai-sdg.workflow.json) | `noob-stablemondai-sdg` preset API workflow template using the selected LoRA, RescaleCFG 0.5, the resolved NOOB negative prompt, and Euler ancestral, SGM Uniform, 32-step, CFG 5.0 sampling. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_flux2-klein-4b.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_flux2-klein-4b.workflow.json) | `flux2-klein-4b` preset API workflow template using the selected LoRA and non-base Flux2 Klein 4B model with distilled 4-step, CFG 1, empty negative-prompt settings. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_flux2-klein-9b.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_flux2-klein-9b.workflow.json) | `flux2-klein-9b` preset API workflow template using the selected LoRA and non-base Flux2 Klein 9B model with distilled 4-step, CFG 1, empty negative-prompt settings. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_flux2-klein-base-4b.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_flux2-klein-base-4b.workflow.json) | `flux2-klein-base-4b` preset API workflow template using the selected LoRA and Flux2 Klein Base 4B model with 40-step, CFG 5.0, `res_multistep`, empty negative-prompt settings. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_flux2-klein-base-9b.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_flux2-klein-base-9b.workflow.json) | `flux2-klein-base-9b` preset API workflow template using the selected LoRA and Flux2 Klein Base 9B fp8 model with 40-step, CFG 5.0, `res_multistep`, empty negative-prompt settings. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_z-image-turbo.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_z-image-turbo.workflow.json) | `z-image-turbo` preset API workflow template using the selected LoRA and Z-Image Turbo bf16 model with 8-step, CFG 1, `res_multistep`, `simple` sampling. |
| [src/kneiff/infer/comfy/resources/workflows/showcase/showcase_krea2-turbo.workflow.json](../src/kneiff/infer/comfy/resources/workflows/showcase/showcase_krea2-turbo.workflow.json) | `krea2-turbo` preset API workflow template using the selected LoRA and the local Krea2 Turbo FP8 model with 8-step, CFG 1, Euler, `simple` sampling. |
| [src/kneiff/infer/comfy/resources/workflows/t2i/solo_generation.workflow.json](../src/kneiff/infer/comfy/resources/workflows/t2i/solo_generation.workflow.json) | Fixed `1024x1024` Krea2 Turbo solo graph with model, LoRA, strength, positive prompt, seed, and filename placeholders. |
| [src/kneiff/infer/comfy/resources/workflows/t2i/solo_anima_generation.workflow.json](../src/kneiff/infer/comfy/resources/workflows/t2i/solo_anima_generation.workflow.json) | Fixed `1024x1024` Anima solo graph with one model-only LoRA, positive and negative prompts, and duo-aligned sampling settings. |
| [src/kneiff/infer/comfy/resources/workflows/t2i/solo_cleanup.workflow.json](../src/kneiff/infer/comfy/resources/workflows/t2i/solo_cleanup.workflow.json) | Fixed `1024x1024`, 4-step Flux2 Klein 9B distilled one-character image-edit graph with one model-only LoRA and the workflow-owned `full_encoder_small_decoder.safetensors` VAE. |
| [src/kneiff/infer/comfy/resources/workflows/t2i/duo_generation.workflow.json](../src/kneiff/infer/comfy/resources/workflows/t2i/duo_generation.workflow.json) | Fixed `1024x1024` Anima graph with two chained `LoraLoaderModelOnly` nodes and positive, negative, seed, and filename placeholders. |
| [src/kneiff/infer/comfy/resources/workflows/t2i/duo_cleanup.workflow.json](../src/kneiff/infer/comfy/resources/workflows/t2i/duo_cleanup.workflow.json) | Fixed `1024x1024`, 4-step Flux2 Klein 9B distilled image-edit graph using core `LoadImage`, `VAEEncode`, and `ReferenceLatent` conditioning, two chained model-only LoRAs, CFG 1, Euler, and `Flux2Scheduler`. The workflow-owned VAE is `full_encoder_small_decoder.safetensors`. |
| `vocabulary.knf.yaml` | Selected project's strict `kneifftags.vocabulary-extension` schema-version-2 document. It declares a unique `namespace`, ordered character and species `identities`, and optional project `categories`, `groups`, `tags`, and explicit built-in `overrides`. Identity and tag definitions can own output tags, aliases, natural/NLG phrases, Chroma tags, ordering, and Kneifftags safety metadata. Kneifftools composes the validated extension with the built-in Kneifftags vocabulary in an isolated engine. A schema-version-1 file is accepted only by the transactional dataset migration. |
| [src/kneiff/prompts/resources/core_prompts.knf.yaml](../src/kneiff/prompts/resources/core_prompts.knf.yaml) | Packaged version-1 prompt baseline: portable character reference, `worst quality` NOOB negative default, and immutable fixed negative controls. `${character}` and `${species}` expand only in this package resource. |
| `prompts.knf.yaml` | Optional strict version-1 project overlay on the packaged prompt catalog. Project scalar defaults replace core defaults; `negative_prompts` override by field, including NOOB showcase runs. `showcase_model_prompts` merges each model family's `positive_prefix` and `negative_prefix` independently and applies them only during ComfyUI showcase generation; the negative prefix prepends to the resolved row or catalog negative base. `ignore_positive_prefix: true` on a row skips model and field positive prefixes. `showcase_positive_prefixes` remains a field-keyed fallback. A same-ID row fully replaces a core row. Every row requires nonempty `uses`; project rows cannot use or replace `negative_control`. |
| `workflows/showcase_.workflow.json` | Optional selected-project ComfyUI showcase workflow. It must be a regular API-format JSON file with prompt, seed, and filename-prefix placeholders; filename-derived IDs are lowercased with `_` separators normalized to `-`, are never remapped through packaged aliases, and must be unique after normalization. Known IDs select their built-in model family; every other ID selects the same `showcase_model_prompts` key. |
| [src/kneiff/prompts/resources/lmstudio/base_prompt.yaml](../src/kneiff/prompts/resources/lmstudio/base_prompt.yaml) | Packaged first-pass LM Studio prompt-generation template. |
| [src/kneiff/prompts/resources/lmstudio/review_prompt.yaml](../src/kneiff/prompts/resources/lmstudio/review_prompt.yaml) | Packaged second-pass LM Studio consistency review template. |
Packaged upscale starter files:
| Path | Role |
|---|---|
| [src/kneiff/infer/comfy/resources/workflows/upscale/upscale_fast.workflow.json](../src/kneiff/infer/comfy/resources/workflows/upscale/upscale_fast.workflow.json) | API workflow template for `knf comfy upscale --fast`; Kneiff patches image, upscale model, and output prefix placeholders. |
| [src/kneiff/infer/comfy/resources/workflows/upscale/upscale_krea2_quality_stage.workflow.json](../src/kneiff/infer/comfy/resources/workflows/upscale/upscale_krea2_quality_stage.workflow.json) | Default Krea2 API workflow template for each quality upscale stage; Kneiff patches dimensions, refiner models, prompt, seed, denoise, model-only LoRA values, and output mode. Krea2 quality upscale does not use TiledDiffusion. |
| [src/kneiff/infer/comfy/resources/workflows/upscale/upscale_quality_stage.workflow.json](../src/kneiff/infer/comfy/resources/workflows/upscale/upscale_quality_stage.workflow.json) | Legacy Z-Image API workflow template used by `knf comfy upscale -z`; Kneiff patches dimensions, refiner models, prompt, seed, denoise, LoRA values, output mode, and optional TiledDiffusion. |
ComfyUI-visible model names required by the packaged showcase presets:
| Preset | Required model files |
|---|---|
| `anima` | `diffusion_models/Anima/anima-base-v1.0.safetensors`, `text_encoders/qwen_3_06b_base.safetensors`, `vae/qwen_image_vae.safetensors`, plus the selected `--lora` below `models/loras`. |
| `anima-novafurryam` | `diffusion_models/Anima/novaFurryAM_v30.safetensors`, `text_encoders/qwen_3_06b_base.safetensors`, `vae/qwen_image_vae.safetensors`, plus the selected `--lora` below `models/loras`. |
| `pony` | `checkpoints/_base_finetunes/ponyDiffusionV6XL_v6StartWithThisOne.safetensors`, plus the selected `--lora` below `models/loras`. |
| `noob-willy` | `checkpoints/_base_finetunes/willysRealism_coreV1.safetensors`, plus the selected `--lora` below `models/loras`. |
| `noob-base` | `checkpoints/_base_finetunes/noobaiXLNAIXL_epsilonPred11Version.safetensors`, plus the selected `--lora` below `models/loras`. |
| `noob-chenkin` | `checkpoints/_base_finetunes/chenkinNoobXLCKXL_v05.safetensors`, plus the selected `--lora` below `models/loras`. |
| `noob-nova` | `checkpoints/novaFurryXL_ilV180A.safetensors`, plus the selected `--lora` below `models/loras`. |
| `noob-scrimblosauce` | `checkpoints/SDXL-realistic/scrimbloSauceXL_v80NAI.safetensors`, plus the selected `--lora` below `models/loras`. |
| `noob-stablemondai-sdg` | `checkpoints/stablemondaiSDG_v10.safetensors`, plus the selected `--lora` below `models/loras`. |
| `flux2-klein-4b` | `diffusion_models/F2K_4B/flux-2-klein-4b.safetensors`, `text_encoders/qwen_3_4b.safetensors`, `vae/flux2-vae.safetensors`, plus the selected `--lora` below `models/loras`. |
| `flux2-klein-9b` | `diffusion_models/F2K_9B/flux-2-klein-9b.safetensors`, `text_encoders/qwen_3_8b_fp8mixed.safetensors`, `vae/flux2-vae.safetensors`, plus the selected `--lora` below `models/loras`. |
| `flux2-klein-base-4b` | `diffusion_models/F2K_4B/flux-2-klein-base-4b.safetensors`, `text_encoders/qwen_3_4b.safetensors`, `vae/flux2-vae.safetensors`, plus the selected `--lora` below `models/loras`. |
| `flux2-klein-base-9b` | `diffusion_models/F2K_9B/flux-2-klein-base-9b-fp8.safetensors`, `text_encoders/qwen_3_8b_fp8mixed.safetensors`, `vae/flux2-vae.safetensors`, plus the selected `--lora` below `models/loras`. |
| `z-image-turbo` | `diffusion_models/ZI_Turbo/z_image_turbo_bf16.safetensors`, `text_encoders/qwen_3_4b.safetensors`, `vae/ae.safetensors`, plus the selected `--lora` below `models/loras`. |
| `krea2-turbo` | `diffusion_models/Krea2/krea2_turbo_fp8.safetensors`, `text_encoders/qwen3vl_4b_fp8_scaled.safetensors`, `vae/qwen_image_vae.safetensors`, plus the selected `--lora` below `models/loras`. |
Training commands:
| Command | Role |
|---|---|
| `knf train start CONFIG...` | Require a populated `HF//` from `knf dataset sync`, prepare the next free run for each config, show the artifact review menu with SimpleTuner resolution behavior and current safe-border aspect-repair readiness in interactive terminals, launch SimpleTuner sequentially, and write final validation grids after success. |
| `knf train start CONFIG... --yes` | Launch without the interactive review gate. |
| `knf train start CONFIG... --no-review` | Launch without showing generated JSON review. |
| `knf train start CONFIG... --resume N` | Validate the prepared run's copied dataset and launch existing `not_started` or `incomplete` run `N` for each config without regenerating artifacts from YAML. |
| `knf train start CONFIG --resume` | Open an interactive picker for resumable runs. In a batch, bare `--resume` prompts once per config. |
| `knf train extend CONFIG_OR_SELECTOR RUN --steps N` / `-s N` | Continue an existing `complete`, `failed`, or `incomplete` run in place by increasing generated `max_train_steps` by `N`, setting `resume_from_checkpoint` to `latest`, patching source YAML `training.simpletuner.trainer.max_train_steps` after confirmation, and launching from the latest numeric checkpoint. |
| `knf train start CONFIG... --testrun` | Apply `training.simpletuner.trainer_testrun` while preparing fresh runs. |
| `knf train start CONFIG... --cuda-device 1` | Select the visible CUDA device for SimpleTuner. |
| `knf train start CONFIG... --fallback-cuda-device 0` | Record a fallback CUDA device for launch wrappers. |
| `knf train prepare CONFIG...` | Require a populated `HF//` from `knf dataset sync`, validate or rebuild its authoritative aspect-repair cache, and prepare new `not_started` runs without launching SimpleTuner. Safe planned repairs replace only files in the new `dataset/` copy; byte-identical review copies appear in `_knf_aspect_repair/` beside it. It reports whether all known PRUNED/INCOMPATIBLE assignments are covered and lists any variants that exceed the 180-pixel automatic-padding limit. Resumed runs remain unchanged. |
| `knf train promote --name NAME` / `-n NAME` | Interactively choose a numeric checkpoint from `TRAINING`, a destination below `COMFY_MODELS_DIR/models/loras`, and a mandatory release version. Preview, confirm, then atomically copy the source without overwrite as `--v.-.safetensors`; `name` defaults to `custom_tokens.character.text`. |
| `knf train runs CONFIG_OR_SELECTOR` | List discovered run numbers, statuses, timestamps, and output directories. |
| `knf train review CONFIG_OR_SELECTOR N` | Review generated JSON artifacts for an existing run without launching. |
| `knf train grid CONFIG_OR_SELECTOR N` | Write `TRAINING/_-kneiff-validation-progress-grid.jpg` from existing SimpleTuner validation images. |
| `knf train grid CONFIG_OR_SELECTOR N --output PATH` | Write the validation progress grid to an explicit path. |
`run_simpletuner_training()` has one launch implementation: it resolves the
absolute Python interpreter declared by the installed `simpletuner` entry point
and runs `python -m kneiff_simpletuner_runner` from the numbered workspace.
`build_simpletuner_launch_environment()` returns the child environment. Neither
API accepts an executable override or an in-process launch switch.
For SDXL configs, `training.simpletuner.model.pretrained_model_name_or_path`
must point at a Diffusers directory. `knf train prepare CONFIG` fails with the
matching `knf model convert --family sdxl ...` command when it finds a local
top-level `.safetensors` or `.ckpt` checkpoint. `knf train start CONFIG` can run
that conversion after confirmation, or automatically with `--yes`, then updates
the source YAML so future starts use the converted directory. Conversion loads
the full single-file SDXL pipeline and then saves the configured VAE override.
After successful SDXL/Pony LoRA training, `knf train start CONFIG` also writes a
ComfyUI-compatible sibling LoRA named
`pytorch_lora_weights.comfyui.safetensors` beside each SimpleTuner
`pytorch_lora_weights.safetensors` checkpoint.
Image commands:
| Command | Role |
|---|---|
| `knf img png2jpg INPUT_DIR` | Convert PNG files below a directory to JPEG. |
| `knf img concat IMAGE... --output out.png` | Concatenate images horizontally. |
| `knf img rename PATH... --base-name NAME` | Rename image files with a prefix or enumerated random suffix. |
| `knf img upscale INPUT... --out-dir PATH` | Upscale one image or a directory of images. |
| `knf img tag PATH... --recursive` | Print RedRocket/JTP-3 tags as e621-style whitespace-separated text. |
| `knf img tag PATH... --recursive --txt` | Write RedRocket/JTP-3 `.txt` tag sidecars. |
| `knf img tag PATH... --recursive --txt --comma` | Write legacy comma-separated RedRocket/JTP-3 tag sidecars. |
| `knf img tag PATH... --csv-stdout` | Print RedRocket/JTP-3 probability CSV output. |
| `knf img caption TARGET --server --model-name MODEL` | Caption an image or directory through an OpenAI-compatible server. |
| `knf img caption TARGET --blip --model-name MODEL` | Caption an image or directory through the BLIP/Qwen path. |
`png2jpg`, local `upscale`, and directory `caption` use the shared interactive
progress renderer. Directory caption totals exclude existing sidecars unless
`--overwrite` is active. Progress is written to stderr; redirected stdout keeps
legacy result and dry-run lines without ANSI codes. `concat`, `rename`, `tag`,
and single-image captioning do not create a Kneiff progress display.
`knf img tag` selected-tag output:
| Mode | Command | Output |
|---|---|---|
| Default stdout | `knf img tag IMAGE` | One e621-style whitespace-separated tag line. |
| Multi-image stdout | `knf img tag IMAGE...` or `knf img tag DIR --recursive` | One `PATHTAGS` line per image. |
| Sidecar files | `knf img tag PATH... --txt` | `.txt` sidecars next to images, e621-style by default. |
| Legacy selected tags | `knf img tag PATH... --comma` or `knf img tag PATH... --txt --comma` | Comma-separated selected-tag text. |
| Probability CSV | `knf img tag PATH... --csv-stdout` | Upstream probability CSV; incompatible with `--txt` and `--comma`. |
`knf img tag` options:
> [!IMPORTANT]
> The current RedRocket/JTP-3 `main` snapshot requires `pyvips` plus native
> `libvips`. Install Python dependencies with `uv sync` or
> `.venv/bin/python -m pip install -e .`. On Fedora WSL, install native
> `libvips` with `sudo dnf install vips`. Current `main` uses calibrated
> upstream tag selection; `--threshold` is only for legacy pinned revisions.
| Option | Meaning |
|---|---|
| `PATHS...` | Image files or directories. Directory inputs require `--recursive` to include nested images. |
| `--recursive`, `-r` | Scan directory inputs recursively. |
| `--threshold`, `-t FLOAT` | Symmetric JTP-3 tag threshold for legacy pinned revisions. Default: `0.2`. Current `main` rejects non-default thresholds. |
| `--device`, `-d TEXT` | Torch device, such as `cuda`, `cuda:1`, or `cpu`. |
| `--batch-size`, `-b INTEGER` | Images per inference batch. Default: `1`. |
| `--workers`, `-w INTEGER` | Upstream image-loader workers. Omit to use JTP-3's automatic worker count. |
| `--seqlen`, `-S INTEGER` | NaFlex sequence length. Default: `1024`. Accepted upstream range: `64` to `2048`. |
| `--prefix`, `-p TEXT` | Tag text forced to the beginning of selected-tag output. |
| `--txt` | Write selected tags to `.txt` sidecars instead of stdout. |
| `--comma`, `-c` | Use legacy comma-separated selected-tag text. |
| `--csv-stdout` | Print probability CSV output instead of selected-tag text. |
| `--repo-id TEXT` | Hugging Face model repository. Default: `RedRocket/JTP-3`. |
| `--revision TEXT` | Hugging Face branch, tag, revision, or commit. |
Maintainer commands:
| Command | Role |
|---|---|
| `just --list` | Show available development recipes. |
| `just sync` | Sync the full maintainer environment from `uv.lock`. |
| `just lock` | Resolve dependencies and refresh `pylock.toml`. |
| `just upgrade` | Relock with upgrades, then sync. |
| `just clean` | Remove caches and build artifacts. |
| `.venv/bin/ruff format .` | Format Python files. |
| `.venv/bin/ruff check .` | Lint Python files. |
| `.venv/bin/pyright` | Type-check Python files. |
| `.venv/bin/pytest` | Run the test suite. |
> [!NOTE]
> Related: use [How-To User Guides: run tests](How-To-User-Guides.md#run-tests)
> for the command sequence.
## Dependency Surfaces
Dependency locations:
| Surface | File Section | Use |
|---|---|---|
| Runtime dependencies | `[project].dependencies` | Packages required by normal users. |
| Dependency groups | `[dependency-groups]` | Local maintainer tools such as tests, linting, typing, docs, and profiling. |
| Lock file | `uv.lock` | Reproducible `uv` installs. |
| Exported lock | `pylock.toml` | Python lock export generated by `just lock`. |
> [!NOTE]
> Related: use [dependency model](Explanations.md#dependency-model) for why
> runtime dependencies and maintainer-only tools stay separate.
## Environment Variables
Common environment variables:
| Name | Role |
|---|---|
| `KNF_APPRC_TOML` | Optional AppRC registry path override. Defaults to `~/.config/knf/knf.apprc.toml`. |
| `KNF_STORAGE` | Required active storage selector for runtimeful commands. The value may be a registered name or a path; AppRC does not auto-select a lone registry entry. |
| `COMFY_URL` | ComfyUI API server URL. Defaults to `http://127.0.0.1:8188`. |
| `COMFY_MODELS_DIR` | ComfyUI models root containing `models/loras` for T2I resolution and showcase LoRA discovery. `models/loras` must be writable for temporary `--training` / `-t` staging and must belong to the running ComfyUI server. Example: `/path/to/comfyui-models`. |
| `COMFY_LORAS_DIR_1` | Primary LoRA subdirectory used by solo T2I, duo participant 1, showcase picker startup, and `COMFY_UPSCALE_LORA`. Relative values resolve below `$COMFY_MODELS_DIR/models/loras`; absolute values must also be below that root. |
| `COMFY_LORAS_DIR_2` | Partner LoRA subdirectory used by duo participant 2. It follows the same relative or root-contained absolute path rules as `COMFY_LORAS_DIR_1`. |
| `COMFY_OUTPUT_DIR` | Required local output root for `knf comfy outpaint --safe-border`; it receives dated lossless PNG repairs. It is also the optional local mirror root for downloaded T2I files and manifests. Blank values leave ordinary ComfyUI results server-managed, but make `--safe-border` unavailable. `--output-dir` overrides this key for one T2I run. |
| `COMFY_T2I_MODEL_SOLO` | Required ComfyUI-visible Krea2 generation UNET for solo. A leading `diffusion_models/` is optional; Kneiff submits the form reported by ComfyUI. |
| `COMFY_T2I_LORA_SOLO` | Required solo generation LoRA below `COMFY_LORAS_DIR_1`. A missing `.safetensors` suffix is accepted when the suffixed file exists. |
| `COMFY_T2I_LORA_STRENGTH_SOLO` | Solo generation model-only LoRA strength. Defaults to `1.0`. |
| `COMFY_I2I_MODEL_SOLO` | Required ComfyUI-visible Flux2 Klein 9B cleanup UNET for `solo --pipeline krea2-flux2` and `solo --pipeline anima-flux2`. |
| `COMFY_I2I_LORA` | Required single-character solo cleanup LoRA below `COMFY_LORAS_DIR_1`. |
| `COMFY_I2I_LORA_STRENGTH` | Solo cleanup LoRA strength. Defaults to `1.0`. |
| `COMFY_T2I_MODEL_DUO` | Required ComfyUI-visible Anima generation UNET for duo and `solo --pipeline anima-flux2`. |
| `COMFY_T2I_LORA_DUO_1` | Required duo participant 1 and Anima solo generation LoRA below `COMFY_LORAS_DIR_1`. |
| `COMFY_T2I_LORA_DUO_2` | Required duo participant 2 generation LoRA below `COMFY_LORAS_DIR_2`. |
| `COMFY_T2I_LORA_STRENGTH_DUO_1` | Duo participant 1 and Anima solo generation LoRA strength. Defaults to `1.0`. |
| `COMFY_T2I_LORA_STRENGTH_DUO_2` | Duo participant 2 generation LoRA strength. Defaults to `1.0`. |
| `COMFY_I2I_MODEL_DUO` | Required ComfyUI-visible Flux2 Klein 9B distilled cleanup UNET for duo. |
| `COMFY_I2I_LORA_1` | Required duo participant 1 cleanup LoRA below `COMFY_LORAS_DIR_1`. |
| `COMFY_I2I_LORA_2` | Required duo participant 2 cleanup LoRA below `COMFY_LORAS_DIR_2`. |
| `COMFY_I2I_LORA_STRENGTH_1` | Duo participant 1 cleanup LoRA strength. Defaults to `1.0`. |
| `COMFY_I2I_LORA_STRENGTH_2` | Duo participant 2 cleanup LoRA strength. Defaults to `1.0`. |
| `COMFY_UPSCALE_MODEL` | ComfyUI-visible upscale model filename used by `knf comfy upscale` when `--model` is omitted. Defaults to `4x-UltraSharpV2.pth`. |
| `COMFY_UPSCALE_REFINER_UNET` | ComfyUI-visible UNET filename for quality `knf comfy upscale`. Defaults to `krea2_turbo_fp8_scaled.safetensors`; `-z` uses `ZI_Turbo/z_image_turbo_fp8_e4m3fn.safetensors` when this value is not explicitly configured. |
| `COMFY_UPSCALE_REFINER_CLIP` | ComfyUI-visible CLIP filename for quality `knf comfy upscale`. Defaults to `qwen3vl_4b_fp8_scaled.safetensors`; `-z` uses `qwen_3_4b.safetensors` when this value is not explicitly configured. |
| `COMFY_UPSCALE_REFINER_CLIP_TYPE` | CLIPLoader type for quality `knf comfy upscale`. Defaults to `krea2`; `-z` uses `lumina2` when this value is not explicitly configured. |
| `COMFY_UPSCALE_REFINER_VAE` | ComfyUI-visible VAE filename for quality `knf comfy upscale`. Defaults to `qwen_image_vae.safetensors`; `-z` uses `ae.safetensors` when this value is not explicitly configured. |
| `COMFY_UPSCALE_LORA` | Optional quality-upscale LoRA path. Relative values resolve below `COMFY_LORAS_DIR_1` when set, otherwise below `$COMFY_MODELS_DIR/models/loras`; the workflow receives the normalized path relative to `models/loras`. |
| `COMFY_UPSCALE_LORA_TOKEN` | Optional activation token prepended to quality-upscale prompt text when `COMFY_UPSCALE_LORA` or `--lora` is used. |
| `COMFY_UPSCALE_LORA_STRENGTH` | Quality-upscale LoRA model and CLIP strength. Defaults to `0.8`; `--lora-strength` overrides it for one run. |
| `COMFY_UPSCALE_DENOISE_BASE` | Quality-upscale denoise formula base. Defaults to `0.15`; `--denoise-base` / `-d` overrides it for one run while preserving automatic stage adjustments. |
| `COMFY_PROMPT_TIMEOUT_SECONDS` | Maximum seconds to wait for each queued ComfyUI prompt. |
| `COMFY_POLL_INTERVAL_SECONDS` | Seconds between ComfyUI history polling attempts. |
| `KNF_LMSTUDIO_BASE_URL` | LM Studio OpenAI-compatible API base URL. Defaults to `http://127.0.0.1:1234/v1`. |
| `KNF_LMSTUDIO_MODEL` | Default LM Studio model id for `knf llm prompt`. Required unless pass-specific model vars, CLI model options, or single-model auto-discovery provide one. |
| `KNF_LMSTUDIO_DRAFT_MODEL` | Optional model id for the first prompt-generation pass. |
| `KNF_LMSTUDIO_REVIEW_MODEL` | Optional model id for the review pass. |
| `KNF_LMSTUDIO_API_KEY` | API key passed to the OpenAI SDK. Defaults to `lm-studio`. |
| `KNF_LMSTUDIO_TIMEOUT_SECONDS` | Maximum seconds for LM Studio API calls. Defaults to `120`. |
| `KNF_LMSTUDIO_MODEL_AUTO` | When true, auto-selects the model only if `/v1/models` reports exactly one model. |
| `KNF_LMSTUDIO_CUDA_DEVICE` | Explicit CUDA index for future Kneiff-managed LM Studio launch helpers. |
| `KNF_LMSTUDIO_CUDA_DEVICE_NAME` | Visible GPU name fragment, such as `RTX 4070 Ti Super`, resolved through `nvidia-smi` for future launch helpers. Existing LM Studio servers keep their current GPU. |
| `KNF_PROMPTGEN_DRAFT_TEMPERATURE` | Sampling temperature for the first prompt-generation pass. Defaults to `0.7`. |
| `KNF_PROMPTGEN_REVIEW_TEMPERATURE` | Sampling temperature for the consistency review pass. Defaults to `0.2`. |
| `KNF_PROMPTGEN_MAX_TOKENS` | Maximum response tokens for each prompt-generation pass. Defaults to `2048`. |
| `KNF_PROMPTGEN_REVIEW_ENABLED` | Whether `knf llm prompt` runs the review pass. Defaults to true; `--no-review` disables it for one run. |
| `KNF_PROMPTGEN_STRICT_JSON` | Whether a response without one unambiguous JSON object fails instead of falling back to prompt text. A JSON object wrapped in a Markdown code fence is accepted. Defaults to true. |
| `KNF_PROMPTGEN_SAVE_EXCHANGES` | Whether to save raw prompt-generation exchanges for debugging. Defaults to false; `--save-exchanges` enables it for one run. Saving requires an active storage root. |
| `KNF_PROMPTGEN_EXCHANGE_DIR` | Optional override for raw exchange JSON files. Relative values resolve below the selected storage root; absolute values are used exactly. When unset, saved exchanges go to `/.llm_promptgen`. |
| `KNF_WORKERS` | Positive worker count for dataset export, image inspection, and SimpleTuner workspace staging in the typed AppRC storage section. Defaults to `8`; set it in `.env.apprc-storage`, through `knf config edit`/`config set`, or in the shell. |
| `BASE_URL` | OpenAI-compatible server base URL for image captioning. |
| `OPENAI_BASE_URL` | Alias for `BASE_URL`. |
| `OPENAI_API_KEY` | OpenAI-compatible API key for image captioning. Local servers may accept `not-needed`. |
| `API_KEY` | Alias for `OPENAI_API_KEY`. |
| `KNF_SIMPLETUNER_EXECUTABLE` | Optional app-wide SimpleTuner console-script override for training and model conversion. Must be an existing absolute path or begin with `~`; it takes precedence over `PATH`. |
| `KNF_SIMPLETUNER_CUDA_DEVICE` | Prepared by the LoRA launcher when `--cuda-device` is set. |
| `KNF_SIMPLETUNER_FALLBACK_CUDA_DEVICE` | Prepared by the LoRA launcher when `--fallback-cuda-device` is set. |
| `VIRTUAL_ENV` | Active virtual environment path. |
| `PYTHONPATH` | Import-path override for local smoke tests. Prefer editable installs for normal development. |
`knf comfy` and `knf llm` require `KNF_STORAGE` or `--storage`. Their native
AppRC sections resolve packaged defaults, app-wide overrides,
storage-local `.env.apprc-storage`, explicit `--env-file` values, and process
environment values according to the selected root options.
> [!IMPORTANT]
> `.env.apprc-storage` cannot select its own storage. AppRC must resolve
> `KNF_STORAGE` before it knows which storage-local file to load. Use
> `knf project use NAME`, shell `KNF_STORAGE`, or root `--storage` to select the
> project.
> [!NOTE]
> Related: use [How-To User Guides: environment problems](How-To-User-Guides.md#environment-problems)
> for the first checks when imports resolve from the wrong location.
## Configuration Files
Important config files:
| File | Role |
|---|---|
| [pyproject.toml](../pyproject.toml) | Python packaging, dependencies, entry points, and tool settings. |
| [justfile](../justfile) | Development automation around `uv`, diagnostics, and locks. |
| `~/.config/knf/knf.apprc.toml` | AppRC named-storage registry written by `knf config storage add` or `knf project init`. `KNF_APPRC_TOML` overrides this path. |
| `~/.config/knf/.env.apprc-app` | App-wide AppRC overrides created by `knf config setup` or `knf config app init`. |
| `.env.apprc-storage` | Machine-local overrides inside a registered storage root. AppRC creates it during `knf project init` registration. It is loaded only after storage selection and cannot select that root. |
| `.env` | Local OpenAI-compatible caption server settings. |
| `.git/` | A `main`-branch repository initialized for a new project by `knf project init`. Its local `user.name` comes from `--git-user-name` and defaults to `kneiff`; no email, remote, commit, global Git setting, or Git LFS setup is created. |
| `.gitignore` | Project-root ignore rules written by `knf project init`, including `.env.apprc-storage`, `.llm_promptgen/`, `.old_manifests/`, `HF/`, and `TRAINING/`. |
| `.gitattributes` | Project-root Git LFS tracking declarations for image, model, archive, and workbook files. It does not run Git LFS setup. |
| `default_tags.txt` | Project-owned starter seed containing `kneiff`, the activation token, and the species token. It is not consumed by Kneiff at runtime. |
| `vocabulary.knf.yaml` | Committed strict `kneifftags.vocabulary-extension` schema-version-2 document containing project identities and project-only vocabulary. |
| `prompts.knf.yaml` | Optional committed version-1 project overlay for the packaged prompt catalog. It owns project-specific scenes; its rows require explicit nonempty `uses` lists. |
| `workflows/showcase_.workflow.json` | Optional committed project override for a packaged showcase workflow. |
| `MANIFEST.knf.xlsx` | Fixed A-H dataset workbook generated and reconciled by `knf dataset sync`. Every image occupies 13 rows. Column C stores independent user input; the thumbnail and five derived output cells are merged across the block. |
| `MANIFEST.yaml` | Generated strict schema-version-2 sidecar for Git diffs. It stores logical record identity and user input but no derived captions. |
| `__kneiff_manifest__` | Very-hidden workbook metadata sheet containing schema provenance, record coordinates, stable identifiers, exact content identity, and generated-value fingerprints. |
| `configs/*.knf.yaml` | Dataset export and optional `training.simpletuner` config. It must be a direct child of `configs/`; `source_root`, `manifest_path`, `export_root`, and `allow_export_inside_source` are invalid because Kneiff derives fixed project paths. `knf project init` always creates the Sygred Anima `configs/ANIMA.knf.yaml` template with local component paths and the Flux2 Klein 9B `configs/F2K_9B.knf.yaml` template using `black-forest-labs/FLUX.2-klein-base-9B` with unset component paths. |
| `SOURCE/` | Source image root scanned by `knf dataset sync`; manifest paths stay relative to this directory. A new project includes empty `0-FULLBODY/` and `2-HEAD/` folders. Add anatomy-focused directories only when a project config maps them. |
| `HF//` | Public Hugging Face dataset export root generated by `knf dataset sync`. The root `HF/` directory exists after initialization but is ignored and initially empty. |
| `TRAINING/_/` | Ignored SimpleTuner workspace generated by `knf train prepare` or fresh `knf train start`. The root `TRAINING/` directory exists after initialization but is ignored and initially empty. |
| `TRAINING/_/kneiff-training-run.json` | Required exact-schema Kneiff run-state marker with `schema_version: 1`, a `not_started`, `running`, `incomplete`, `failed`, or `complete` status, normalized absolute paths, explicit optional fields, a nonempty unique subset list, and SHA-256 hashes for every generated JSON artifact. Subsets must match direct `dataset/` children from data-backend `instance_data_dir` values. Markerless, symlinked, modified, or stale workspaces are rejected rather than migrated. The generated `simpletuner-config.json` remains the executable source of truth. |
| `.old_manifests/` | Archived manifest workbooks retained by the project scaffold. |
| `README.md` | Export-root Hugging Face dataset card generated by dataset sync. |
| `metadata.jsonl` | Export-root Hugging Face ImageFolder metadata generated by dataset sync. |
| `.hfignore` | Export-root Hugging Face ignore file generated by dataset sync. |
| `HF//.gitignore` | Export-root Git ignore file generated by dataset sync. |
| `.kneiff-export-state.json` | Export-root local incremental sync state generated by dataset sync and ignored by generated `.hfignore` and `.gitignore`. |
| `kneiff-training-image-grid.jpg` | Export-root contact sheet generated by `knf dataset sync`. |
| `TRAINING/_-kneiff-validation-progress-grid.jpg` | Final validation-progress contact sheet generated after successful `knf train`. |
| [src/kneiff/project_vocabulary.py](../src/kneiff/project_vocabulary.py) | Read-only schema detection, strict extension loading, cached isolated engine composition, project identity metadata, and public definition access. |
| [src/kneiff/project_vocabulary_migration.py](../src/kneiff/project_vocabulary_migration.py) | Pure schema-version-1 project vocabulary conversion, validation, diagnostics, and field-aware legacy input rewrites. |
| [src/kneiff/datasets/manifest/block_schema.py](../src/kneiff/datasets/manifest/block_schema.py) | Authoritative 13-row workbook field order, headers, merge geometry, and dimensions. |
| [src/kneiff/datasets/manifest/block_sync.py](../src/kneiff/datasets/manifest/block_sync.py) | Transactional content reconciliation, migration staging, archive creation, activation, and rollback. |
| `kneifftags @ git+https://huggingface.co/spaces/kneiff/kneifftags.git@v0.4.1` | Exact caption-engine source release. Kneifftools uses only symbols exported from the Kneifftags package root. |
| [.gitignore](../.gitignore) | Local and generated files excluded from Git. |
| `.github/workflows_inactive/` | Ignored local starter CI workflows, if present. |
> [!NOTE]
> Related: use [configuration model](Explanations.md#configuration-model) for
> how local settings, environment variables, and package defaults should stay
> understandable.
## Model Registry
`kneiff.model_registry` is the source of truth for SimpleTuner profile metadata,
compact promotion filename IDs, known model aliases, and friendly dataset-card
labels.
| ID | SimpleTuner profile | Dataset-card label | Recognized aliases |
|---|---|---|---|
| `ANIMA` | `anima` / `base-v1.0` | Anima Base v1.0 | Anima, `anima-base-1.0` |
| `F2K_4B` | `flux2` / `klein-4b` | Flux.2 Klein 4B | F2K 4B, Flux.2 Klein 4B |
| `F2K_9B` | `flux2` / `klein-9b` | Flux.2 Klein 9B | F2K 9B, Flux.2 Klein 9B |
| `CHROMA` | `chroma` / `hd` | Chroma1-HD | Chroma, Chroma1-HD |
| `ZI` | `z_image` / none | Z-Image | ZI, Z-Image |
| `SDXL` | `sdxl` / none | SDXL | SDXL, Pony |
## Public Interfaces
Documented public surfaces:
| Surface | Current Name | Stability |
|---|---|---|
| Package import | `kneiff` | Public package root. |
| CLI entry point | `knf` | Public command declared in `pyproject.toml`. |
| JTP-3 wrapper entry point | `jtp3-wrap` | Public command declared in `pyproject.toml`. |
| CLI implementation module | `kneiff.main` | Import owner for console entry points. |
| AppRC application contract | `kneiff.config.KNEIFF_RC` | Native AppRC capability declaration with application name `knf`. |
| Typed runtime bundle | `kneiff.config.KneiffConfig` | Aggregate of all validated Kneiff AppRC sections. |
| Native config sections | `kneiff.config.StorageConfig`, `kneiff.config.ComfyConfig`, `kneiff.config.LmStudioConfig`, `kneiff.config.PromptgenConfig` | Typed AppRC config classes; construct these directly instead of using loader helpers. |
| Storage registry | `~/.config/knf/knf.apprc.toml` | AppRC-managed persistent storage list. |
| App-wide overrides | `~/.config/knf/.env.apprc-app` | App-wide AppRC dotenv layer. |
| Storage selector env var | `KNF_STORAGE` | Required selector for runtimeful commands; accepts a registered name or path. |
| Dataset config names | `configs/*.knf.yaml` | Public naming convention for path derivation. |
| Dataset config YAML keys | Strict documented fields | Duplicate and unknown fields are rejected before export or training artifact generation, including nested caption, augmentation, resize, caption-output, publishing, and Hugging Face fields. Mapping and caption-output subset names must be exact YAML strings without surrounding whitespace; duplicate normalized mapping sources are rejected. `source_root`, `manifest_path`, `export_root`, and `allow_export_inside_source` are rejected. The top-level `training` block is validated by the training schema. |
| Manifest workbook | `MANIFEST.knf.xlsx` | Public dataset workbook name. |
| Manifest YAML sidecar | `MANIFEST.yaml` | Generated diff-friendly manifest output; do not treat it as editable source. |
| Relative path field | `Relative_path` | Required first row in every 13-row image block. |
| Caption output config | `caption_outputs` | Public global sidecar config block. |
| Caption output overrides | `caption_outputs_overrides` | Public per-subset override block. |
| Export mirroring config | `augmentations.mirrored_extra`, `augmentations.mirrored_transform`, `augmentations.seed` | Public export-time mirror controls. `mirrored_extra` is an exact YAML boolean, and `seed` is an unquoted YAML integer; strings and other coercible scalars are rejected. |
| Image resize config | `image_resize` | Public export-time resize block. |
| Hugging Face publishing config | `publishing.huggingface` | Optional dataset-card fields such as `repo_id`, `pretty_name`, `version`, `optimized_for_model`, `license`, `tags`, `provenance`, `adult_content`, and `notes`. |
| Training selector | `training` | Kneiff-owned selector with only `enabled`, `backend`, and `simpletuner`. `enabled` requires an exact YAML boolean. `backend` accepts only the exact unpadded string `simpletuner`; other, misspelled, or whitespace-padded values are rejected. Unknown fields are rejected even when the nested SimpleTuner block is disabled. |
| SimpleTuner config | `training.simpletuner` | Public LoRA training config block. Kneiff-owned fields use strict types and reject unknown keys; nested native SimpleTuner override mappings remain pass-through. Kneiff owns the fixed workspace paths `simpletuner-config.json`, `simpletuner-multidatabackend.json`, optional `simpletuner-validation-prompts.json`, `.simpletuner-cache/`, and `_simpletuner-output/`. Generated-path override keys are rejected, including `trainer.output_dir` and `trainer_testrun.output_dir`. |
| SimpleTuner subsets | `training.simpletuner.subsets` | Required non-empty image-subset mapping when SimpleTuner training is enabled. Names and optional backend `id` values must be portable single-segment identifiers; set `disabled: true` to exclude a subset from the workspace copy. |
| SimpleTuner curriculum | `training.simpletuner.curriculum` | Optional single-run exact-set curriculum block. `phases` names active image subsets at each `start_step`; `subsets: all` expands to every configured image subset, and total steps still come from `training.simpletuner.trainer.max_train_steps`. |
| SimpleTuner validation schedule | `training.simpletuner.validation_schedule.start_step` | Optional strict non-negative optimizer step for Kneiff's delayed scheduled validation. A positive value runs at exactly that step and every `trainer.validation_step_interval` afterward; the step-0 benchmark and final validation remain unchanged. It requires a positive step interval and rejects `trainer.validation_epoch_interval`. |
| SimpleTuner testrun profile | `training.simpletuner.trainer_testrun` | Optional trainer-behavior overrides used only with fresh `knf train prepare --testrun` or `knf train start --testrun`; it cannot change the fixed output directory. |
| SimpleTuner startup validation | `training.simpletuner.trainer.disable_benchmark` | Native SimpleTuner flag. Set `true` to skip the before-training baseline render or `false` to run it. |
| SimpleTuner validation prompts | `training.simpletuner.validation_prompts` | Strict Kneiff-owned prompt-library config generated by `kneiff.training.lora.simpletuner_validation_prompt_artifacts`; the wrapper and each source reject unknown fields and require exact YAML booleans. Root `styles` supplies caption styles unless a source overrides them with `caption_styles`. It selects curated `training_validation` captions from the resolved project catalog, direct `custom` prompts, independently enabled fixed core wolf/residential-street/office-worker controls, and optional manifest samples. Controls and manifest samples each require one effective supported style (`tags`, `chroma`, or `nlg`). In a custom prompt, `{activation_token}` resolves to the selected project's character token. `negative_control_species` and `from_manifest.profile` are removed; training config cannot redirect the project prompt source. |
| ComfyUI byte upload | `ComfyUiClient.upload_image_bytes(data, *, filename, subfolder="", overwrite=True, type="input")` | Upload encoded image bytes to ComfyUI. `type` accepts `input`, `output`, or `temp`; omitting it preserves input-upload behavior. |
| ComfyUI owned cancellation | `ComfyUiClient.cancel_owned_prompts(prompt_ids)` | Delete only matching pending prompt ids and interrupt an active prompt only when the current queue confirms that its id belongs to the supplied set. |
| Solo T2I entrypoint | `kneiff.infer.comfy.pipelines.t2i_solo.run(request, ...)` | Run the Krea2 solo preset through shared staged orchestration. |
| Duo T2I entrypoint | `kneiff.infer.comfy.pipelines.t2i_duo.run(request, ...)` | Run the Anima baseline and Flux2 cleanup preset through shared staged orchestration. |
| T2I contracts | `kneiff.infer.comfy.pipelines.T2iPipelineRequest`, `T2iPipelinePlan`, `T2iJob`, `T2iStageResult`, `T2iPipelineResult` | Typed request, planning, job, stage, and final-result interfaces for direct Python callers. |
| Project vocabulary | `kneiff.project_vocabulary.ProjectVocabulary` | Loaded schema-2 extension, isolated composed Kneifftags engine, primary character/species metadata, and ordered activation tokens. |
| LoRA config templates | `kneiff.training.lora.templates/*.yaml` | Packaged config templates: `complete.yaml`, `chroma.yaml`, `z-image.yaml`, `flux2-klein-4b.yaml`, `flux2-klein-9b.yaml`, `anima.yaml`, and `sdxl.yaml`. |
The former `load_comfy_config()`, `load_lmstudio_config()`, and
`load_promptgen_config()` helpers are removed. Construct the native section
classes or `KneiffConfig` instead. Non-Typer callers must run
`KNEIFF_RC.bootstrap(storage=...)` before constructing env-backed config; the
`knf` `CliRuntime` performs that bootstrap automatically.
Package areas:
| Package Area | Role |
|---|---|
| `kneiff.config` | Native AppRC application contract, typed bundle, and config section classes. |
| `kneiff.clients.openai_compatible` | OpenAI-compatible API client setup. |
| `kneiff.project_vocabulary` | Schema detection, strict Kneifftags extension loading, project identity metadata, and isolated engine composition. |
| `kneiff.datasets.manifest` | Fixed-block schema, path discovery, workbook and sidecar IO, exact-content reconciliation, Kneifftags rendering, and transactional sync. |
| `kneiff.datasets.export` | Dataset export config loading, planning, caption-profile rendering, writing, and reporting. |
| `kneiff.datasets.augmentations` | Image augmentation transforms and batch workflow. |
| `kneiff.model_registry` | Shared compact model IDs, SimpleTuner profile metadata, public aliases, and dataset-card labels. |
| `kneiff.training.lora` | SimpleTuner config generation, launch, config templates, and checkpoint conversion. |
| `kneiff.training.lora.config_templates` | Packaged LoRA config template discovery and reading helpers. |
| `kneiff.training.lora.simpletuner_config` | Shared parsing helpers for the `training.simpletuner` project config block. |
| `kneiff.training.lora.simpletuner_validation_prompt_artifacts` | SimpleTuner prompt-library models and artifact builders. |
| `kneiff.project_resources` | Project vocabulary, prompt-overlay, workflow, and scaffold validation orchestration. |
| `kneiff.prompts` | Project-agnostic prompt catalog types, fixed controls, parsing, and overlay merging. |
| `kneiff.infer` | Diffusion inference package. |
| `kneiff.infer.comfy` | ComfyUI client, typed resource references, showcase generation, and server-side upscale orchestration. |
| `kneiff.infer.lmstudio` | LM Studio model resolution, dataset-shaped prompt fields, and two-pass prompt-generation orchestration. |
| `kneiff.utils.gpu` | NVIDIA GPU discovery and CUDA launch environment selection helpers. |
| `kneiff.cli.app` | Typer command tree used by the `knf` entry point. |
| `kneiff.app.workbench` | Gradio caption and validation-prompt workbench used by the Hugging Face Space shim. |
| `kneiff.utils` | Shared utility facade and owned utility modules. |
| `kneiff.utils.image.caption` | Generic VLM/server image captioning and sidecar helpers. |
| `kneiff_dev` | Maintainer-only tooling scaffold. |
> [!NOTE]
> Related: use [How-To User Guides: run the first command](How-To-User-Guides.md#run-the-first-command)
> for the first user-facing smoke test.
## Figure Visual Tokens
`docs/render_figures.py` owns the figure theme, token names, and rendered SVG
assets. Keep figure captions and generated asset names stable.
| Token | Value | Use |
|---|---|---|
| `blue` | `#00a2ff` | Maintainer and interface nodes |
| `green` | `#32bc00` | User tasks and editable data |
| `orange` | `#f4a261` | Entry points and project boundaries |
| `purple` | `#8b5cf6` | References and generated artifacts |
| `teal` | `#00a6a6` | Configuration and selection flow |
> [!NOTE]
> Related links:
> - Use [static figure rules](README.md#static-figure-rules) before adding docs figures.
> - Use [documentation authoring](Development.md#documentation-authoring) before changing docs structure or figure assets.