f63ff6830d36500a1dcca7c1a5eb4ff58b8f8401
Three defects, the first found by inspecting the user's Penpot file live while the gate reported something else. The audit resolved the page root with penpotUtils.findShapeById(rootId). Every new Penpot page shares the same root frame id, 00000000-0000-0000-0000-000000000000, and findShapeById searches globally, so that lookup always returned the root of the FIRST page in the file - the user's empty one - rather than the page the gate had just created. That is why the baseline reported shapeCount 0 on all ten prompts while the file actually held 28 shapes and 20 texts. It resolves by pageId now, which is unique. With that fixed the baseline reproduces the reported symptom exactly rather than something worse: the button gets 4 shapes, all grey; the navbar gets 10 shapes and 6 real texts with a single distinct fill colour. Production does create structure and text. What it never manages is to apply colour - it creates the shapes in a call that works, then sets fills in a later call using Figma syntax, that call throws, and the shapes keep the #B1B2B5 default. So "creates grey boxes" was accurate and "creates nothing" was my measurement error. Two metrics now capture that directly, since neither distinct-colour counts nor placeholder-grey counts see it - #FFFFFF and #000000 are not mid greys, so a design where every fill is a default passes both. explicitFillShare is the share of filled shapes whose colour is not one of Penpot's three defaults, thresholded by difficulty (0.80 high, 0.65 medium, 0.50 low, since a small artefact's structural neutrals weigh heavily in a ratio). And onlyDefaultColors is a veto: true when the whole palette is those three. White and black stay legitimate when chosen - the distinction is co-presence, not the hex. They are only suspicious when they are all there is; alongside chosen brand colours they also count as neutrals in paletteStructured. resumen() crashed adding None scores from failed prompts. Beyond the crash, an unmeasured prompt must not average in as a zero: "could not measure" and "the model did it badly" are different, and averaging them would have made a mid-run plugin outage look like cheap quality. They are reported separately and any missing prompt makes the verdict invalid, because a baseline with 5 of 10 measured is not a baseline. The gate now empties its own page after exporting the PNG. Across three runs the plugin reliably handled 5 or 6 heavy prompts and then degraded to 30-second timeouts on createPage - that is not random flakiness, it tracks the file growing by one page per prompt, so the gate was manufacturing its own failure. The evidence that matters is the PNG plus the JSON metrics, not the live page. A page is kept only when its PNG failed, so there is something to inspect. Exit code 3 now distinguishes "plugin degraded mid-run, reload it and resume these ids" from "plugin not connected".
Description
No description provided
465 MiB
Languages
Python
92.8%
Jinja
7.2%