Repository navigation
Commit 35b178b
docs(skills): the data skill's percent row states the storage scale — a fraction unless the field declares max above 1 (#28513)
<!-- claude-projects-attribution: {"github_login":"os-tesla"} -->
_Requested by **Tesla** · [project
thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6Jao1GXHCbqC69qQauk9Qizcus)_
Fixes #28489
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:objectstack-data 技能字段类型表的 `percent` 行,把「Percentage values
(0-100)」改成平台真正的存储规则:不声明 `max` 大于 1 时存 0-1 的小数,声明了(如 `max:
100`)才存整数百分点;种子、默认值、API 写入都按这个存储刻度。
- 为什么改:发布出去的技能说错了一句,AI 作者照着在没有 `max` 的 percent 字段上种 `25`,界面读出来是
`2500%`(#28487 契约复审发现,triage 定 p2)。
- 风险与回滚:纯文档;技能文件 token 上限余量为 1,新增以删除 `Vector (AI Embeddings)`
示例支付(它唯一的事实「`dimensions` 是平级键」Enhanced Types 表行已写明);回滚即 revert。
- 先看:`skills/objectstack-data/rules/field-types.md` 第 54 行(`percent`
行)与被删的 Vector 示例块,`.changeset/28489-percent-storage-scale-skill.md`。
- 两分钟验证:`node scripts/check-skills-token-ratchet.mjs`,预期退出
0,`field-types.md` 读数 3207/3207。
- 需要你做的:受管面(`skills/**`,Tier H)——席位完成契约复审后,由授权账号 Approve,再由席位落地。
## What changes
One cell of the `percent` row in
`skills/objectstack-data/rules/field-types.md` (Numbers table). It read
`Percentage values (0-100)`; it now reads: *Percentage; stored as a
fraction (0-1) unless the field declares `max` above 1 (`max: 100`),
then whole points; seeds, defaults, API values use that scale.* The
Config cell (`min`, `max`, `precision`, `percentDisplay`) is unchanged.
The rule is `percentScaleOf` in
`packages/spec/src/data/percent-scale.ts` on `main` `1f1a369b`: "A
percent field stores a FRACTION unless it declares `max` above 1" — the
rule the percent edit widget writes by (typed input divided by 100
unless `max` is above 1), so `min: 0, max: 100` is a storage statement,
not only validation; the read side (`percentDisplayValue`,
`ui/packages/fields/src/index.tsx` `PercentCellRenderer` via
`percentCellScale`) multiplies a fraction by 100. The cell says "seeds,
defaults, API values use that scale" because every write path stores the
number as sent: a seeded `25` on a field without `max` reads back
`2500%`, and `0.25` is what "25%" needs.
**Changeset** `.changeset/28489-percent-storage-scale-skill.md`:
`@objectstack/skills` patch, both declaration lines.
### Token ceiling — paid by deletion, never by re-wrap
`field-types.md` had 1 token of headroom under its 3207 ceiling after PR
#28487. The new cell is +128 bytes over the old one. Deleted to pay for
it: the `### Vector (AI Embeddings)` example under Common Field
Configurations (125 bytes) — its one fact, that `dimensions` is the flat
field-level key, is already the Enhanced Types row (`` `dimensions`
(flat sibling, e.g. `1536`) ``), and the invented-key blockquote at the
top of the file already names `vectorConfig` as refused. No line was
re-wrapped.
**Readings** (bytes · ceil(bytes/4) tokens · lines), base `1f1a369b` →
head `12f6cdc6`:
| Surface | Before | After |
|:---|:---|:---|
| `skills/objectstack-data/rules/field-types.md` | 12824 B · 3206 tok ·
273 lines | 12828 B · 3207 tok · 264 lines (ceiling 3207, headroom 0) |
Every other file under `skills/` is unchanged.
## Tests
Documentation only. `skills/objectstack-data/evals/*.json`, `SKILL.md`
and the other rules files were grepped for `percent`, `0-100` and
`0–100`: no eval or other skill text states a 0–100 scale, so no eval
changes (the order's condition did not fire).
## Acceptance notes
- **Scope held to the one cell.** The `scale` consequence
(`FieldSchema.scale` counts the decimal places of the displayed
percentage-point value, so a fraction-stored field carries `scale + 2`
stored places) is stated once on the `scale` describe and not restated
in the skill; the cell gives the author the storage answer the `scale`
rule hangs on.
- **The `progress` type is not a `percent`.** Its row (`Progress bar`,
`min`, `max`) is untouched; `percentScaleOf` answers `undefined` for it
and the renderer reads it as whole points, which is not this card's
subject.
- **Not touched:** `skills/*/references/_index.md` (open PR #28467), the
docs site page (`content/docs/data-modeling/fields.mdx` Number Types
already carries no 0–100 claim for `percent`), `skills/objectstack-ui`.
- **Dedupe words** for the seat: percent fraction skill, percentScaleOf
skill, field-types token ceiling.
## Verification
All readings at head `12f6cdc6` (= `origin/main` `1f1a369b` + one
commit).
- **Derived gates** — `node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack` → 43 families; every line run with
stdin closed after `turbo run build
--filter='@objectstack/client-react...'` under the verify lock, exit
codes landed on disk first; `dispatch-gates.mjs --repo
objectstack-ai/objectstack --ran FILE` → `✓ dispatch-gates --ran: 43
derived famil(ies) accounted for — 42 run, 1 NOT-MEASURED (1 DERIVED
from a recorded exit 3)`. 42 families exit 0, among them
`check-skills-token-ratchet` (+ `--self-test`),
`check:skill-identifier-liveness`, `check:corpus-claim-drift`,
`check:doc-authoring`, `check:role-word`, `check:pm-skill-id-lint`,
`check:pm-governed-merges`, `@objectstack/spec check:skill-examples`,
`check:closing-keyword-parity`, `check:empty-changeset`,
`check:changeset-no-major`.
- NOT MEASURED: `pnpm check:dual-build-cjs-loads`, exit 3 (PREREQUISITE
NOT MET — it needs every package's `dist`, a full `pnpm build`); the
diff touches no package entry. CI runs it.
- **Tier** — `skills/**`: `claude-fable-5-1` MANDATORY, no one-line
exit; this thread runs on that tier.
- **Changed lines** — 1 file under `skills/` plus the changeset, far
under the 3000 human-merge threshold.
Dogfood: not run — the title carries no `!` and `Clause-②` carries no
`(narrowing)` arm.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(No schema touched.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes (CI-owned repo scan; no
`.ts` touched).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (Not touched.)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01L9qibvc9vjAiGhyhnLTp34)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent eeec88d commit 35b178b
2 files changed
Lines changed: 11 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| |||
243 | 243 | | |
244 | 244 | | |
245 | 245 | | |
246 | | - | |
247 | | - | |
248 | | - | |
249 | | - | |
250 | | - | |
251 | | - | |
252 | | - | |
253 | | - | |
254 | | - | |
255 | 246 | | |
256 | 247 | | |
257 | 248 | | |
| |||
0 commit comments