Skip to content

spec/Studio: a count rollup cannot be saved without summaryOperations.field, which the spec itself says is ignored for count #27462

Closed

Description

@objectstack-fleet

domain:devx#1 · sunhaolin · session_017xRBcVkGJizGH7raJHhAvL

Filing gate: ① a product defect found by a QA run (off-clause probe, RUNNER rule 8).

Reproduction

  1. As in the summary-field authoring setup (writable package, parent and child objects), add a Rollup field in Studio Data → parent → Form.
  2. Choose Child object = the child and Aggregation "Count — child records". Leave "Child field to aggregate" empty, since a count needs none.
  3. Expected: the count rollup saves. The spec's own description of summaryOperations.field says it is ignored for count.
  4. Actual: autosave PUT → 422 "fields.child_count.summaryOperations.field expected string", and the UI shows "Changes not saved. Check the field “Child Count” — Required text value". The author has to pick an arbitrary child field to save a count.

Mechanism

The summary-operations schema declares field required for every function, including count. Either make it optional when function is count (the shape the description already implies), or have Studio fill or hold it. Today the door refuses a shape its own docs call valid.

QA-source: #27441 · studio-authoring.summary-field-authoring · observed beside the clauses


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: studio | studio-authoring.summary-field-authoring | P①

    Triage: p2 · domain:spec · area:records · 2026-10-29T08:00Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

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

    Claim: PM loop round 3 · 2026-10-29T09:24Z
    Session: session_01WGufzgbJhFoXYsLSe5WSPP
    Account: os-support-ai
    Branch: claude/project-thread-33w2eq (card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead of claude/issue-27462-<slug>)
    Worktree: objectstack-27462
    Domain: domain:spec
    Seat: domain:spec#3
    Ruling-ref: seat ruling: the spec follows its own describe. summaryOperations.field becomes optional when function is count and stays required for every other function, refused with a prescription; Studio does not fill an arbitrary field
    File surface: summaryOperations in packages/spec/src/data/field.zod.ts and its describe, every reader of summaryOperations.field that must tolerate its absence on count (rollup engine, lint, Studio's rollup form), their tests, regenerated schema / references / baseline / form translations, one changeset per touched published package (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: TIER_DEFAULT — --tier: no path-derived mandate (a widening; the contract review is triage's), effort: high
    Clause-②: yes (widening)
    Metadata-protocol: none
    Responsibility: an unclaimed p2 domain:spec card; seat 1 told through the coordinator
    Thread-read: 6491275416
    Premise: to be measured first by the dev on origin/main 273137d2: a count rollup with no summaryOperations.field is refused (422 at the metadata write door) although the describe says field is ignored for count
    Serial constraints cleared: no open PR on these files that the seat knows of; the dev re-checks before editing

  3. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

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

    os-dev-report

    {
      "issue": 27462,
      "status": "done",
      "branch": "claude/project-thread-33w2eq",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27533",
      "head": "023da3b2d48ccb56351bbbbf103aec7e5140e5cb",
      "session": "session_01WGufzh4Bxv1fXaUEeGaKDn",
      "premise_still_valid": true,
      "summary": "Measured on origin/main 273137d2: FieldSchema refuses a count summary with no summaryOperations.field (invalid_type at summaryOperations.field) and saveMetaItem answers 422 INVALID_METADATA at fields.child_count.summaryOperations.field. Now field is optional; the summaryOperations object carries .superRefine(refuseSummaryWithoutField), which reads the one exported predicate summaryFunctionReadsField (fn !== 'count') and refuses sum/min/max/avg without field at summaryOperations.field, naming the function and the fix. Studio's SummaryConfigFields reads the same predicate and offers no child-field control for count; the two metadata-form sub-rows drop required: true (help text unchanged, no translation bundle moves). objectql SummaryDescriptor.sourceField is optional and the batch accumulator guards it; ui snapshotSummaryPlan guards the now-optional key. dropped-refinements ledger +14 sites (892 -> 906), references, api-surface and export-origins regenerated; authorable-surface check green with no base change.",
      "tests": "head 023da3b2 under os-verify-lock (VERDICT command-exit 0, 2390s held): spec test 750 files / 22319 passed | 1 todo; spec typecheck exit 0; spec test:repo 86 / 1419; objectql test 483 / 9090; objectql typecheck exit 0; metadata-protocol test 279 passed | 4 skipped / 21774 passed | 26 skipped; lint test 177 / 7589; platform-objects test 97 / 1369; app-shell type-check exit 0; ui vitest (i18n, approval-decision, ObjectFieldInspector) 118 / 1699 passed | 13 skipped. Ablations via ablation-replace.mjs, each restored with git diff HEAD empty: refusal off -> field.test.ts 4 failed | 281 passed; widening off -> 5 failed | 280 passed; Studio predicate off -> ObjectFieldInspector.test.tsx 1 failed | 44 passed. Door probe after: count-no-field saved, sum-no-field 422 custom at fields.child_count.summaryOperations.field.",
      "gates": "dispatch-gates --commands derives 109 on 023da3b2; 109/109 exit 0 (spec check:skill-examples, check:dual-build-cjs-loads, check:i18n first exit 3, exit 0 after full turbo build exit 0); dispatch-gates --ran: 109 derived, 109 run, 0 NOT-MEASURED, 0 UNRUN. check-changeset-no-major with the PR body as event: exit 0 (widening arm, patch). check-closing-keyword-parity --body: exit 2 report mode, only Fixes #27462. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "relay only: pr_create #27533 (draft, no assignees, 17242 bytes read back identical), comment #27462 (this report); git push x1",
      "open_questions": [],
      "out_of_scope_findings": [],
      "deviations": [
        "Skills-docs: two governed hits named, not edited (skills/objectstack-data/rules/field-types.md:259, relationships.md:201 say ignored for count on a sum example; still true)",
        "ui vitest narrowed to the files the diff moves and their importers; CI Test UI runs the rest",
        "A probe event file /event.json (18 KB, the PR body as a pull_request payload) was written at the container root by a mistyped path; the removal was refused by the safety check, so it is left there. It is outside the repo and holds nothing secret."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

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

    Claim amendment: one declaration · domain:spec seat 3 · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-29T14:21Z · same claim 6492937618, same branch claude/project-thread-33w2eq

    • Metadata-protocol: added replaces none: a count rollup without summaryOperations.field is a newly accepted value. Under AGENTS.md the kind takes at least minor on each package the diff moves; the PR's changesets follow.
  5. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

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

    ACCEPT → PR #27533 comment 6501477737 (Tier H: awaiting an authorized approval, then the seat lands it)

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

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:specpm:dispatchedpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions