Skip to content

Figma frame selection: consume dev-status (sectionStatus/handoffStatus) from Kiwi decode as primary signal, heuristics as fallback #280

Description

@chubes4

Signal (verified)

Figma's Dev Mode "Ready for dev" / "Completed" status is carried in the .fig Kiwi data, under internal field names (NOT the public REST devStatus). Verified by decoding the raw-deflate schema chunk of two real fixtures (wp-cloud-2.fig, david-perell.fig, schema version 106) — bounded read, no message decode:

  • sectionStatus / SectionStatusInfo — the Ready-for-dev status, attached to sections
  • handoffStatus / HandoffStatusMap / HandoffStatusMapEntry — dev-handoff state
  • enum values: DEV_HANDOFF, DEVELOPMENT, COMPLETED
  • related: NodeStatusChange, currentStatus, statusInfo

The REST/Plugin devStatus is a public projection of these. So we can read the signal from the Kiwi message we already decode — no REST dependency. This is the scalable path: schema-driven decode works for any .fig.

Why this matters

Frame selection today is 100% heuristic — device_hint inferred from name+width, sibling grouping by name similarity, max_pages. That's pattern-based guessing at designer intent. sectionStatus/handoffStatus IS designer intent, stated explicitly. Using it:

  • Selects/prioritizes deterministically — marked-ready sections in, WIP/drafts out.
  • Kills the duplicate-draft false-positive (e.g. WP.Cloud's 4× "For Hosts" desktop drafts) with real data instead of width/name heuristics.
  • Gives a natural page/component unit: a Ready-for-dev section.

Scope

  1. Decode (the valuable part): extend the Kiwi field policy so the existing schema-driven decoder carries sectionStatus/sectionStatusInfo/handoffStatus through into the scenegraph. No hand-rolled byte parsing — use the real Kiwi decode.
  2. Normalize: map the internal enum (DEV_HANDOFF/DEVELOPMENT/COMPLETED) to a clean dev_status on nodes (ready_for_dev | completed | null), carrying the raw value alongside for auditability.
  3. Select: when any dev_status is present, make it the PRIMARY frame-selection signal (prefer ready/completed sections+frames); demote the name/width heuristics to fallback used only when no dev-status exists in the file.
  4. Diagnose: dev-status coverage (how many sections/frames carry a status, and the selection source: dev_status vs heuristic).

Acceptance

  • A scenegraph with a Ready for dev / Completed section selects those frames and skips WIP; with no dev-status present, behavior falls back to today's heuristics unchanged.
  • Diagnostic reports dev-status coverage and which signal drove selection.

Validation

Schema presence is proven. Value-level proof (a section actually marked ready) needs a marked fixture decoded — the FSE Pilot file has the label visible in-app and should be re-exported into the fixtures dir, then validated on the lab (not locally — large .fig message decode is RAM-heavy).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions