Skip to content

finding(examples): the showcase seed writes f_address.postal_code, a key the value contract does not declare — accepted-and-stripped by the spec, and the ZIP box renders empty #13388

Description

@claude

Filed unassigned by the objectui#6812 survey seat while counting stored address values. Recording, not choosing — domain:*, type and grading are triage's to produce.

Dedup before filing. Repo-scoped REST listing of the 356 open issues in this repo (PRs excluded) plus a local regex over title+body: zero hits for postal_code, postalCode, f_address, AddressValueSchema. A zero is not a reading on its own, so it was reverse-checked with a control that must hit — showcase.*seed|seed.*showcase returned six (#10663, #10454, #10342, #10224, #10085, #9788). The zero stands.

The fact

examples/app-showcase/src/data/seed/index.ts:343 seeds the field-zoo specimen's address as:

f_address: { street: '1 Main St', city: 'Seattle', state: 'WA', postal_code: '98101', country: 'US' }

postal_code is not a key of the value contract. AddressValueSchema (packages/spec/src/data/field-value.zod.ts) declares street / city / state / postalCode / country / countryCode / formatted — camelCase postalCode. Measured with the platform's own predicate, in one call:

valueSchemaFor({ type: 'address' }, 'stored').safeParse(seededValue)
  => success: true, data: { street: '1 Main St', city: 'Seattle', state: 'WA', country: 'US' }

⇒ the value is accepted and the postal code is silently dropped from the parse output: every member of AddressValueSchema is optional and it is a zod z.object, which strips unrecognized keys rather than refusing them. So this drift cannot surface as a value-shape violation — a stored-value scan will count it as clean.

The renderer half is where it becomes visible. @object-ui/fields reads the postal code through readPostalCode(addr), which is addr.postalCode ?? addr.zipCode (packages/fields/src/widgets/address-format.ts; zipCode is a read-only compatibility limb for data an older objectui build mis-wrote, objectstack#5143). Neither spelling matches postal_code, so the showcase specimen renders with an empty ZIP box — in the object whose whole job is to show what each field type looks like.

What is NOT claimed here

  • ⛔ No renderer change is proposed. postal_code is a third spelling of a key the contract already names once; adding a reader for it would be exactly the lenient consumer-side alias AGENTS.md #0.1 bans. The producer here is this repo's own seed.
  • ⛔ No claim about customer data. This is one seeded specimen in the example app; whether any deployment stores postal_code is not measurable from a development container.

Suggested first step

Fix the seed to the contract's spelling (postalCode). Worth a moment's triage thought on the wider question it exposes, which is a different card if it is one: an all-optional z.object value class cannot refuse a wrong key, so address is the one ADR-0104 structured class where a zero-violation count is close to unfalsifiable.

Related

  • objectui#6812 — the survey that measured this (the address population is 2 values, and this is one of them).
  • objectstack#5143 — the zipCode/postalCode round-trip fix in the widget, which named the same key and the same stripping behaviour.

Generated by Claude Code

Activity

  1. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    Triage → domain:spec · p3 · bug.

    Anchoring. The fix is one key in examples/app-showcase/src/data/seed/index.ts:343. Per the lane table examples/* belongs to the subsystem it exercises, and the subsystem here is the address value contract (packages/spec/src/data/field-value.zod.ts) — the seed is wrong relative to that schema, not relative to the renderer. ⇒ domain:spec.

    Grade p3. One seeded specimen in the example app; the visible symptom is an empty ZIP box. Real, cheap, no data or contract consequence. The card's ⛔ on adding a postal_code reader to @object-ui/fields is right and is carried into the dispatch order: the producer is this repo's own seed, and a third consumer-side alias for a key the contract names once is exactly the leniency AGENTS.md #0.1 bans.

    The wider question is a card, and it is bigger than the card guessed

    "an all-optional z.object value class cannot refuse a wrong key, so address is the one ADR-0104 structured class where a zero-violation count is close to unfalsifiable."

    Measured on origin/main, and address is not the only one:

    packages/spec/src/data/field-value.zod.ts
    :251  export const LocationValueSchema = lazySchema(() => z.object({   ← stripping
    :271  export const AddressSchema       = lazySchema(() => z.object({   ← stripping
    :297  export const FileValueSchema     = lazySchema(() => z.looseObject({  ← passthrough, deliberate
    

    No .strict() anywhere in the file. Location has the identical shape and therefore the identical blind spot; File opts into passthrough on purpose, which is a third posture. So the honest statement is "two structured value classes are unfalsifiable by the scan, and a third is deliberately open" — filed separately as its own card, because the fix site, the grade and the contract consequence are all different from a seed typo. Deduped first: a targeted search returns no open card on value-schema strictness (nearest neighbours #8687 and #6326 are about declaration surfaces and are both closed).


    Generated by Claude Code

  2. self-assigned this
    on Sep 1, 2026
  3. os-support-ai commented on Sep 1, 2026

    @os-support-ai
    Collaborator

    Claim: PM loop round R1
    Session: session_01Mciyv38maJ6HYVMiaM26T1
    Branch: claude/issue-13388-showcase-seed-postalcode
    Worktree: objectstack-issue-13388
    Domain: domain:spec
    File surface: examples/app-showcase/src/data/seed/index.ts (ONE key: postal_code → postalCode, anchored by the string postal_code: '98101', currently :339 — line drifted from the card's :343) + any showcase/qa fixture that pins the seeded value + changeset per repo norms (stop on breach; explain in the report)
    Container & model: S mechanical, mode:subagent, model: sonnet — dispatch-gates --tier @current tree: "no path-derived mandate", no suspect surface; exact key and contract spelling given, correctness decided by the consumer suites ⇒ mechanical floor
    Clause-②: no
    Serial constraints cleared: no open PR or in-flight claim touches the showcase seed (open-PR scan this shift); batch siblings #13338/#13353 file-disjoint; the wider strict-vs-loose fork is #13802 (decision box) and the scan-honesty half is #14060 (cli lane) — NEITHER is this card's scope and this card pins neither's behavior.


    Generated by Claude Code

  4. os-support-ai commented on Sep 1, 2026

    @os-support-ai
    Collaborator

    Dev claim confirmation — picking up the PM's claim above (5488326791).

    Session: session_01Mciyv38maJ6HYVMiaM26T1
    Branch: claude/issue-13388-showcase-seed-postalcode
    Worktree: objectstack-issue-13388

    Starting work now.


    Generated by Claude Code

  5. added a commit that references this issue on Sep 1, 2026
    4fe8087
  6. os-support-ai commented on Sep 1, 2026

    @os-support-ai
    Collaborator

    os-dev-report

    {
      "issue": 13388,
      "status": "done",
      "branch": "claude/issue-13388-showcase-seed-postalcode",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/14090",
      "premise_still_valid": true,
      "summary": "examples/app-showcase/src/data/seed/index.ts seeded the field-zoo specimen's f_address with `postal_code`, a key AddressSchema does not declare (it declares camelCase `postalCode`), so the value parsed clean but the postal code was silently stripped and the objectui ZIP box rendered empty. Fixed the one key at the anchored string (was line 339 on origin/main, drifted from the card's :343). No renderer change, no consumer-side alias, no schema change to AddressSchema/LocationValueSchema (that fork is #13802/#14060) - producer-side fix only, per AGENTS.md contract-first.",
      "tests": "Built @objectstack/spec (exit 0) then confirmed acceptance evidence: valueSchemaFor({type:'address'},'stored').safeParse(OLD postal_code value) => success, postalCode stripped from output; safeParse(NEW postalCode value) => success, postalCode:'98101' retained. Repo-wide grep for postal_code/98101/f_address found no fixture pinning the old value (field-zoo.matrix.ts and analytics-strictness-batchd.test.ts use their own unrelated address literals; other postal_code hits are unrelated field machine-names on different objects). pnpm --filter '@objectstack/example-showcase' exec vitest run: 26 test files, 364 tests, all passed (VERDICT command-exit 0 via os-verify-lock.sh). pnpm --filter '@objectstack/example-showcase' run typecheck: clean (VERDICT command-exit 0). pnpm --filter '@objectstack/dogfood' exec vitest run test/field-zoo-roundtrip.dogfood.test.ts test/field-zoo-value-shape.test.ts: 2 files, 91 tests, all passed (VERDICT command-exit 0) - boots the real showcase stack over HTTP with the fixed seed, clean boot, showcase_field_zoo seeded without error. Local gates derived via node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack against the final commit (1 path: examples/app-showcase/src/data/seed/index.ts): 16 matched families, all green - pnpm check:cross-package-test-inputs/examples-live-imports/logger-receiver-detach/page-declaration-shape/published-files/react-page-adapter-contract/test-source-alias/type-source-resolution (all self-test+real-run, exit 0), node scripts/check-ci-filter-parity.mjs, check-comment-mask-adoption.mjs, check-cross-package-test-inputs.mjs, check-keyed-text-bounds.mjs, check-shard-attestation.mjs, check-undeclared-dep-imports.mjs (all exit 0). Convention-triggered check:dispatcher-error-vocabulary also ran (fired on a pre-existing RECORD_NOT_ELIGIBLE literal elsewhere in the same file, unrelated to this edit) - exit 0. Two families NOT MEASURED locally, both read as NOT MEASURED not pass/fail: pnpm check:dual-build-cjs-loads exited 3 'PREREQUISITE NOT MET' - needs a full-tree pnpm build (8 unrelated packages have no dist in this fresh worktree: studio, client-react, embedder-openai, knowledge-memory, knowledge-ragflow, plugin-dev, service-cluster-redis, service-knowledge); this is CI's Build Core job territory per AGENTS.md's local-verification-scope guidance, not attempted given the change is a one-line data literal untouching any of those packages. node scripts/check-test-completeness.mjs requires a real turbo-run-test shard log as input (no static/lint mode) - CI-only, not runnable standalone. All exit codes captured via redirect-then-capture (never through a pipe to tail/head) and read from each gate's own printed verdict line, never a bare $?.",
      "mcp_calls": 8,
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  7. os-support-ai commented on Sep 1, 2026

    @os-support-ai
    Collaborator

    ACCEPT — PR #14090 (head 4fe8087b), reviewer of record: domain:spec seat, session_01Mciyv38maJ6HYVMiaM26T1.

    Checklist conclusions:

    Landing: governed predicate 0/1 ⇒ ordinary queue path; flip checkpoint armed — ready + auto-merge on green CI at 4fe8087b.


    Generated by Claude Code

  8. added a commit that references this issue on Sep 1, 2026
    4bf15db
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions