DOGMA v39 Period-Aware Tile Prompt
When the VLM calls a car four different things — canonicalise the terms first
- prompt
- clean_report
Here's a small, real problem with handing a VLM's vocabulary straight to a generator. Ask a vision model to inventory a street tile and it prefixes the same concept five ways: car, cars, vehicle, automobile, sedan. Send that as an allowlist and you've told the model four times over that cars matter - and once you add "traffic" or "urban scene" to the list, you've told it to restyle the whole frame. v381 is the v36 term extractor with a canonicalisation pass bolted on.
What the extra pass does
It's an alias table plus a ban list, and it's worth knowing exactly what's in it because the node's behaviour is entirely that table:
- Aliases collapse onto one head term.
car,automobile,vehicle,vehicles→cars.pedestrian,person→people.facade,architecture→buildings.asphalt,pavement,street→road surface.lawn→grass.bush,shrub→vegetation. Roughly two dozen entries, plus abalcony→balconies/roof→roofspair that only exists to stop singulars and plurals eating two slots. - Vague terms are banned outright:
traffic,traffic jam,city,urban scene,scene,metal,glass. These aren't categories you can restore, they're moods - and on an LLM-encoded model a mood in the prompt is a licence to recompose. - The context becomes the lead, not a trailing note. Instead of appending the project context at the end, v381 takes its first two sentences (split on
.!?), caps them at 520 characters, and puts them in front of the refine instruction. If the context is empty it substitutes: "Preserve the exact era, location and technology visible in the source; never modernize."
Resulting prompt shape, nine supported terms and eight protected terms max:
<period lock> REFINE ONLY ALREADY-VISIBLE CARS; PEOPLE; ROAD SURFACE. The source
pixels are the ONLY authority for object existence... Do NOT add another instance
of any listed class... Never rewrite text, logos or license plates.
Two sentences there are doing the heavy lifting for a scene that should be left alone. "The source pixels are the ONLY authority for object existence" and "Do NOT add another instance of any listed class" are aimed squarely at the failure this pipeline keeps hitting: a tile with two cars comes back with four, because the prompt said "cars" and the model obliged.
Outputs prompt and clean_report - the report here is machine-readable, one SUPPORTED: line and one PROTECT: line, which makes it easy to eyeball across a run.
Install
ComfyUI Manager → search DOGMA Nodes, or:
cd ComfyUI/custom_nodes && git clone https://github.com/axior/ComfyUI-DOGMA-Nodes
Restart ComfyUI. No dependencies (requirements.txt is # No external dependencies.), no weights, nothing to configure. The pack README doesn't mention this node - the semantic suite imports itself from dogma_semantic_v5641.py - and there's no community documentation for it anywhere, so treat the class body as the manual.
Where it bites
Ranked lists are capped, and the tail is cut. Nine supported terms is about three concepts after canonicalisation. Big busy tiles will lose entries - the ones the VLM listed last, which may be the ones you cared about. clean_report shows what survived.
Canonicalisation can over-merge. vehicles swallowing cars and trucks is usually right; on a tile that genuinely has a bus and a van as distinct targets, it flattens your intent. There's a banned set you can read in source, but it isn't exposed as an input - if you need different behaviour, you're editing Python.
The two-sentence context cap is arbitrary but consistent. A context paragraph whose important clause is third gets half-included. Keep your project context to two sentences and this node is predictable.
It's still a text node. No mask, no sampler settings. On a 4-step distilled Klein pass at CFG 1 it does exactly what a prompt can do, which is a lot less than people hope and a lot more than nothing.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| tile_report | STRING | — | |
| project_context | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | — |
| clean_report | STRING | — |