Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

finding(plugin-grid): NumberCellRenderer and GridField.computeRow hit the SAME unguarded ceiling objectui#9808 fixed #10071

Closed

Description

@os-steve

Path: P2 | 那条路第 2 步「本地跑起来、看到」 | 合规元数据的 scale 越界在两处未设防点抛 RangeError,格子/网格编辑当场断
分诊重测与定级:2026-09-20T15:01Z

Filed by the domain:spec @ objectui execution seat, session session_01QVJUngS9FKfuyQ9NFR2Nbn, 2026-09-20. ⛔ Not graded and ⛔ not routed — domain:*, type and priority:* are the triage seat's sole production.

⚠️ Provenance: measured by the PREDECESSOR seat (hotlong, session_01UanLVj6xvbS6puBCewLr8L) and parked in seat post #5734's 欠账 table — that session's write classifier refused POST /issues, so 14 measured findings were drafted and never filed. This seat's token permits POST, so they are filed now.

✅ Re-measured at source by the triage seat on today's origin/main, with a lit control — the claim below is CONFIRMED. The measurement is in the triage comment on this card; where it differs from the inherited wording, ⛔ the comment governs and this paragraph does not.

The claim

objectui#9808 fixed an unguarded numeric ceiling (a RangeError reachable from authored metadata). The predecessor measured the identical unguarded shape at two further sites: NumberCellRenderer and GridField.computeRow.

⇒ the fix landed at one site; these two were never covered.

What triage should settle

Whether the reading still holds at source on today's origin/main, with a lit control on the same instrument so a zero is an absence the instrument could have seen.

Dedupe words: NumberCellRenderer scale RangeError · GridField computeRow ceiling · 9808 unguarded toFixed

Blocked-by: #10229


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Re-measurement at source, replacing the deleted triage comment

    domain:spec @ objectui execution seat · session session_01877XiBYSaRCk2CU7cMSg3S · 2026-09-24T05:45Z · objectui origin/main 62597c5 · read with git show / git grep on origin/main, never the working tree. Maintainer instruction in this seat's session, verbatim: 「这些卡你自己分析和排查一下」.

    ⚠️ The clone is shallow: its oldest commit is 8ed4b95 at 2026-09-20T12:48Z, so commits between filing and that instant are not visible. ⛔ Grading and routing stay with the triage seat; this comment supplies evidence only.

    Verdict: CONFIRMED. The claim is a user-reachable crash from metadata the installed contract accepts.

    • packages/fields/src/index.tsx:767-774 (NumberCellRenderer) passes minimumFractionDigits: scale ?? 0, maximumFractionDigits: scale ?? 20 to formatDisplayNumber with no clamp. The catch in packages/core/src/utils/number-display.ts:198-204 only retries without the locale, using the same digits.
    • packages/fields/src/widgets/GridField.tsx:321-322 computeRow does Number(v.toFixed(scale)) with no clamp.
    • Engine check (node 22): (1).toFixed(101) throws RangeError, and Intl with 101 fraction digits throws too.
    • Lit control: the objectui#9808 guard (renderablePercentScale / PERCENT_SCALE_CEILING = 100, widgets/percent-scale.ts:146,156) is used only by formatPercent (index.tsx:26,660) and PercentField. The same grep finds it at neither of the two sites above.
    • Contract: the lockfile pins @objectstack/spec@17.4.0, which accepts scale: 101 (recorded at percent-scale.ts:27-43). The spec source bounds it at 100 (data/field.zod.ts:931,1230), but that is the unconsumed changeset 18972-field-scale-renderer-ceiling.md, which names these two readers. packages/types field-types.ts:409,448 declares scale?: number with no bound.
    • Fix surface: those two sites, reusing the percent-scale clamp-and-report. Clause-②: no, because a clamp narrows. Size S.

    Generated by Claude Code

  2. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 2 — objectui#10071, clamp the two unguarded scale sites
    Session: session_01877XiBYSaRCk2CU7cMSg3S
    Branch: claude/issue-10071-number-scale-ceiling
    Worktree: objectui-issue-10071
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: packages/fields/src/index.tsx (NumberCellRenderer), packages/fields/src/widgets/GridField.tsx (computeRow only), packages/fields/src/widgets/percent-scale.ts if the clamp is shared from there, their __tests__, one .changeset/10071-…md (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus (TIER_DEFAULT; dispatch-gates --tier refuses objectui paths from an objectstack checkout, so the tier is this seat's explicit per-card call)
    Clause-②: no
    Thread-read: 5808431037
    Serial constraints cleared: objectui#9909 (domain:ui, claimed at 2026-09-24T05:43Z) lists packages/fields/src/widgets/GridField.tsx for its machine-locale sites (:356-430, :832, :1227 on 62597c5). This card touches only computeRow :321-322 there, so the regions are disjoint but the file is shared, and whichever lands second resolves the conflict. No open PR touches packages/fields/src/index.tsx (5 open PRs read at 2026-09-24T05:54Z). #8071's plugin-grid PR objectui#9924 closed at 2026-09-20T09:32Z.

    Governing measurement: re-measure comment 5808431037 on this card (objectui 62597c5).

  3. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 10071,
      "status": "done",
      "branch": "claude/issue-10071-number-scale-ceiling",
      "pr": "https://github.com/objectstack-ai/objectui/pull/10227",
      "session": "session_01877XiBYSaRCk2CU7cMSg3S (subagent, parent's id)",
      "premise_still_valid": true,
      "summary": "NumberCellRenderer and GridField computeRow now clamp a declared scale above 100 (accepted by the installed @objectstack/spec 17.4.0, refused by Intl and toFixed) to 100 and warn once, reusing the objectui#9808 ruling. percent-scale.ts (module-private, not in the barrel) gains renderableFractionScale(declared, face, card), and renderablePercentScale delegates to it, so the percent diagnostic is byte-identical. No new published export (Clause-2 no holds). The 9808 SUNSET failure message now names every importer instead of two call sites. Assignee was already set (os-bill). The newest Claim (5808522661) names this branch. origin/main was still 62597c5 at the merge, and objectui#9909 has not landed.",
      "mechanism_assumptions": {
        "A1_number_cell": "CONFIRMED. On 62597c5 the NumberCellRenderer passes scale unclamped as min/maxFractionDigits. The formatDisplayNumber catch retries with the same intlOptions. Base pin: RangeError minimumFractionDigits value is out of range.",
        "A2_computeRow": "CONFIRMED. computeRow does Number(v.toFixed(scale)) unclamped. Base pin: RangeError toFixed() digits argument must be between 0 and 100. Producer: plugin-form deriveColumns/hydrateColumns copy a child field's scale when it carries an expression.",
        "A3_guard_reach": "CONFIRMED. A grep for renderablePercentScale/PERCENT_SCALE_CEILING in packages/*/src finds only PercentField and formatPercent. The survey grep for scale-driven toFixed/FractionDigits hit exactly the two unguarded sites plus the PercentField toFixed sites (positive control, already guarded).",
        "A4_contract": "CONFIRMED. The installed spec 17.4.0 FieldSchema.safeParse accepts number/currency with scale 101 (with and without expression). The strict-door control is lit: an unknown key is refused by name. objectstack origin/main b7c792b has .changeset/18972-field-scale-renderer-ceiling.md, which names both readers."
      },
      "tests": "Base red at BASE 62597c5, fix absent, new pin present: 'Tests 4 failed | 8 passed (12)'. The 4 failures are the RangeErrors above. The 8 lit controls are in-range, ceiling-inclusive, currency default, negative width, and the spec-door controls. The fix was committed at 5a5911e before the green runs. pnpm exec vitest run packages/fields/ at 5a5911e: 'Test Files 176 passed (176) Tests 2988 passed (2988)', lock VERDICT command-exit 0. Final head 2302cbe (the only later change is a test-only any-to-never cast): 5 files (the 10071 pin, the 9808 pin, NumberCellRenderer.test, NumberCellRenderer.grouping.test, GridField.test): 'Test Files 5 passed (5) Tests 99 passed (99)', VERDICT command-exit 0. A separate ablation was not run. The base-red run is the before leg, on the same instrument and the same committed pin file.",
      "gates": {
        "install": "pnpm install exit 0",
        "build_closure": "pnpm --workspace-concurrency=2 --filter '@object-ui/fields^...' build, VERDICT command-exit 0",
        "type_check": "pnpm --filter @object-ui/fields type-check, VERDICT command-exit 0. The first attempt exited 2 with TS2307 on unbuilt workspace deps, a prerequisite miss and not a measurement. tsc -p tsconfig.test.json --listFiles includes both pin files.",
        "eslint": "eslint on 5 changed ts/tsx files: exit 0, 0 errors. The new test file and percent-scale.ts have 0 warnings. The remaining warnings are pre-existing in index.tsx/GridField.tsx. This is a narrowing, not the repo-wide lint (CI owns that).",
        "check:new-line-citations": "exit 0, 'VERDICT new-cross-file-line-citations: 0 new citation(s)'",
        "check:control-bytes": "exit 0",
        "check:self-import": "exit 0",
        "check:pending-changeset-literals": "exit 0",
        "check:changeset-claims": "exit 0, report-only. It flags pending changesets 6625/6694/6837/7166 that name the edited files. I read them, and none is falsified: .scale is still read in both files.",
        "changeset-presence": "node scripts/check-changeset-presence.mjs exit 0, 1 changeset declared",
        "core": "not touched, so no core run",
        "ci": "in_progress, not awaited, per contract"
      },
      "line_budget": "n/a (no skills/** or governed surface touched)",
      "files_changed": [
        "packages/fields/src/index.tsx",
        "packages/fields/src/widgets/GridField.tsx",
        "packages/fields/src/widgets/percent-scale.ts",
        "packages/fields/src/__tests__/NumberScaleOutOfRange-10071.test.tsx",
        "packages/fields/src/__tests__/PercentScaleOutOfRange-9808.test.tsx",
        ".changeset/10071-number-scale-ceiling.md"
      ],
      "deviations": [
        "File surface: I also edited PercentScaleOutOfRange-9808.test.tsx, but only the SUNSET failure-message string. Its 'two call sites' would have become false once the module gained number-face importers. It is a test of the shared module, within 'their tests'.",
        "Labels: zero writes. The dispatch named no labels, and objectui skip-changeset has no readers."
      ],
      "mcp_calls": "0",
      "api_writes": "2 relay writes plus git push: (1) pr_create via fleet-write dispatch (POST /repos/objectstack-ai/objectstack/dispatches, run 35963728948, executing POST /repos/objectstack-ai/objectui/pulls, draft), which created PR 10227; (2) this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectui/issues/10071/comments). git push to origin twice (branch probe and commits), not REST.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    ACCEPT: objectui#10071, delivered by PR objectui#10227 at head 2302cbe0b8e7e2fcc4a8487732656a4ccf2e9791. Reviewed 2026-09-24T06:19Z by session session_01877XiBYSaRCk2CU7cMSg3S.

    Implemented-by: claude/issue-10071-number-scale-ceiling (os-dev report 5808825869)
    Reviewed-by: domain:spec @ objectui seat, against GitHub, not against the report

    check reading
    PR shape open, draft, base main, body line 1 Fixes #10071, no other card number beside a closing keyword
    scope (/pulls/10227/files) 6 files: fields/src/index.tsx (+8 −2), widgets/GridField.tsx (+6 −1, computeRow only, so it does not touch objectui#9909's :356-430 region), widgets/percent-scale.ts (+31 −9), two tests, one changeset (@object-ui/fields: patch). Nothing outside the claimed surface. The 9808 test edit is a failure-message string only, and the report declares it
    Clause-② no confirmed: renderableFractionScale is exported from percent-scale.ts, which the index.tsx export * block never names. GridField.js is re-exported, but it only imports the helper
    diff both sites route the declared width through the #9808 clamp (ceiling 100, warn once per face and width). renderablePercentScale delegates, so its diagnostic is byte-identical. Negative and non-integer widths keep their existing path
    tests base-red leg on 62597c5: 4 RangeErrors, 8 lit controls green. Fix head: packages/fields 176 files / 2988 tests pass (at 5a5911e). The final head 2302cbe is a test-only cast, with 5 files / 99 tests re-run
    CI at 2302cbe 42 runs, read at 2026-09-24T06:19Z: 23 success · 3 skipped (coverage matrix placeholders, dependabot) · 16 in progress. ⛔ Not yet green, so the landing waits for convergence on this head

    Deviations: none beyond the declared test-string edit. mcp_calls 0; writes were pr_create and one report comment via the relay.

    Next: when every check on 2302cbe is green or an expected skip, flip ready and enqueue. ⚠️ Relay automerge_enable lacks permission (seat post §④), so enqueueing may need a maintainer click.

  5. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    State: pm:dispatched → pm:blocked at 2026-09-24T06:47Z. Session session_01877XiBYSaRCk2CU7cMSg3S.

    The work is done and accepted (PR objectui#10227). Every check on its head is green or an expected skip, except Spec Main Shape Gate. That gate is red on every objectui PR right now, because of upstream drift from objectstack main (anchor objectui#10229, untriaged at this reading). This is the external-gate case of pm:blocked: the assignee stays, and this seat follows the PR to MERGED.

    Blocked-by: #10229
    Unlock-action: re-check PR #10227


    Generated by Claude Code

  6. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    State: pm:blocked → pm:dispatched at 2026-09-24T12:43Z. Session session_01877XiBYSaRCk2CU7cMSg3S.

    Blocked-by: objectstack-ai/objectui#10229 is discharged. The fix, PR objectui#10238, merged into main as f4f1f45. main was merged into PR objectui#10227's branch (merge-only commit 0455efc; nothing was rebased or force-pushed), so its Spec Main Shape Gate re-runs against the fixed gate.

    Next: when every check on the new head is green or an expected skip, flip ready and enqueue. The earlier ACCEPT stands; a merge of main does not change the reviewed diff.


    Generated by Claude Code

  7. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Enqueued: PR objectui#10227 is ready and in the merge queue as of 2026-09-24T12:56Z (ready_for_review, then added_to_merge_queue, read from the PR timeline). Session session_01877XiBYSaRCk2CU7cMSg3S.

    Head 0455efc shows 43 check runs: 40 success, 3 expected skips (Test (coverage), the unexpanded coverage-shard placeholder, dependabot). Spec Main Shape Gate is green against the gate fixed in objectui#10238. The paths are not governed (six files in packages/fields and .changeset, 268 lines), and Clause-②: no. This seat follows the PR to MERGED.


    Generated by Claude Code

  8. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Landed: PR objectui#10227 merged as 0361d6b, verified by content on objectui origin/main at 2026-09-24T13:07Z, not from the merge flag. renderableFractionScale appears in packages/fields/src/index.tsx (2) and packages/fields/src/widgets/GridField.tsx (2). Lit control: renderablePercentScale in index.tsx (2). The card was closed by Fixes. pm:dispatched is removed in this act (a closed card carries no pm state label), and the assignee stays as the record. Session session_01877XiBYSaRCk2CU7cMSg3S.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanepriority:p2

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions