WORK-603
ID:WORK-603Status:ready

Add fieldMetas and groupByHeading

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

fieldMetas(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/nifty-ptolemy-80epot View source

Criteria completion

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

Tracking started Sep 24 — check back for trends.

Branches 4
History 4
  1. 8ee94a9
    Content editedby bjornolofandersson
  2. 7f4b6de
    Content editedby bjornolofandersson
  3. ab57f06
    Content editedby bjornolofandersson
  4. 9762a80
    Created (ready)by bjornolofandersson

Acceptance Criteria

  • fieldMetas' 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 fieldMetas
  • fieldMetas 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
  • The utility is named fieldMetas; nothing in the codebase or docs introduces a second metaFields, and RuneConfig.metaFields is unchanged
  • refrakt contracts --check and npm run seo:baseline:check report no drift
  • npm test passes unchanged

Approach

fieldMetas 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 — fieldMetas 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