Skip to content

spec(data): field-scale.ts states that a server sum / avg over a no-fixed-width number does not yet carry its width, and the ruled end-state — ruling A (deferred) on objectui#11254 #21183

Closed

Description

@objectstack-fleet

Filed by the director seat, summon #32, session_016tKoy8NJa35Yih1FdzrVmn, as the one executable step of the maintainer's ruling A (deferred) on objectstack-ai/objectui#11254 Q1. The ruling is batch #261 item 4, maintainer 「其他四张同意」; the record is the Ruling: comment on objectui#11254. ⛔ Not a claim.

What was ruled

  • The end-state (A). For a sum / avg over a number field with no declared scale, the analytics result reports the width. Its column metadata carries the widest decimal count among the values the server read, or the field's declared scale when there is one. The object-metric tile rounds to that. This is the party that sees the inputs reporting the width (contract-first).
  • Deferred. Nothing is built now. The trigger is the first first-party producer: an object-metric tile or dataset measure doing sum / avg over a number that declares no scale and whose author wrote no format. Then A is built in one go, with no new decision card.
  • Until then. The tile keeps its whole-number pattern for that one case (objectui packages/plugin-dashboard/src/ObjectMetricWidget.tsx:354 on main 8001068b9c). The protocol must not claim more than the runtime delivers: that is this card.

The defect this card fixes in the protocol text

packages/spec/src/data/field-scale.ts:59-71 (spec main d34aa58a2a) states ruling A′ as protocol: "a computed result over a no-fixed-width column rounds to the widest decimal count among the values that entered it — derived from the data, ⛔ never a constant".

Scope

  1. In field-scale.ts, the A′ paragraph states the server-aggregate exception, at the same place and in the same voice:
    • which computed results the rule binds today;
    • that a server sum / avg over a no-fixed-width number still shows a whole number;
    • the ruled end-state (the analytics result reports the width) and the trigger above;
    • the two declared channels an author has today: a field scale, or a tile format.
  2. ⛔ No schema change, no new key, no runtime change. Clause-②: no. A patch changeset, since the docblock ships in the published types.

Lane

domain:spec, level S, mode:subagent. The same-family display carriers (the gantt tooltip's number row, NumberCellRenderer) stay on objectui#11254, in domain:ui.

Dedupe

mcp__github__search_issues, repo-scoped, open and closed, 「field-scale computed result server aggregate width analytics column metadata scale」 → 8 hits, all closed. The nearest is #20241, a stale grid description in the same docblock, already fixed. None records the server-aggregate gap.

Dedupe words: field-scale server aggregate width · A prime metric tile sum avg · analytics column width


Generated by Claude Code

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    domain:specDomain lane — seat card indexed by label:pm:seat
    area:reportsBusiness reporting — dashboards, reports, the numbers a manager reads
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 1, 2026
  2. objectstack-fleet commented on Oct 2, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01UtnxvdiN376GF3sgXwAw4d
    Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-21183-field-scale-server-aggregate
    Worktree: objectstack-issue-21183
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface: on origin/main d7d5b4f96a. packages/spec/src/data/field-scale.ts: the A′ paragraph of the module docblock (about :59-79) states the server-aggregate exception in its own voice, per the card's scope and the ruling A (deferred) it records on objectstack-ai/objectui#11254. It says which computed results the rule binds today, that a server sum / avg over a no-fixed-width number still shows a whole number, the ruled end-state and its trigger, and the two declared channels today (a field scale, a tile format). Plus any generated reference page that lifts the docblock (none found by git grep), and one @objectstack/spec patch changeset. ⛔ No schema change, no new key, no runtime change. Stop on breach; explain in the report.
    Container & model: S, mode:subagent, model: opus (default build tier; packages/spec/src/** non-test, so the contract review runs at CONTRACT_REVIEW_TIER through an isolated subagent)
    Clause-②: no
    Thread-read: none
    Serial constraints cleared: at 2026-10-02T17:22Z, no open PR and no in-flight claim touches packages/spec/src/data/field-scale.ts. #21000 (this seat, in flight) edits packages/spec/src/data/analytics.zod.ts and service-analytics, not this file.

  3. objectstack-fleet commented on Oct 2, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 21183,
      "status": "done",
      "branch": "claude/issue-21183-field-scale-server-aggregate",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/21449",
      "session": "session_01UtnxvdiN376GF3sgXwAw4d — this run's harness-stamped id (subagent = parent's); identity record = claim comment 5957645758, whose newest (and only) Claim: names this branch, verified before any edit",
      "premise_still_valid": true,
      "summary": "The A′ paragraph of packages/spec/src/data/field-scale.ts was rewritten in place, in its own voice. It now says four things. (1) The widest-decimal rule binds today only results whose inputs the renderer sees: the grid summary footer, and the object-metric tile's min / max. (2) A server sum / avg over a number with no declared scale does not get that width, because the tile receives one number and AnalyticsResultResponseSchema's column metadata has no width. Measured at .objectui-sha pin 89cad75d5570, the object-metric tile shows that answer as a whole number, and the dataset-bound tile with no measure format rounds it to at most two decimals. (3) The ruled end-state A (the analytics result reports the width) and its trigger. (4) The two declared channels today: a field scale, or a format. The diff is comment-only: no schema, key, export or runtime change. Two things differ from the dispatch and the card, and both are measured. First, there is NO patch changeset and the PR carries skip-changeset, because the module docblock ships in no published file (see deviations). Second, the card's \"still shows a whole number\" holds on the object-metric tile only. The docblock states what each face does at the pin.",
      "tests": "Head 97a757c216. (1) pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2, under os-verify-lock (VERDICT command-exit 0): \"Test Files 600 passed (600) / Tests 17684 passed | 1 todo\". (2) src/data/field-scale.test.ts alone: 13 passed. (3) pnpm --filter @objectstack/spec run typecheck: VERDICT command-exit 0; check:test-typecheck OK, with 52 files / 246 errors / 135 pinned signatures held. (4) pnpm --filter @objectstack/spec build: exit 0, check-dts-emitted 38/38. (5) check:generated: \"All 15 generated artifacts are up to date\". It was taken on 80ae4f4cb3; 97a757c216 changes only .changeset/, and check:docs, check:api-surface and check:authorable-surface re-ran green on 97a757c216. (6) eslint, narrowed: eslint --no-inline-config --format json packages/spec/src/data/field-scale.ts reports 1 file, 0 errors, 0 warnings. The population is read from eslint (isPathIgnored false for the only changed file). Invariance: the parserOptions resolved for the file are ecmaVersion / sourceType only, with no project, so no type-aware linting runs. (7) Shipping measurement, after the build, by grep over every path in spec files[]: the new text \"binds TODAY\" hits 0 files; the module docblock that was already there (\"What an ABSENT\", \"Why a resolver and not a Zod default\") hits 0 files; the positive control, resolveFieldScale's TSDoc \"The decimal places this field displays\", hits 2 files (dist/data/index.d.ts, dist/data/index.d.mts). (8) No ablation or reverse verification: the diff is comment-only, with no behaviour to reverse.",
      "mcp_calls": "0 — no MCP GitHub tool was called",
      "api_writes": "3 relay strokes. Each was a POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write as objectstack-fleet[bot], and together they carried 4 endpoint writes: (1) POST /repos/objectstack-ai/objectstack/pulls (pr_create, draft #21449; read back identical, 8692 bytes); (2) POST /repos/objectstack-ai/objectstack/issues/21449/labels (skip-changeset) and (3) POST /repos/objectstack-ai/objectstack/issues/21449/assignees (os-sales), both in one label-write call, read back as matching; (4) POST /repos/objectstack-ai/objectstack/issues/21183/comments (this os-dev-report). There were also 3 git pushes, which are not REST writes. Everything else was a read: gh api on the card, its comments, the ruling comment, objectui PR 11375 and the PR read-back.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed (it is in the PR #21449 Acceptance notes). The dataset-bound tile (objectui DatasetWidget, then formatMeasure in @object-ui/core dataset-format.ts, at pin 89cad75d5570) rounds a min / max over a no-fixed-width number with no measure format to at most two decimals, not to the answer's own decimal count. So A′'s min / max reading holds on the object-metric tile only. There is no first-party producer: no example dataset or metric aggregates min / max (git grep on d7d5b4f96a). The ruled end-state A (a width on the analytics column) would cover this face. Dedupe words: dataset metric min max decimals · formatMeasure no format width · A prime dataset face"
      ],
      "gates": "Head 97a757c216. node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (no paths) derived 73 commands. All 73 ran and 72 exited 0. One is NOT MEASURED: pnpm check:dual-build-cjs-loads exited 3, PREREQUISITE NOT MET, because it needs the whole workspace built (pnpm build). That does not fit the foreground budget, so it is declared to CI. Invariance: the diff reaches no emitted file. --ran reconciliation: \"73 derived, 72 run, 1 NOT-MEASURED, 0 UNRUN\" (exit 0). The seat's 79-command derivation was also run in full on 80ae4f4cb3, while the changeset was still in the diff, and it is identical to this tool's re-derivation on that head: 76 exited 0 on the first pass and 3 exited 3. check:doc-formula-expressions and check:lean-entry-closure went green after @objectstack/formula, @objectstack/lint and @objectstack/objectql were built; dual-build-cjs-loads stays NOT MEASURED. Gates named in the dispatch: check:objectui-pin-citations green (49 asserting citations match .objectui-sha, 73 historical recorded); check:docs green; check:generated green; check:nul-bytes green.",
      "line_budget": "n/a. No skills/** or line-ratcheted file is touched. The diff is +25 / -1 in one file, 26 changed lines against the human-merge threshold of 5000.",
      "deviations": [
        "Changeset. Dispatch Zone 1 and the card asked for one @objectstack/spec patch changeset, \"since the docblock ships in the published types\". Measured after building spec, the module docblock ships in no path of spec's files[]: field-scale.ts is not a *.zod.ts file, and the docblock is attached to no exported declaration. The grep counts and the positive control are under tests. The os-dev definition counts as published only what files[] ships, and it wins over a dispatch on conflict; AGENTS.md Post-Task step 3 also reserves skip-changeset for a diff that publishes nothing. So the changeset written in 80ae4f4cb3 was removed in 97a757c216, and skip-changeset went on in the same label-write call as the PR assignee. Reversal: restore .changeset/21183-field-scale-server-aggregate-width.md from 80ae4f4cb3 and remove the label.",
        "Card premise, in part. Its \"a server sum / avg ... still shows a whole number\" holds at pin 89cad75d5570 on the object-metric tile only (ObjectMetricWidget.tsx inferredFormat answers '0,0' at line 354, the same line the card cites on 8001068b9c). With no measure format, the dataset-bound tile prints an integer as it is and rounds any other value to at most two decimals. A field scale never reaches that tile: service-analytics copies only the measure format into the column metadata. The docblock states each face as the pin does. objectui PR #11375 (merge b149617e6f) IS an ancestor of the pin, by git merge-base --is-ancestor exit 0.",
        "objectui sibling checkout. The first ancestry reading (exit 1) was taken on a shallow clone, with the merge commit below the shallow boundary, so it proved nothing. The pin was fetched with --deepen=150 into a private ref, refs/os-dev/issue-21183/pin, which was read and then deleted. This grew objectui's object store and .git/shallow and rewrote its primary checkout's FETCH_HEAD. No branch, remote-tracking ref or working tree was touched.",
        "No merge of origin/main before the PR. Three commits landed after base d7d5b4f96a: 535d1d25ab, b79301000c and 53fd35e3e3. git diff --stat from the base to origin/main over field-scale.ts, api/analytics.zod.ts and .objectui-sha is empty. The merge queue rebuilds on current main."
      ],
      "files_changed": [
        "packages/spec/src/data/field-scale.ts"
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 2, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #21449 @ 97a757c216

    domain:spec seat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim 5957645758 · 2026-10-02T18:34Z

    • Shape (read on GitHub): a draft against main. The first line is Fixes #21183, then Clause-②: no. PR assignee os-sales, label skip-changeset. The branch's delta against main is 1 file, +25 / -1: the A′ paragraph of packages/spec/src/data/field-scale.ts's module docblock, all comment lines. No governed path.

    • Review: at-tier PASS 5958810461 on this head. Its findings:

      • No accept-set or surface change.
      • Each sentence is true at .objectui-sha pin 89cad75d5570 and on main:
        • the widest-decimal rule binds today only the grid summary footer and the object-metric tile's min / max;
        • a server sum / avg over an undeclared-scale number gets no width, because AnalyticsResultResponseSchema's column metadata carries none and service-analytics copies only the measure format;
        • each tile's behaviour is stated as the pin does it;
        • ruled end-state A and its trigger are in the ruling's own words;
        • a field scale is said to reach only the face it reaches.
    • skip-changeset, confirmed by that same-head PASS. The card's premise that "the docblock ships in the published types" is false, on three readings:

      • files[] ships src/**/*.zod.ts only, and field-scale.ts is not one;
      • the build drops sourcesContent;
      • the published @objectstack/spec@17.6.0 tarball carries none of this module docblock's text, while it does carry the exported resolveFieldScale TSDoc.

      The diff publishes nothing from any released package, which is the case AGENTS.md reserves skip-changeset for.

    • Card premise, in part (the dev's measured correction): "still shows a whole number" holds on the object-metric tile only. The dataset-bound tile rounds to at most two decimals. The docblock states each face, without departing from ruling 5933283974.

    • Gates on this head: 39 check-runs: 32 success, 7 skipped, none failed and none pending. check-expected-skips: OK. check-governed-merges --pr 21449: NOT governed, 26 changed lines. mergeable_state: clean. A local git merge-tree against origin/main 53fd35e3e3 merges without conflict. No main commit since the merge base touches the file, and no open PR touches it.

    • Out-of-scope finding: the dataset-bound tile's min / max also round to a constant two decimals with no measure format. That is an A′ gap of ruling 5933283974 Q2's family, with no first-party producer, and it is covered by end-state A once built. Recorded beside Q2 on plugin-dashboard: ObjectMetricWidget formats a number or percent aggregate with an inferred 0,0 / 0,0% pattern and never reads the resolved width, the metric half of ruling A′ (objectstack#19628) left open by objectui#9843 objectui#11254 (5958830649), so it is findable where its family lives; not filed as a card.

    Landing: ready, then auto-merge through the merge queue.

  5. objectstack-fleet commented on Oct 2, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #21449 → b94a2a7277

    domain:spec seat 1 (session_01UtnxvdiN376GF3sgXwAw4d), holder of claim 5957645758 · 2026-10-02T19:03Z

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:reportsBusiness reporting — dashboards, reports, the numbers a manager readsdomain:specDomain lane — seat card indexed by label:pm:seatpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions