You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
spec/Studio: a count rollup cannot be saved without summaryOperations.field, which the spec itself says is ignored for count #27462
Filing gate: ① a product defect found by a QA run (off-clause probe, RUNNER rule 8).
Reproduction
As in the summary-field authoring setup (writable package, parent and child objects), add a Rollup field in Studio Data → parent → Form.
Choose Child object = the child and Aggregation "Count — child records". Leave "Child field to aggregate" empty, since a count needs none.
Expected: the count rollup saves. The spec's own description of summaryOperations.field says it is ignored for count.
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
Read fresh. The schema refuses a count rollup without summaryOperations.field, but the spec's own describe says that field is ignored for count. From the 18.3.0 RC run ([sweep] v18.3.0 release test sweep #27377 §5); it is retested on the next wave.
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/main273137d2: 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
{
"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."
]
}
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.
Activity
objectstack-fleet commentedon Oct 29, 2026
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.
summaryOperations.field, but the spec's own describe says that field is ignored for count. From the 18.3.0 RC run ([sweep] v18.3.0 release test sweep #27377 §5); it is retested on the next wave.fieldoptional whenfunction: 'count'widens the accept set:Clause-②: yes (widening), aSkills-docs:line, and a contract review before approval (pm-dispatch(contract-review): a seat sends a PR to the maintainer for approval only after a contract PASS on the current head, and a PR that landed still owing one is re-reviewed after landing, with each finding filed as a new card #27345).bug,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:spec#3 · os-support-ai · session_01WGufzgbJhFoXYsLSe5WSPP
Claim: PM loop round 3 · 2026-10-29T09:24Z
Session:
session_01WGufzgbJhFoXYsLSe5WSPPAccount:
os-support-aiBranch:
claude/project-thread-33w2eq(card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead ofclaude/issue-27462-<slug>)Worktree:
objectstack-27462Domain:
domain:specSeat:
domain:spec#3Ruling-ref: seat ruling: the spec follows its own describe.
summaryOperations.fieldbecomes optional whenfunctioniscountand stays required for every other function, refused with a prescription; Studio does not fill an arbitrary fieldFile surface:
summaryOperationsinpackages/spec/src/data/field.zod.tsand its describe, every reader ofsummaryOperations.fieldthat 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: highClause-②: yes (widening)
Metadata-protocol: none
Responsibility: an unclaimed p2
domain:speccard; seat 1 told through the coordinatorThread-read: 6491275416
Premise: to be measured first by the dev on
origin/main273137d2: a count rollup with nosummaryOperations.fieldis refused (422 at the metadata write door) although the describe saysfieldis ignored for countSerial constraints cleared: no open PR on these files that the seat knows of; the dev re-checks before editing
objectstack-fleet commentedon Oct 29, 2026
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
objectstack-fleet commentedon Oct 29, 2026
domain:spec#3 · os-support-ai · session_01WGufzgbJhFoXYsLSe5WSPP
Claim amendment: one declaration ·
domain:specseat 3 · sessionsession_01WGufzgbJhFoXYsLSe5WSPP· 2026-10-29T14:21Z · same claim 6492937618, same branchclaude/project-thread-33w2eqMetadata-protocol: addedreplacesnone: a count rollup withoutsummaryOperations.fieldis a newly accepted value. Under AGENTS.md the kind takes at leastminoron each package the diff moves; the PR's changesets follow.objectstack-fleet commentedon Oct 29, 2026
domain:spec#3 · os-support-ai · session_01WGufzgbJhFoXYsLSe5WSPP
ACCEPT → PR #27533 comment 6501477737 (Tier H: awaiting an authorized approval, then the seat lands it)