arkennemasis Cell Matrix (N-axis cartesian product)
The cartesian product that knows when to stop
- cells_json
- count
- report
ArkCellMatrix is where a client's variation spreadsheet becomes an actual list of jobs. It takes the compiled recipe and expands it into every cell - the cartesian product of all N axes times the plates. If you have three colour variants, two material variants and two camera plates, you get twelve cells, and each cell carries everything downstream needs to generate one image without ever re-deriving the combination.
In the arkennemasis Variation pipeline this is the node between Recipe Compile and the generation chain. It's pure combinatorics plus some very deliberate pruning, and it never calls a model - the entire cost is in what you do with the cells afterwards.
The mechanism, and the parts that save you money
The headline input is recipe_json (the compiled recipe, with the locks and tolerances already injected as constants). Feed in optional intake_json and something interesting happens: when the client's sheet declared specific variant rows, only the combinations they actually declared are generated. If a client deliberately omitted red+large, the matrix honours that instead of burning a generation on a combination they told you not to make.
The three pruning dials are where a beginner gets real value:
limit(0 = all) - cap how many cells come out. The tooltip's advice is worth following: use a small number for your first end-to-end test.pick- which cells the limit keeps.spread across the matrixwalks the whole product at even intervals, so a 5-image test covers different colours and different spec formats instead of five near-identical variations of the first colour.first onestakes them in order, for resuming a deliberate slice.only_axis_value- pin one axis to one value, per line (axis=value), to sweep a single axis. That's exactly what axis-level review needs and it's one of the least-promoted features here.
skip_delivered: why resume is safe
skip_delivered defaults to on, and it's worth understanding why it's a checkbox on this node rather than something downstream. It leaves cells that are already delivered out of the list entirely, and the tooltip spells out the reason: per-cell skipping cannot work behind a fan-out, because ComfyUI unions every item's lazy decision - one unfinished cell would force the generator to be called for all of them. So the resume logic lives here, reading the durable job records in jobs_dir (default variation/jobs, never written by this node). Turn it off and you rebuild the whole set and pay for it again.
Outputs are cells_json (the full list), count, and a report. cells_json feeds either ArkCellAt (for a sequential per-cell chain) or ArkCellFanOut (for the concurrent version).
Installing and gotchas
It ships with the comfyui-arkennemasis pack - ComfyUI Manager → Install via Git URL → https://github.com/Hishamahmer/comfyui-arkennemasis, or
cd ComfyUI/custom_nodes && git clone https://github.com/Hishamahmer/comfyui-arkennemasis
pip install replicate httpx
then restart. No models, no keys. The trap most people hit is treating the matrix as a simple double for-loop and hard-coding two axes - the pack is explicit that "two nested loops over exactly two axes is a defect, not a simplification." This node exists so the per-cell chain stays written once no matter how many axes the recipe declares. The other common mistake is leaving jobs_dir on a per-run folder; it must survive runs, or skip_delivered has nothing durable to read and you'll quietly regenerate finished work.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| recipe_json | STRING | {} | — |
| intake_jsonopt | STRING | Optional. When present, only the variant rows the client actually declared are generated. | |
| limitopt | INT | 00–100000 | Generate at most this many cells. 0 = all of them. Use a small number for the first end-to-end test — three cells on one axis is the spec's own step 2. |
| offsetopt | INT | 00–100000 | Skip this many cells first. With limit, lets you run a specific slice without touching the rest. |
| only_axis_valueopt | STRING | Optional filter, 'axis=value' per line. Pin one axis to one value to sweep another axis on its own — which is exactly what axis-level review needs. | |
| pickopt | COMBO | WHICH cells the limit keeps. 'spread' walks the whole matrix at even intervals, so a 5-image test covers different colours AND different specification formats instead of five variations of the first one. 'first ones' takes them in order — use it to resume a deliberate slice with offset. | |
| skip_deliveredopt | BOOLEAN | true | Leave cells that are already delivered OUT of the list. Resume relies on this: the per-cell skip downstream cannot work behind a fan-out, because ComfyUI unions every item's lazy decision, so one unfinished cell would bill the generator for all of them. Off = rebuild the whole set and pay for it again. |
| jobs_diropt | STRING | variation/jobs | Where the durable per-cell records live. Only read here, never written. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| cells_json | STRING | — |
| count | INT | — |
| report | STRING | — |