AI Des2WF — Abstraction Architecture
Des2WF converts one design frame into an editable wireframe. It preserves the design's copy and source layout while simplifying presentation. The backend owns PostgreSQL and capture; the worker owns parsing, classification, assembly and result artifacts; the plugin materializes the result.
The model: one → many decomposition
A design component can become several primitive wireframe nodes, or an accepted wireframe-kit
variant. The existing five spec cases remain layout_frame, instance, compose, text and
unmatched; source geometry and graphic provenance are additive fields, not new node cases.
mode=primitives skips kit selection, not graphic classification. Both modes use contextual
vision when version-matched source PNG evidence is available. mode=kit additionally proposes
registered kit variants with sampled majority voting and deterministic acceptance guards. A kit or
model failure can fall back to primitives without failing the wireframe.
flowchart LR
A["Snapshot + optional source PNG"] --> B["Deterministic parse"]
B --> C["Optional kit selection"]
C --> D["Per-appearance graphic classification + scoped overrides"]
D --> E["Census → apply_kit"]
E --> F["Record rendered policy → emit → score"]
F --> G["Artifacts + result → plugin materialization"]
The decision layer: the census
The flat census records what each source node contributes before layout emission. Its row kinds are
text, box, region, rule, ink, ornament, instance and glyph.
glyphpreserves source artwork, including an instance's actual overrides.inkbecomes an image placeholder: a crossed box at larger sizes, a filled slot at small sizes.ornamentrecords confirmed decoration but emits no paint. A transparent flow slot can remain where removing it would disturb auto layout; an empty absolute decoration need not remain.apply_kitreplaces only rows an accepted variant accounts for. Copy and independently drawn descendants must still be represented.- Every drawn row must be accounted for in emitted lineage. Intentional
ornamentsuppression is an explicit exception, not permission to silently drop arbitrary rows.
Graphic policy: context, not an icon-name allowlist
Candidate discovery is structural: visible graphic owners without text descendants are inspected. Size, a layer name, or bitmap versus vector format does not decide its semantic role.
For each appearance, the strong model receives a screen overview, a source graphic crop, its containing-control crop, ancestor context, names, variants, bounds and local labels. Labels belong to the containing control, not arbitrary nearby text. One component can need different treatment in different contexts; no AI decision is automatically cached across components, variants, files or uses.
| Role | Default applied policy |
|---|---|
direction, action, state, identity, list_marker |
Preserve source shape: arrows, standalone hamburger actions, SNS/brand identity and state indicators carry information |
unknown or uncertain evidence |
Preserve |
content_image, redundant_artwork |
Simplify only when the proposal is high-confidence, requests simplification and says it carries no information |
decoration |
Under the same guards, suppress its paint rather than draw a crossed placeholder |
redundant_artwork also requires a label_node_id that actually exists in the candidate's local
labels. A decorative menu illustration beside an existing label can qualify; “menu icon” is not a
blanket replacement rule. Button flourishes and footer backdrops classified as decoration must not
become image placeholders. Confidence is model judgment, not a calibrated probability.
Evidence, bounds and fallback
The backend captures the PNG from the same Figma version as the JSON snapshot with absolute bounds, using the requesting user's credentials. The immutable source PNG key includes both the frame subtree hash and render hash. Missing version information means no unpinned export.
The worker validates PNG format, a maximum of 32,000,000 pixels, positive source bounds and matching aspect ratio (within the configured 2px / 0.5% tolerance). It prepares a 1280px overview, up-to-512px graphic crops and up-to-1024px control crops, composited onto white.
Classification uses batches of 6, at most 3 concurrent calls and a 180-second classification budget. All candidates are eligible; recursive interleaving across sections and controls prevents a dense branch from monopolizing early batches. There is no first-120-candidate cap. Crop buffers are prepared per active batch, not retained for the whole screen.
Missing/corrupt/oversized/misaligned evidence, provider failure, invalid or incomplete replies, unknown or duplicate IDs, and timeout preserve source artwork. Unfinished candidates retain explicit fallback reasons. These bounds do not guarantee that every graphic is classified on every run.
Explicit human overrides and audit
Operators can set organization-, project- and file-scoped graphic_override_v1 records. Node
overrides take precedence over exact master-component plus exact-variant overrides; conflicting
duplicates prefer preservation. An explicit simplify override produces ink, not ornament.
Generation reads these records but never automatically writes AI decisions back as overrides.
Legacy metadata-only verdict records are not consumed. See Stores.
Both the result artifact and result document contain graphic_classification: prompt/model
version, source/evidence hashes, proposals, applied decisions and fallback reasons.
record_rendered_policy runs after kit application: a child's proposal is not a separate visible
change when an enclosing source glyph or kit instance already covers it. Inspect rendered_kind,
rendered_reason and covered_by as well as the proposal.
Emission: two layouts, orthogonal to the mode
The API and worker retain layout=absolute as the default for compatibility. The current plugin
explicitly requests layout=auto and offers no layout selector.
| Layout | Contract |
|---|---|
absolute |
Drawn rows are placed at source coordinates under the root; no reflow; depth beyond 2 fails the flatness gate |
auto |
Retain source container ownership, including one-child wrappers; preserve native itemSpacing, padding, alignment, baseline and wrapping rather than measuring new sibling gaps |
source_layout carries per-axis FIXED / HUG / FILL, min/max dimensions, absolute positioning,
stroke participation and hidden flow state. Absolute overlays stay outside the flow.
A single child in a SPACE_BETWEEN container is centered only when source bounds support that
interpretation. These are opt-in source-geometry fields; legacy specs without them keep their
existing materializer behavior.
text_geometry preserves font family, source weight, line height, letter spacing, auto-resize,
leading trim, vertical alignment and paragraph geometry. Same-file source-text cloning can retain
read-only OpenType features such as PALT. Text remains verbatim with a literal neutral color and no
design style bindings. Font fallback or necessary reflow can still change wrapping and must be
diagnosed; geometry preservation is not a pixel-perfect guarantee.
Materializer responsibilities
Source glyph lookup is scoped by source_file_key. The plugin clones the actual source instance
with its overrides rather than recreating the default master. If cloning fails, it can export the
actual source as PNG; unavailable or wrong-file sources produce a visible fallback and diagnostics.
Cloned artwork is proportionally scaled and centered on both axes. Already-correct geometry is not needlessly resized. Glyph wrappers permit intentional source overflow and keep cloned children absolute inside an auto-layout parent.
Ordinary surfaces are de-styled to neutral boundaries; rules retain their authored edges and selected controls can retain a filled state marker. Preserved source glyphs are intentionally not repainted, so identity artwork can retain its original color. Neutralization is not “remove every font and fill.”
The default canvas name is des2wf · {source_name}, falling back to the spec version if the source
name is empty. An explicit spec.name wins, including upstream CODE2WF output names.
How assembly decides
Kit selection remains per-project data, not a name-matching table in code. Selectable atoms are
variants, not component sets. Majority-voted proposals pass unreachable, copy_truncated,
slot_overflow, imagery_heavy, size_implausible and unknown_atom guards.
Slot capacity counts distinct layer paths, because repeated paths address the same text destination.
A rejected proposal leaves the primitive representation intact.
Scoring
ds@1.0 is an emittability gate × verbatim content preservation, compared as a multiset.
unmatched, invented/displaced text, crossed text, coincident boundaries, and excessive
absolute depth fail the gate. Lost strings reduce content preservation instead of independently
failing the gate. integrity, flatness, ink_covered and boundary_fidelity remain diagnostic
terms at weight 0.
The score band uses margin 0.07 when llm_assisted is set by kit selection or graphic classification,
otherwise 0.0. Mode alone does not determine the band or reproducibility. Re-running vision is not
guaranteed to return the same decisions.
A score of 1.0 is not an icon-accuracy or visual-quality pass. The frozen JSON corpus has no source PNGs and checks conservative fallback/layout invariants. Mocked model tests check policy safety; real-provider runs and regenerated plugin screenshots are needed to assess visual quality. The post-terminal render review adds findings without changing the generation's completion state.