arkennemasis Plate Lock (freeze + measure the base photo)
The base photo you'll never regenerate again
- plate
- mask_1
- mask_2
- mask_3
- mask_4
- subject_mask_in
- plate
- subject_mask
- plate_lock_json
- report
- plate_path
ArkPlateLock is the anchor node of the arkennemasis Variation pipeline, and its job is exactly what the name says: freeze one base photograph so it can never quietly change mid-run. You feed it the one retouched photo of a product, it measures the thing to death, and from then on every candidate the pipeline produces is compared back against that frozen record. The whole "every delivered image shows the same physical object" promise of the pack rests on this node not being reselectable.
What it actually does
It writes two things: the plate image itself and a lock file of measurements. The lock records the file hash, dimensions, colour profile, per-region boxes, and the scale-invariant proportion ratios that the verification step compares every candidate against. "Scale-invariant" matters - a candidate can come back at a slightly different resolution and still be judged by the shape of the product, not by pixel counts.
Here's the part people find surprising: the lock is not a one-way door you set and forget. overwrite defaults to off, and when it's off the node refuses to replace an existing locked plate. That refusal is the lock doing its job. Re-locking mid-run silently changes what every later cell gets compared to, and the author treats that as a bug you should have to fight to make. If you re-run with a tweaked base photo and get a refusal, that's the safety working, not a node malfunction.
The inputs that matter
plate- the chosen base photo, one per camera angle. This is the only input that isn't a widget.plate_id- a camera-angle id, defaultfront. It must match the plate id used in the recipe and in the job keys, so pick something stable and stick to it.lock_dir- where the frozen plate and its lock file land.variation/platesby default; relative paths resolve inside ComfyUI's output folder.
The optional side is where you tune how much the node knows. regions is a comma-separated list of region names, in the same order you wire mask_1 through mask_4. Those names are the product's own - this node never invents a set, and nothing downstream assumes a particular one. Or skip the sockets entirely and point region_mask_dir at a folder of <region>.png masks (white = the region); masks are authored once per plate and reused by every cell, so hand-painting them in an editor is entirely reasonable. subject_mask_in lets you hand over an explicit whole-subject mask; leave it out and it's derived from the plate's own border colour.
The colour_profile (default sRGB) is decided here and enforced at verification and embedded at delivery. Generating in one colour space and delivering in another is the classic cause of "the colour looks wrong" after a client downloads a file - this node is where you stop that from ever starting.
Where it sits
The chain reads: Variation Intake → Plate Lock → Recipe Brief/Compile → Cell Matrix → per-cell generation → Verify → Deliver. Plate Lock is the output-node that kicks it all off, and it emits plate, subject_mask, plate_lock_json, report, and plate_path. plate_lock_json is the one you keep - it flows into Calibrate and the verification nodes so they compare against the same frozen measurements.
Installing and gotchas
It's part of the comfyui-arkennemasis pack, so install the pack: in ComfyUI Manager pick Install via Git URL and paste https://github.com/Hishamahmer/comfyui-arkennemasis, or
cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
pip install -r ComfyUI/custom_nodes/comfyui-arkennemasis/requirements.txt
then restart ComfyUI. No model files, no API key - the whole Variation module is deterministic measurement and text, which is why it runs with zero spend. The usual mistakes here are pointing lock_dir somewhere that gets cleaned per-run, and trying to re-lock a plate while overwrite is off. If a cell's colour keeps failing verify, check the plate's colour_profile matches what your generation path emits, not what you think it emits.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| plate | IMAGE | The chosen, retouched base photograph. One per camera angle. | |
| plate_id | STRING | front | Camera-angle id. Must match the plate id used in the recipe and the job keys. |
| lock_dir | STRING | variation/plates | Where the frozen plate and its lock file are written. Relative paths resolve inside ComfyUI's output folder. |
| regionsopt | STRING | Comma-separated region names, in the same order the mask sockets below are wired. The names are the product's own and come from the recipe — this node never invents them, and nothing downstream assumes any particular set. | |
| region_mask_diropt | STRING | Optional folder of <region>.png masks (white = the region). Authored once per plate and reused by every cell, so hand-painting them is entirely reasonable. | |
| mask_1opt | MASK | Region mask 1 — pairs with the first name in 'regions'. | |
| mask_2opt | MASK | — | |
| mask_3opt | MASK | — | |
| mask_4opt | MASK | — | |
| subject_mask_inopt | MASK | Optional explicit whole-subject mask. Omitted = derived from the plate's own border colour. | |
| colour_profileopt | STRING | sRGB | Decided once, here, and enforced at verification and embedded at delivery. Generating in one space and delivering in another is the usual cause of 'the colour looks wrong' after delivery. |
| overwriteopt | BOOLEAN | false | Off: refuse to replace an existing locked plate. That refusal is the lock doing its job — re-locking mid-run silently changes what every later cell is compared to. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| plate | IMAGE | — |
| subject_mask | MASK | — |
| plate_lock_json | STRING | — |
| report | STRING | — |
| plate_path | STRING | — |