WORK-603
ID:WORK-603Status:ready

Add metaFields and groupByHeading

The two utilities with actual design in them, as opposed to the spellings in WORK-602.

metaFields(attrs, spec) collapses the declare-then-name-again cycle into one declaration, returning a Record<string, Tag> usable directly as properties. plugins/plan/src/tags/work.ts goes from 36 lines of plumbing to about 13:

Priority:mediumComplexity:moderateMilestone:v0.38.0Source:SPEC-140
claude/work-603-metafields-data-form View source

Criteria completion

Criteria completion: 0 of 10 (0%) checked; tracking started on Sep 28, no incremental history yet0%25%50%75%100%Sep 28Oct 11

Tracking started Sep 28 — check back for trends.

Branches 4
History 2
  1. ed4967a
    Created (ready)by bjornolofandersson
  2. 9762a80
    Content editedby Claude
    docs(plan): break down v0.38.0 — rune transform consolidation

Acceptance Criteria

  • metaFields' spec is data: a bare string, or { from: [...], default } — no entry accepts a function
  • The spec round-trips through JSON.parse(JSON.stringify(...)) unchanged
  • from resolves only the declared roots (attrs.*, file.*); an unknown root is rejected at call time rather than resolving to empty
  • The five runes reading config.variables.file express their created / modified fallback without a closure
  • A property-and-ref name collision is still rejected with the ADR-008 error when the properties object comes from metaFields
  • metaFields is adopted where a rune's metas are all plain attrs reads mapped into properties; runes needing a meta outside properties, or conditionally, keep the explicit form
  • groupByHeading is adopted at the seven loop sites, with each rune's per-item parser left rune-specific
  • No lint rule or contract assertion makes either utility mandatory
  • refrakt contracts --check and npm run seo:baseline:check report no drift
  • npm test passes unchanged

Approach

metaFields writes into the same flat key space as refs (ADR-008), so the collision check has to keep working against a computed object rather than a literal — worth a test, since the current check reads Object.keys of both and a generated object is the case nobody has exercised.

Key order matters for data-rune-fields, which is JSON.stringifyd: iterate the spec in declaration order so the bag's key order stays stable and the contracts diff stays empty.

groupByHeading shares only the traversal. parseColorEntry, parseNameValue, parseFontEntry and parseLocationItem stay where they are — the loop is the duplication, not the parsing.

Blocked by

  • WORK-598 — metaFields produces the properties object, so it lands after the children emission is gone rather than having to reproduce it

References

  • SPEC-140 — Tier 3, D5
  • ADR-008 — the flat namespace properties and refs share