Files
open-design/packages/plugin-runtime
f1a73f0d89 feat(od-next): structure-only layout primitives for the prototype task profile (#7327)
* feat(od-next): ship structure-only layout primitives with the prototype task profile

Blind evals and the pet-grooming runs showed the same layout defects over and
over — stacked spans that never became blocks, chrome height constants reused
as padding, authored copy crammed until it wrapped — while the prose rules that
forbid them sat unchanged in the prompt. The rules are now backed by something
the Build can copy instead of re-derive:

- `assets/task-profiles/prototype/layout.css`: a ~50-line, structure-only
  stylesheet (`@layer od-layout`, `:where()`, `od-` prefix) for stacked
  information, truncation/clamp of data text, media ratio, rails, and an
  optional screen skeleton. Declared as a prototype resource, staged into
  `.od-frames/` under the existing ownership manifest, and quoted into the
  stable request context as the `layout-primitives` fact on every prototype
  run.
- Prototype rule card 2.2.0: a "Variable-length text and stacked information"
  section that separates authored copy (rewritten to a budget, never
  truncated) from data text (truncate/clamp in lists, wrap in full on
  confirmation and detail screens), keyed to the real class names; the quality
  floor's layout bullet now points at the primitives.
- Core 2.1.0: the variable-length-text paragraph rewritten as actions
  (three fates before the text is written) instead of prohibitions.
- Run-finish observation `od_next_layout_primitives`
  (verbatim / modified / linked / absent) so the rollout can tell whether a
  model tier reproduces the block faithfully enough for inlining.

* fix(od-next): let aspect-ratio win on .od-media and pin two rule-card gaps

The first verification runs exposed one primitive bug and two recurring model
slips: `.od-media` lacked `height: auto`, so an `<img height=…>` attribute
kept its pixel height and the ratio never applied (tall cropped thumbnails);
cards built on `<a>` shipped with browser-default link styling; and product
tokens declared on an inner wrapper left sheet/dialog overlays mounted in the
shell's screen without a surface. The stylesheet and the rule card now say so.

* fix(od-next): keep .od-media at its intrinsic ratio; make cropping an explicit opt-in

Review: the fallback aspect-ratio of 1 plus an unconditional object-fit:
cover turned every unset .od-media into a square crop — contradicting the
core image-geometry rule (content-bearing images render their full frame;
cover is reserved for deliberate crops) and the primitive's own comment,
exactly on the media the rule card points at product shots. The primitive
now defaults to aspect-ratio: var(--od-ratio, auto) with no object-fit;
a uniform tile crop sets --od-ratio and adds .od-media-cover together,
and the commerce-card row of the rule card says so.

* fix(od-next): carry finish-time observations on run_finished, not the frozen baseProps

Review: od_next_device_platform*/od_next_layout_primitives were spread into
baseProps, which is built at run creation — before any deliverable exists —
and run_finished only spreads that frozen object. The daemon log printed the
observations while the analytics event never carried them, which defeats the
rollout signal these fields exist for. They now join finishedProperties,
read live from the run after the physical run resolves. (The device-shell
fields shipped with the same trap in the shells PR; fixed here on the same
lines.)

---------

Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
2026-08-25 03:58:46 +00:00
..