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. added
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Nov 2, 2026
  2. 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

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 3, 2026
  4. 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).

  5. 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).

  6. 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."
      ]
    }
  7. 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.

  8. 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.

  9. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:specDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions