Skip to content

T2: homogeneous repeated sub-structure → data array (item-mode collection) - #32

Merged
ryandmonk merged 2 commits into
mainfrom
feat/t2-collection
Aug 7, 2026
Merged

T2: homogeneous repeated sub-structure → data array (item-mode collection)#32
ryandmonk merged 2 commits into
mainfrom
feat/t2-collection

Conversation

@ryandmonk

Copy link
Copy Markdown
Contributor

The second representation capability, on the T1 baseline, scoped by measurement. 267 tests (+8); all byte gates untouched.

Fail-first

radio-group-item and select's seven subs sat in the 80-unresolved eval ledger; the item-mode spelling was refused by the v2 grammar; ex.notification-preferences refused end-to-end (/tmp/t2-failfirst.txt, quoted in the suite).

What landed

Item-mode collects{ "of": ["select-item"], "into": "prop:options", "item": { "label": "self.text" } }: each matching descendant becomes one record whose fields resolve on that item's own node (self.text, self.props.<prop>, the new item-local self.id). Absent sources omit the field and A3 arbitrates — relocation, never synthesis. Mixed item/table keys refuse; item fields are closed to item-local selectors at schema and parser (sibling reads refuse; the parse layer names T3).

Measured scoping, reported not papered over

  • select-item carries its label as own text — pure homogeneous shape, collected completely, A3-green.
  • radio-group-item carries only its id; its label is a sibling label joined by htmlForid — a declared key join, T3's mechanism by the ratified boundary (position-pairing is banned). T2 collects {value: self.id}; the sibling labels drop with record (mode-aware messages naming T3) — pinned as the measured T3 frontier.
  • Neither item declares a value prop in the contract (examples encode value into ids by convention) — a contract-modeling gap noted alongside dspack#38.

Measurements

  • Production-v3 coverage: 80 → 72 unresolved (radio-group-item collected; select-item collected, four select subs dropped with authored reasons, content/group absorbed). Fixture reproducible; the receiving plans are committed evidence.
  • Full battery green locally and from a fresh clone (267, pack + v2/strict/browser smokes, json-render, pinned check:sync).

Also in this PR: the authoritative post-T1 Build re-baseline

Same prompts/model/config; contract 3.1.0 (the dspack#37 governance rule live via #36+gen#52): the zero-control-form hole is closed — caught at S3 with repairable findings, the found 0 emit blocker gone from the whole post-T1 column. Post-T1 0/6 with every failure at an honest frontier (unmapped alert/field-set/dialog, stray subs correctly refused, governance-tightened lint exhaustion). Evidence in eval/t1-rebaseline-matrix.json.

Boundaries held

No T3 joins, no T4 slots, no T5 variants (all still refuse); pins intact; no downstream migration; not merged, not published.

🤖 Generated with Claude Code

… collection)

The second representation capability, scoped by measurement of the
production shapes it targets. Fail-first captured before any code
(/tmp/t2-failfirst.txt): radio-group-item and select's seven subs sat in the
80-unresolved eval ledger, the item-mode spelling was refused by the v2
grammar, and ex.notification-preferences refused end-to-end.

ITEM-MODE COLLECTS. A collect may declare `item: { field: selector }`
instead of the table-mode shape: each descendant matching `of` (document
order) becomes ONE RECORD whose fields resolve against that item's own node
— self.text, self.props.<prop>, and the new item-local self.id. Absent
sources omit the field and gate A3 arbitrates required record shapes:
relocation, never synthesis. Mixing item-mode and table-mode keys refuses;
item fields are closed to item-local selectors at the schema AND the parser
(sibling reads refuse; the parse layer names T3 as defense-in-depth).

THE MEASURED SHAPES, honestly scoped. select-item carries its label as its
own text — the pure homogeneous shape, collected completely and A3-green.
radio-group-item carries ONLY its id: its label is a sibling `label`
component joined by htmlFor->id — a DECLARED KEY JOIN, which is T3's
mechanism by the ratified boundary, and position-based pairing is banned.
T2 collects what each item itself carries ({value: self.id}); the sibling
labels are dropped WITH RECORD (mode-aware messages naming T3 — the v1
table-mode strings stay byte-frozen), pinned as the measured T3 frontier.
Also recorded, not papered over: neither item declares a `value` prop in the
contract (the examples encode value into ids by convention) — a
contract-modeling gap for the taxonomy trail alongside dspack#38.

Eval overlay: the full receiving plans (a collecting plan IS a catalog
component, unlike T1's transparent plans) land as committed evidence.
Production-v3 derived coverage: 80 -> 72 unresolved (radio-group-item
collected; select-item collected, four select subs dropped with reasons,
content/group absorbed). The 72 stay deliberately open as the T3-T5 measure.

267 tests green (+8 T2). All byte gates untouched.
…ole is closed

Same six prompts, same model and config as the T1 matrix; contract 3.1.0
(the form-control rule live), gen 0.2.2, emit 0.5.0+T1.

The T1-exposed defect now fails at the layer that owns it: zero-control
forms are caught at S3 with repairable findings, and the 'donation boundary
found 0' emit blocker is gone from the entire post-T1 column. The old 0/6
number stands only as historical evidence of the hole.

Authoritative post-T1: pre-T1 1/6; post-T1 0/6 with every failure at an
honest frontier — unmapped components (alert, field-set, dialog), stray subs
outside their compound (correctly refused), and lint-exhausted repairs where
the model cannot satisfy the tightened governance in two attempts. Two
adapter timeouts retried once, originals preserved. T1's conversion on this
model is limited by model quality, not representation: the named chain
emits deterministically in the corpus tests, and under generation the
model's empty forms now die at governance instead of sailing through — the
system working.
Copilot AI lite review requested due to automatic review settings August 7, 2026 17:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the T2 “item-mode collection” capability to the v2 profile grammar and A2UI emitter, enabling homogeneous repeated sub-structures (e.g., select items, radio-group items) to be collected into array-valued props while explicitly deferring joins/sibling pairing to T3. This extends the existing T1 baseline and updates the evaluation fixture and documentation to reflect the new measured coverage.

Changes:

  • Extend the v2 profile schema + parser to support collects[].item item-mode (and forbid mixing with table-mode keys).
  • Implement item-mode collection in the A2UI surface emitter, including diagnostics updates and self.id selector support for item fields.
  • Add a dedicated src/t2.test.ts suite and update eval fixture artifacts/counts to reflect the new resolved coverage.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/transform/shadcn-v2-respelling.ts Adds production v3 T2 receiving plans for radio-group and select using item-mode collects.
src/transform/profile.v2.schema.json Updates JSON schema to allow item-mode collects via oneOf alongside table-mode.
src/transform/profile-schema-v2.ts Mirrors the schema change in the TS-embedded schema.
src/transform/parse-v2.ts Parses self.id, validates item-mode vs table-mode exclusivity, and builds the internal collect model for item-mode.
src/transform/model.ts Extends selector and collect model to represent item-mode fields and self-id.
src/targets/a2ui/surface.ts Emits item-mode collected records and updates drop/composition diagnostics for item-mode.
src/t2.test.ts Adds fail-first regression + coverage tests for the new item-mode behavior.
src/eval-fixture.test.ts Updates fixture narrative and expected unresolved counts (80 → 72) and resolved breakdown.
eval/t1-rebaseline-matrix.json Adds the authoritative post‑T1 baseline measurement artifact.
eval/shadcn-v3.eval.profile.json Updates the committed eval profile fixture to use T2 plans for radio-group/select.
eval/build-eval-profile.mjs Incorporates the new T2 plans when building the eval profile.
docs/PROFILES.md Documents T2 item-mode syntax and constraints (no joins/sibling reads).
Suppressed comments (1)

src/targets/a2ui/surface.ts:924

  • In item-mode, the surface-composition-flattened diagnostic message correctly mentions “collected item records”, but the corresponding fidelity entry still hard-codes the table-mode note about “cell content beyond text”. This makes the ledger inconsistent/misleading for item-mode collects; the fidelity note should mirror the selected mode.
        code: "surface-composition-flattened",
        message: itemsOnly
          ? `${path}: compound '${node.component}' subtree consumed into collected item records (uncollected content is not carried).`
          : `${path}: compound '${node.component}' subtree consumed into the synthesized table shape (documented casualty; cell content beyond text is not carried).`,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 893 to +897
message: reason
? `${childPath}: '${c}' dropped: ${reason}.`
: `${childPath}: '${c}' has no slot in the synthesized table shape; dropped.`,
: itemMode
? `${childPath}: '${c}' is not a collected item and has no disposition; dropped (sibling pairing is T3's declared join).`
: `${childPath}: '${c}' has no slot in the synthesized table shape; dropped.`,
@ryandmonk
ryandmonk merged commit 496f7d3 into main Aug 7, 2026
2 checks passed
@ryandmonk
ryandmonk deleted the feat/t2-collection branch August 7, 2026 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants