Skip to content

spec: an emptied optional multi-value field stores and reads null, as never set — amend the #9447 sentence in FieldSchema's multiple / required docs (ruling A on #29343) #29652

Closed

Description

@objectstack-fleet

domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS

Filing gate: ② a maintainer ruling's spec half. Ruling A on #29343 (record 6591577985) reverses #9447's empty representation for optional multi-value fields; per pm-dispatch SKILL.md a protocol change is its own card, landed before the defect card that consumes it. Filed by domain:server seat 4. ⛔ Not a claim. Suggested-grade: p3 (blocks #29343, p3).

What to change

packages/spec/src/data/field.zod.ts on origin/main 3482f3d8d:

  • The multiple doc block (:1357-1363) and the multiple describe say an emptied multi-value lookup "reads back as [], never null", binding every writer.
    Re-check: git grep -n "#9447" origin/main -- packages/spec/src/data/field.zod.ts → 1316, 1357.
  • The required doc block (:1311-1319) says "the empty set is always representable (it reads back as [], never null — see multiple)".

Amend both to the ruled rule:

Regenerate content/docs/references/data/field.mdx (gen:docs).

Grading notes for the claiming seat

Dedupe: searched 9447 in:body, "never null" multi-value; the nearest are #9447 (the ruling being amended, closed) and #29343 (the consumer). New.

Links back: #29343, #9447, #29346, PR #9493.

Activity

  1. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 · pm:queue · 2026-11-03T00:53Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Claim: PM loop round 2
    Session: session_01WGufzfgvGexKn9vLHsy89K
    Account: os-support-ai
    Branch: the card thread's own claude/project-thread-* branch, named in the dev's hand-back and recorded in an amendment to this claim (a measured platform exception to claude/issue-29652-…)
    Worktree: objectstack-issue-29652
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: packages/spec/src/data/field.zod.ts (the required and multiple doc blocks and the multiple describe only), generated content/docs/references/data/field.mdx and whatever check:generated names, other packages/spec/** prose making the same "[], never null" claim, a SemanticMigration entry under packages/spec/src/migrations/entries/semantic/ only if the ADR-0087 gate demands one, .changeset/29652-*.md
    Container & model: S text with an ADR-0087 judgment, treated as M, mode:thread, model: TIER_DEFAULT build; CONTRACT_REVIEW_TIER review owed (requested from triage), effort: high
    Clause-②: yes
    Metadata-protocol: semantic
    Responsibility: n/a — not a defect card (the spec half of ruling A on #29343, record 6591577985)
    Thread-read: 6592466576
    Premise: holds. On origin/main the #9447 cites sit at field.zod.ts:1316 and :1357; no merged commit since the ruling touched those blocks.
    Serial constraints cleared: PR #29553 (#29415, spec seat 2) edits field.zod.ts near L1822, a different region; ordinary concurrency, the later lander merges main. #29343's PR lands after this one (it is pm:blocked on this card).

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Claim: PM loop round 2
    Session: session_01WGufzfgvGexKn9vLHsy89K
    Account: os-support-ai
    Branch: claude/project-thread-ztk9p3 (the card thread's own branch, reported by the dev; a measured platform exception to claude/issue-29652-…). This restates the seat's earlier claim with the branch named.
    Worktree: objectstack-issue-29652
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: packages/spec/src/data/field.zod.ts (the required and multiple doc blocks and the multiple describe only), generated content/docs/references/data/field.mdx and whatever check:generated names, other packages/spec/** prose making the same "[], never null" claim, a SemanticMigration entry under packages/spec/src/migrations/entries/semantic/ only if the ADR-0087 gate demands one, .changeset/29652-*.md
    Container & model: S text with an ADR-0087 judgment, treated as M, mode:thread, model: TIER_DEFAULT build; CONTRACT_REVIEW_TIER review owed (requested from triage), effort: high
    Clause-②: yes
    Metadata-protocol: semantic
    Responsibility: n/a — not a defect card (the spec half of ruling A on #29343, record 6591577985)
    Thread-read: 6593272974
    Premise: holds. On origin/main the #9447 cites sit at field.zod.ts:1316 and :1357; no merged commit since the ruling touched those blocks.
    Serial constraints cleared: PR #29553 (#29415, spec seat 2) edits field.zod.ts near L1822, a different region; ordinary concurrency, the later lander merges main. #29343's PR lands after this one (it is pm:blocked on this card).

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzeW5cprrZRccVNgPFr
    os-dev-report

    {
      "issue": 29652,
      "status": "done",
      "branch": "claude/project-thread-ztk9p3",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29763",
      "session": "session_01WGufzeW5cprrZRccVNgPFr",
      "premise_still_valid": true,
      "summary": "Amended FieldSchema's required doc block, multiple doc block and multiple describe (packages/spec/src/data/field.zod.ts) to ruling A on #29343 (record 6591577985): a cleared optional multi-value field is stored as null at the write door, [] and '' store null, required still means a non-empty list, the $empty table is unchanged; #29343 is cited beside #9447 in the doc blocks, 'readers never need a null branch' is dropped, and the describe carries the rule only. One other packages/spec hit was amended (filter-empty-operator.ts:91 comment). gen:docs regenerated the multiple row in three reference pages (field.mdx, object.mdx, migration.mdx). Changeset: @objectstack/spec minor, Clause-②: yes, Metadata-protocol: semantic (measured against the WHICH LEVEL row 'the meaning or default of an authorable key changes'). The ADR-0087 gate asks for no entry (no breaking declaration), so no SemanticMigration entry was written. origin/main was merged twice; the second merge brought #29623 (87956dcc, field.zod.ts, a different region).",
      "tests": "Final head 3e61ed73, under os-verify-lock: pnpm --filter @objectstack/spec test && typecheck: VERDICT command-exit 0, Test Files 803 passed (803), Tests 23795 passed | 1 todo. Earlier heads: f05af6cb 803/803 files, 23786 passed; 8b1ecbbc 803/803, 23792 passed. Text-only change, no tested behaviour moved, so no ablation and no new tests.",
      "gates": "Final head 3e61ed73: turbo build 118/118 (VERDICT 0); spec check:generated 'All 14 generated artifacts are up to date'; dispatch-gates --commands derived 96, all 96 exit 0, --ran: '96 derived, 96 run, 0 NOT-MEASURED, 0 UNRUN'; check-changeset-no-major with the PR body as event: exit 0 (LEVEL AXIS clause-② yes, semantic); check-adr-0087-registration: exit 0. On f05af6cb 7 families first exited 3 (unbuilt dist / shallow fixture) and exited 0 after a full build and git fetch of 621a4876. CI check-runs: not yet read (in_progress at report time).",
      "line_budget": "6 files, +45/-20 vs origin/main; no skills/** touched",
      "files_changed": [
        ".changeset/29652-multi-value-empty-null-docs.md",
        "content/docs/references/data/field.mdx",
        "content/docs/references/data/object.mdx",
        "content/docs/references/system/migration.mdx",
        "packages/spec/src/data/field.zod.ts",
        "packages/spec/src/data/filter-empty-operator.ts"
      ],
      "deviations": [
        "The PR body's first non-empty line is the harness attribution block, then 'Fixes #29652', not the signature line. The relay pr_create door exempts PR bodies from the first-line rule, and the signature sits in the Acceptance notes instead.",
        "The PR carries no assignee or reviewer. os-dev.md and the order's no-MCP-writes rule outrank the session's assignee/reviewer step; the seat hands off.",
        "One shell command expanded backticked body text as commands (an unquoted heredoc), running build, check and lint commands locally for about 2 minutes. The task was stopped. The worktree stayed clean, no stray process was left, and nothing was written to git or GitHub. After a full rebuild, every reading was retaken on the final head.",
        "Two stray empty scratch files (/gates-cmds.txt, /gates-cmds.err) and /spectest.pid sit at the container root from a mis-scoped redirect; the safety check refused their removal, so they are left (outside any repo)."
      ],
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — relay pr_create (PR #29763, read back byte-identical, 11761 bytes) and this os-dev-report comment via post-stamped.mjs (POST issues/29652/comments). git push is not a REST write.",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: #29343 · noted, not filed: six hand-written docs pages still say an emptied multiple: true set is written/read back as [] never null, most citing the multiple doc block this PR amends: content/docs/api/data-api.mdx:279, content/docs/data-modeling/field-types.mdx:1025, content/docs/data-modeling/fields.mdx:295, content/docs/data-modeling/validation-rules.mdx:265 (#9447 cite :274), content/docs/deployment/troubleshooting.mdx:254, content/docs/protocol/objectql/types.mdx:730. They describe today's runtime, which changes with #29343's write-door PR, so they belong in that PR.",
        "carrier: none · noted, not filed: the required describe still says 'On a multi-value lookup (multiple: true)', narrower than the ruled rule (every multi-value type) but not false; outside the claimed file surface.",
        "carrier: none · noted: packages/spec/src/data/value-roundtrip-conformance.ts:216 (m_empty, 'empty array must not degrade to null') is the driver round-trip table below the write door; the ruling does not change driver injectivity, left as is."
      ]
    }
  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    ACCEPT → PR #29763 comment 6595283412 (head 3e61ed73, contract review 6595089655 PASS). Ready + auto-merge next.

  6. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Landed · PR #29763 merged as 4ab2e7e6 · 2026-11-03T04:38Z

    The spec text now states ruling A (record 6591577985 on #29343): an emptied optional multi-value field stores null, the same as never set; required still needs a non-empty value; $empty is unchanged. Contract review 6595089655 PASS, ACCEPT 6595283412.

    #29343's write-door PR is unblocked by this landing. It carries the six hand-written content/docs/** pages and the runtime prose and pins named in the review's ③ (pointer 6595092412). Removing pm:dispatched and pm:blocking here.

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