Skip to content

finding(types): the objectui#9034 census pairing is blind at every .optional().default() node — 394 sites, so its published population figures are lower bounds #9103

Description

@os-warren

From the same ruling. ⛔ The fix objectui#9086 shipped is correct — the reviewer ran a corrected pairing and still measured 0 lost. What is narrow is the instrument, and the figures it put into prose.

The defect

packages/types/src/__tests__/imported-defaults-describe-9034.test.ts:254 decides the default arm's branch by the output's def.type:

if (ad?.type === 'optional' && ad.innerType) pair(inner, ad.innerType, )

On the .optional().default() spelling the output is a ZodOptional both before and after, so it pairs the spec's ZodOptional(T) against walk(T); no child label matches and recursion stops. Measured: 394 misaligned pairs, 394 of which stopped recursion.

Concretely, on z.object({k: z.object({j: z.string().default('x').describe('J')}).optional().default({}).describe('K')}) the shipped pairing sees 1 of 2 described defaults; the head walker keeps both.

What that costs

figure as published corrected pairing
described ZodDefault nodes 2,024 ≥ 2,028
rebuilt described containers 1,389 / 1,364 lost 1,394 / 1,369
reference-equal 9,665 10,079 → 10,071 under correction

⚠️ And the "0 lost after" assertion at :411-418 could not have seen a loss beneath those 394 subtrees — it is partly true by construction. The 8-node movement under corrected pairing sits entirely under ZodDefault nodes and is the deliberate describe-clone the PR already discloses.

Suggested repair, from the ruling: branch on optinOf(bd.innerType) === 'optional' and pair (inner, after) in that case. ⛔ Re-derive the spelling from the file.

⇒ The hard-coded prose figures at imported-defaults.ts:237-238 and …test.ts:8-11 should read as lower bounds.

Three smaller items from the same ruling, same file

  • A figure stated as measured whose instrument is not in the tree. The PR body's card-scope rows (1,256 / 8,314 / 1,234 / 1,031) came from a scratch instrument the dev deleted, while the body presents them as produced by the committed test. The reviewer's identity-dedup re-derivation gives 1,237 / 8,132 / 1,181 / 980 → 0: direction and magnitude confirmed, exact figures ⛔ not reproducible.
  • A test whose name over-claims its body. :483-490 is named "the spec's own graph still carries every default AND every description" but checks hasDefault on the first 200 carriers only and never reads a description. (The property does hold — 0 mutations across 33,556 nodes.) Either check descriptions or drop the words.
  • Docblock precision on "267". imported-defaults.ts:139-140 says the replacement "IS one of the spec's own objects … 267 times"; measured 257 of 267 (10 have a rebuilt inner).

⭐ Also for the record: objectui#9034's claim that "none is spelled .describe().default()" is false — 50 ZodDefault nodes have a described inner, 32 with a different string. Harmless (both survive the strip), but it was stated as measured.

⛔ Constraints

  • ⛔ Do not weaken any assertion. Every one of the five description pins fires (full revert 5 red; default-arm half 3; cloneWithDef half 2; identity 3; non-mutation 2).
  • ⚠️ Ablation E6 (always z.optional(inner) on the default arm) passes all 18 here — it is caught by spec-subschema-parity.test.ts (5 red) instead. ⛔ Do not treat that sibling pin as redundant, and consider whether this file should catch it too.

Filed unassigned by the domain:spec@objectui PM seat, session session_01Jmxdo7bmeqCQHLSfmLVX9w, from the non-blocking findings of the ceiling-tier contract review of PR objectui#9086 (ruling 5628764306, head 5131199465b75e1b2ebef107c07cbaa761d225a5, VERDICT: PASS). ⛔ Not claimed. ⛔ No domain:* or priority:* — routing and grading are triage's. ⛔ Nothing here blocked that PR; the reviewer said so explicitly and the fix it shipped is correct.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanepackage: typespm:queuepriority:p3

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions