Skip to content

feat(console): a percent field with percentDisplay plain shows the percentage with no progress bar - #28315

Merged
objectstack-fleet[bot] merged 8 commits into
mainfrom
claude/project-thread-7n641c
Oct 31, 2026
Merged

objectstack-fleet[bot] merged 8 commits into
mainfrom
claude/project-thread-7n641c

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Fixes #28255

Refs #27973

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:百分比字段声明 percentDisplay: 'plain' 时,控制台只显示百分比数字,不再画进度条;列表、记录页字段、头部高亮、快速查看、相关列表、画廊卡片全部生效。字段设计器为 percent 字段新增 Bar / Plain 选项。
  • 为什么改:赢单概率、活动转化率这类数值是比率不是进度,画成进度条会误导;HotCRM 的 crm_opportunity.probability 和活动比率字段一直显示进度条。契约在 feat(spec): a percent field declares its read-only face, a progress bar or the plain percentage (percentDisplay) #28222 已声明,本 PR 补上渲染端。
  • 风险与回滚:只影响写了 plain 的字段;未写或写 bar 的字段显示不变。回滚即 revert 本 PR,无数据迁移。
  • 先看:① ui/packages/fields/src/index.tsx(PercentCellRenderer 的 plain 分支)② ui/packages/plugin-grid/src/objectGridGenerateColumns.tsx(三条列路径各复制一次)③ packages/spec/liveness/field.json(percentDisplay 行转 live)。
  • 两分钟验证:cd ui && pnpm exec vitest run packages/fields/src/__tests__/PercentCellRenderer.percentDisplay-28255.test.tsx,预期 5 个用例全绿(plain 无 progressbar,只有 25%)。
  • 需要你做的:无,席位落地。

What changes

  • The percent cell reads the key. PercentCellRenderer (ui/packages/fields/src/index.tsx) returns the formatted percentage alone when field.percentDisplay === 'plain'. Absent or bar keeps the bar, the renderer default the describe names. Storage (max), width (scale) and locale are read exactly as before, above the branch. Only the literal plain turns the bar off: the spec refuses any other value, so there is no second spelling to accept.
  • Every relay site copies it beside useGrouping — the same seven sites the useGrouping liveness row names:
    • ui/packages/plugin-grid/src/objectGridGenerateColumns.tsx — the three configured-column paths (ListColumn objects, string columns, inline rows with a fields projection);
    • ui/packages/plugin-detail/src/fieldEnrichment.ts — ENRICHED_FIELD_METADATA_KEYS, shared by DetailSection and HeaderHighlight;
    • ui/packages/plugin-detail/src/RecordDetailPanel.tsx (buildRecordDetailFields), ui/packages/plugin-detail/src/RelatedList.tsx (effectiveColumns), ui/packages/plugin-list/src/ObjectGallery.tsx (buildEnrichedField).
  • Spec rows the card names, nothing else in packages/spec:
    • field.form.ts gains the percentDisplay row: a select over bar / plain, visibleWhen: "data.type == 'percent'", no default, so an untouched row writes nothing.
    • The percentDisplay omit row in metadata-form-zod-reconciliation.test.ts (added by feat(spec): a percent field declares its read-only face, a progress bar or the plain percentage (percentDisplay) #28222) goes.
    • liveness/field.json: the row flips planned → live, with evidence (the renderer read) and producer naming the seven relay sites the way the useGrouping row does. The describe (and its TSDoc) drops the not-yet-read clause. Regenerated: content/docs/references/** (three pages, the describe) and liveness/state-counts/field.md (live 100 → 101, planned 9 → 8).
  • Changeset .changeset/28255-percent-display-plain.md, all patch.

Clause-② measured on the diff: no. The accepted set is unchanged (no schema edit; check:authorable-surface green), and the declaration surface is unchanged (check:api-surface green against an unmodified api-surface/; ENRICHED_FIELD_METADATA_KEYS is not exported from @object-ui/plugin-detail's entry). The form row offers a key the schema already accepted, and the liveness flip records a reader; neither widens what parses or what the package entries declare. Metadata-protocol: none: what an author can write and what it means are unchanged; the renderer now honours it.

  • Surface note, accepted by the seat: the new form row is a declared row, so its label and help text land in the platform-objects metadata-forms catalogs and pnpm check:i18n went red on it (7 bundles drifted). packages/platform-objects/src/apps/translations/{en,zh-CN,ja-JP,es-ES}.metadata-forms.generated.ts (+16 lines) are regenerated with node scripts/check-i18n-bundles.mjs --write, and the three translated locales are hand-translated, so no source-hash entry is left behind. That is the only file outside the order's surface.

Tests

  • ui/packages/fields/src/__tests__/PercentCellRenderer.percentDisplay-28255.test.tsx — plain draws no progressbar and prints 25%; plain keeps the declared storage and width (max: 100, scale: 1 → 33.3%); bar and absent keep the bar (control); a blank value is still the empty face.
  • ui/packages/plugin-grid/src/__tests__/gridPercentDisplay-28255.test.tsx — each of the three configured-column paths, plus the auto-generated columns as the reference face; a same-shape control field with no key keeps its bar.
  • ui/packages/plugin-detail/src/__tests__/percentDisplayRelay-28255.test.tsx — DetailSection and HeaderHighlight (the enrichment key list), RecordDetailPanel with no data source (the panel's own copy is the only road), RelatedList's cell bag; one control bar per surface.
  • ui/packages/plugin-list/src/__tests__/ObjectGallery.percentDisplay-28255.test.tsx — the gallery card.

Acceptance notes

  • The read is on the field, whatever its type: PercentCellRenderer also draws progress and textual fields promoted by format: 'percent'. The spec describes the key for percent, and the form row is gated to percent; a progress field that carried plain would also drop its bar. Not widened in the spec, not refused in the renderer.
  • The record History tab (ui/packages/app-shell/src/utils/auditHistoryDisplay.ts) also copies useGrouping, but it formats text only and never draws the percent cell or its bar, so it is not a percentDisplay relay site and is unchanged.
  • @object-ui/types' PercentFieldMetadata does not declare percentDisplay (it was outside the order's surface), so the grid, panel and related-list sites read it the way they read scale, through as any. Declaring it there (typed from SpecField['percentDisplay'], as NumberFieldMetadata.useGrouping is) would let those sites drop the casts.
  • The useGrouping liveness row's producer still names ui/packages/plugin-grid/src/ObjectGrid.tsx#generateColumns; the column builder now lives in objectGridGenerateColumns.tsx, which is what the new percentDisplay row names. The path still resolves, so check:liveness is green; noted, not touched.

Verification

The full readings below were taken at 7faff9ec (based on origin/main 6285203). Head 988c264c then merges seven newer main commits (clean; none touches ui/) and regenerates the three reference-doc pages the merge driver deferred (main's currencyConfig.homeAmount rows). Scoped re-checks at 988c264c: spec src/data/field src/system/metadata-form src/data/form 22 files / 692 tests passed, check:liveness, check:authorable-surface, check:api-surface, check:generated (14 of 14 current after --fix), check:i18n, check:i18n-stale-fill, check:nul-bytes, check:doc-authoring, check-changeset-no-major, check-sdui-manifest: all exit 0.

New pins and ablation (6 legs, each restored by blob hash)

node scripts/ablation-replace.mjs per leg, then the four new test files (cd ui && pnpm exec vitest run ...). All ui test imports resolve @object-ui/* from source, so no rebuild between legs.

Leg (mutation) Red Green kept
renderer: if (percentField.percentDisplay === 'plain') → if (false) 11 of 14 (every plain pin on every host) 3 (bar / absent / blank controls)
grid: the three (fieldMeta as any).percentDisplay = copies → void (--expect 3) 3 (each configured path) auto-generated columns, the reference face, as predicted
enrichment: 'percentDisplay' deleted from ENRICHED_FIELD_METADATA_KEYS 2 (DetailSection, HeaderHighlight) 12
panel: buildRecordDetailFields copy deleted 1 (RecordDetailPanel) 13
related list: cell-bag copy deleted 1 (RelatedList) 13
gallery: buildEnrichedField copy deleted 1 (ObjectGallery) 13

Each leg printed ok mutation landed: anchor N -> 0 and ok restored: blob == HEAD; git diff --quiet HEAD -- ui held after every leg.

Package tests and type-check
  • cd ui && pnpm exec vitest run --maxWorkers=2 packages/fields/ packages/plugin-grid/ packages/plugin-detail/ packages/plugin-list/ — Test Files 1074 passed | 2 skipped (1076), Tests 11502 passed | 25 skipped (11527) (lock VERDICT command-exit 0).
  • pnpm --filter @object-ui/fields --filter @object-ui/plugin-grid --filter @object-ui/plugin-detail --filter @object-ui/plugin-list run type-check — exit 0, each package's type-check echoed.
  • cd packages/spec && pnpm exec vitest run src/data/field src/system/metadata-form src/data/form — Test Files 22 passed (22), Tests 692 passed (692); pnpm check:liveness exit 0.
  • env -u OS_SKIP_DTS pnpm --filter @objectstack/spec build && pnpm --filter @objectstack/spec check:generated — 12 of 14 up to date, check:docs and check:liveness stale as expected; --fix regenerated exactly those two.
Derived gates: 109 derived, 109 run, 0 NOT-MEASURED

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack against this diff (109 families after the i18n commit added check:i18n-stale-fill), each line run with stdin redirected from /dev/null, exit codes recorded, reconciled with dispatch-gates.mjs --repo objectstack-ai/objectstack --ran: ✓ 109 derived famil(ies) accounted for — 109 run, 0 NOT-MEASURED. Every recorded exit is 0. Three first-pass non-zeros, each re-run green:

  • pnpm check:i18n exit 1 → the bundle drift above; regenerated and translated → exit 0.
  • node scripts/check-plugin-teardown-shape.mjs --self-test exit 3 (shallow clone could not read pinned commit 621a487) → fetched it → exit 0, 48 cases.
  • pnpm check:type-check-debt exit 3 (queue-timeout: the lock was held by this branch's own ui test run) → re-run under the lock → exit 0.

Prerequisites: a full platform build (env -u OS_SKIP_DTS pnpm turbo run build --filter='!@objectstack/docs' --filter='!@object-ui/*', 77 tasks) and the ui dependency closure (49 tasks), both exit 0.


Generated by Claude Code

…ntage with no bar

PercentCellRenderer reads the field's percentDisplay; the seven relay sites
that copy useGrouping onto a cell's field metadata copy it too. The field
form gains the percentDisplay row, its reconciliation omit row goes, and the
liveness row flips planned -> live.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibvqwtTGSkCm75Nci1s
…talogs

Regenerated with check-i18n-bundles --write; the zh-CN, ja-JP and es-ES
leaves are translated.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibvqwtTGSkCm75Nci1s
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/platform-objects, @objectstack/spec, touching 6 documentable anchor(s). ⚠️ 2 changed file(s) yielded no anchor (packages/spec/liveness/field.json, packages/spec/liveness/state-counts/field.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

11 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/concepts/metadata-driven.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/data-modeling/external-datasources.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/data-modeling/field-types.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/data-modeling/validation-rules.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/deployment/troubleshooting.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/deployment/validating-metadata.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/getting-started/quick-reference.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/kernel/contracts/data-engine.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/protocol/backward-compatibility.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/protocol/objectql/types.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/protocol/objectui/concept.mdx (via FieldSchema (symbol, a top-level const))

⛔ 2 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v17/17-0.mdx (via FieldSchema (symbol, a top-level const))
  • content/docs/releases/v17/17-1.mdx (via FieldSchema (symbol, a top-level const))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 2 changed file(s) yielded no anchor (packages/spec/liveness/field.json, packages/spec/liveness/state-counts/field.md) — pages documenting those are invisible to this run
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 59 of 211 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 168 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json b33946512c9f968432cb8b094961424220da4bc6 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 42918840ef4894eafe08af264663478167426bd1 — the merge of head 436f05ff83549684851d609a06962b8a92c09270 into base b33946512c9f968432cb8b094961424220da4bc6, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 42918840ef4894eafe08af264663478167426bd1 && git checkout 42918840ef4894eafe08af264663478167426bd1
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin b33946512c9f968432cb8b094961424220da4bc6 436f05ff83549684851d609a06962b8a92c09270 && git checkout -B drift-repro b33946512c9f968432cb8b094961424220da4bc6 && git merge --no-ff 436f05ff83549684851d609a06962b8a92c09270

node scripts/docs-audit/affected-docs.mjs --json b33946512c9f968432cb8b094961424220da4bc6

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs b33946512c9f968432cb8b094961424220da4bc6 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…edicate censuses

The platform-objects translated-label census (695 -> 696) and the lint
shipped-predicate census (89 -> 90, literal comparisons 64 -> 65) pin the
metadata form rows; the new percent-gated row is one more of each.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibvqwtTGSkCm75Nci1s
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract-review-claim: session_01L9qibw58ehQ2gRHP2h2Puz · head 436f05ff83549684851d609a06962b8a92c09270 · 2026-10-31T06:15Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 436f05ff83549684851d609a06962b8a92c09270
Local-runs: none
Scope: ui/packages/fields/src/index.tsx (PercentCellRenderer's plain branch), ui/packages/plugin-grid/src/objectGridGenerateColumns.tsx (the three configured-column copies), ui/packages/plugin-detail/src/fieldEnrichment.ts (ENRICHED_FIELD_METADATA_KEYS), ui/packages/plugin-detail/src/RecordDetailPanel.tsx (buildRecordDetailFields), ui/packages/plugin-detail/src/RelatedList.tsx (effectiveColumns), ui/packages/plugin-list/src/ObjectGallery.tsx (buildEnrichedField), packages/spec/src/data/field.zod.ts (the percentDisplay describe and TSDoc), packages/spec/src/data/field.form.ts (the percentDisplay row), packages/spec/src/system/metadata-form-zod-reconciliation.test.ts (the omit row removed), packages/spec/liveness/field.json (the row flipped live), packages/spec/liveness/state-counts/field.md, packages/platform-objects/src/apps/translations/*.metadata-forms.generated.ts (the four catalog entries), the three count pins (predicate census 89 to 90, literal comparisons 64 to 65, translated rows 695 to 696), the four new test files, the regenerated reference pages, .changeset/28255-percent-display-plain.md

Inputs: card #28255 (body; the claim of ui seat 1 and its surface), its parent #27973 (the spec half, #28222 merged), PR #28315 (body, the docs-drift comment, the file list of 25 files, the diff of 817 lines against main read whole, the eight commits from the merge-base b1e1dcf including the merge of main at 1bb1662 and the census pins at 436f05f), the 65 check-runs on this head (read 2026-10-31T06:21Z: all 65 runs completed, none failed, none cancelled, none in progress; success: Auto Label, Build & E2E UI, Build Core, Build Docs, Build UI Deps, Check Changeset, Check Documentation Links, Check PR Size, Dogfood Regression Gate, Flag docs affected by code changes, Governed Surface Queue Guard, Lint & Repo Gates, Lint UI, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · scoped · tooling self-tests, Live E2E UI, PR-body guards (claim · duplicate · Part-of · single-writer path), Plan Test Core shards, Spec property liveness, Test Core, Test Core (all 8), Test UI, Test UI (all 16), Type Check UI, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, TypeScript Type Check, filter; skipped: 18.x upgrade harness (opt-in), Dogfood Regression Gate (matrix shard/3), Dogfood Verify CLI, Packed-tarball smoke (opt-in), Schedule gate · skip when a green push run covers the commit, Temporal Conformance (live PG + MySQL), UI Published Artifacts), and the tree at this head for PercentCellRenderer (the branch sits after percentCellScale, formatPercent and the locale read, so the number under plain is the same number the bar face prints) and on main for the describe this PR narrows. The head is mergeable and clean against today's main (merge-tree clean); none of the files main moved since the merge-base is in this diff.

① Derived judgments

  • The renderer reads the key exactly as the describe says - right. Only the literal plain returns the formatted percentage alone (a tabular-nums span); absent or bar falls through to the existing bar face unchanged, and the storage (max), width (scale) and locale reads happen above the branch, so plain prints the same 33.3% the bar face would. The spec enum refuses any third value, so the renderer needs no second spelling. Pinned: plain no progressbar and 25%; plain with max: 100, scale: 1; bar keeps the bar; absent keeps the bar (control); blank stays the empty face.
  • Every relay site copies the key beside useGrouping - right, and the set is the one the useGrouping row names: the grid's three configured-column paths (copy-if-defined, as useGrouping), the detail enrichment key list (shared by DetailSection and HeaderHighlight), the record detail panel's own field builder, the related list's cell bag (spread-if-defined) and the gallery card. Each copy is guarded on !== undefined so an absent key writes nothing. Pinned per host with one control bar each; the ablation table shows each leg red on its own host only.
  • The spec rows: form row, describe, omit row, liveness - right. field.form.ts gains a select over bar / plain gated data.type == 'percent' with no default, so an untouched row writes nothing; the describe and TSDoc drop the "not read yet" clause and nothing else (the enum, optionality and the display-only sentence are unchanged); the percentDisplay omit row leaves the reconciliation ledger because the form now offers it; liveness/field.json flips planned to live with the renderer as evidence and the six relay files as producers; state-counts/field.md recounts live 100 to 101, planned 9 to 8, classified 110. Spec property liveness and check:liveness gate the row.
  • The three count pins and the catalog entries are what the form row costs - right. A declared row with a visibleWhen adds one predicate (89 to 90) and one literal comparison (64 to 65) to the metadata-form censuses, and one row to each locale catalog (695 to 696 translated rows); the four metadata-forms.generated.ts catalogs carry the label and help text, the three translated locales hand-written so no source-hash entry remains. These are the i18n-catalog cost every new spec form row pays (the lane's trap note from feat(spec): a percent field declares its read-only face, a progress bar or the plain percentage (percentDisplay) #28222).
  • Accept-set: nothing an author writes moves - right. No schema edit; check:authorable-surface and check:api-surface are in the check-run line. Clause-②: no and Metadata-protocol: none are right: the key parsed before and means what it meant; the renderer now honours it.
  • Check-runs as gate verdicts - read as above; every run on this head completed and none is red, cancelled or in progress at the read.

② Semver level

③ Boundary flags

④ Design judgment

  • Nothing blocking, no should-fix on the diff. Tried: a value above 1 with max absent (the bar face and the plain face share percentCellScale, so both read it as whole-stored); a header chip in a narrow container (the plain span keeps whitespace-nowrap, the Console: percent display renderer's fixed-width progress bar clips the value in a record-highlights chip (33% renders as 3) #5066 layout contract's point); a column configured as a string name (path B copies the key as path A does); a gallery card with no object definition (def undefined, nothing copied, the bar stays). One branch in one renderer, six copy sites that mirror an existing key's shape, and the pins per host: the smallest shape that reaches every read-only face.

Verdict reasoning. The renderer implements the describe as written with the number unchanged and the bar the default; every read-only host carries the key by the same relay the lane already accepted for useGrouping; the spec rows are the flip the spec half promised, with the census and catalog costs paid and pinned; the semver is patch everywhere; the head is clean against main and every check is green or skipped. What remains is the liveness-count overlap with #28322, named with the merged truth.

Implemented-by: claude/project-thread-7n641c
Reviewed-by: session_01L9qibw58ehQ2gRHP2h2Puz

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-tesla · session_01L9qibzC6RxMfB59EsgAoNN

席位核对

ACCEPT · seat domain:ui#1 · head 436f05ff · 2026-10-31T06:23Z

席位意见:百分比字段声明 percentDisplay: plain 后,表格、详情、相关列表、画廊和页头高亮现在只显示百分数,不再画进度条。数值和进度条那一面完全一致;没声明或声明 bar 的字段不受影响。Studio 的字段表单也新增了这个选项,只在百分比类型上出现。HotCRM 的概率、转化率这类字段可以改成纯数字显示了。

  1. Shape: Fixes #28255, Refs #27973, draft, base main, 25 files, +507/−27. Changes:
    • One plain branch in PercentCellRenderer.
    • Six relay sites copy the key beside useGrouping.
    • The field.form.ts row, plus removal of the reconciliation omit row.
    • The field.zod.ts describe/TSDoc trim.
    • The liveness field.json flip to live and the regenerated state-counts/field.md.
    • The four metadata-forms catalogs and three regenerated reference pages.
    • Two census pins (predicate 89 → 90 and literal comparisons 64 → 65; translated rows 695 → 696).
      All of this matches claim amendments 6538936278 and 6539153174.
  2. Seat read: the branch sits after the scale, format and locale reads, so plain prints the bar face's own number. The control (absent → bar) is pinned on every host, and the ablations were shown red on each relay site.
  3. Contract review: PASS at this head, record 6540032891 (CONTRACT_REVIEW_TIER), by the contract-review lane, not the drafter. No should-fix. Its boundary flags:
  4. Gates / check-runs: on 436f05ff: 65 completed, 0 failure. mergeable_state clean.
  5. Landing: check-governed-merges --pr 28315 reports NOT governed, 534 changed lines ≤ 3000. The seat readies the PR and arms auto-merge, on the maintainer's 「按 pm-dispatch 审过的pr你可以自主落地」 (seat thread, 2026-10-30T14:19Z).

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 31, 2026 06:24
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit 700ec85 Oct 31, 2026
66 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-7n641c branch October 31, 2026 06:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Percent field shows a plain percentage when percentDisplay is plain: PercentCellRenderer reads the key

1 participant