Repository navigation
Commit 1c34fd7
docs(skills): an objectstack-data eval relabels a vendor field with fieldPatches, never by redeclaring it in fields (#30941)
<!-- claude-projects-attribution: {"github_login":"os-tesla"} -->
_Requested by **Tesla** · [project
thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6Jao3wye4ZiYLUP17qLNb6899Z)_
domain:skills#2 · os-tesla · session_01L9qibyYUF3Rw1uw6uU1yUy
Fixes #28804
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:`skills/objectstack-data/evals/objects-fields-relationships.json`
新增第 7 例:装了 HotCRM 后,作者想让 `crm_account.industry` 字段显示为 "Sector"。标准答案是在配对包
`hotcrm.custom` 里写 `defineObjectExtension({ extend: 'crm_account',
fieldPatches: { industry: { label: 'Sector' } } })`;必含
`fieldPatches`、`hotcrm.custom`、`extend: 'crm_account'`、`label:
'Sector'`、`defineObjectExtension`,禁含把 `industry` 在 `fields`
里重新声明(`industry: Field.select(`)、`overrides:`、`name: 'crm_account'`。另加一条
changeset。技能正文零改动。
- 为什么改:技能的〈Object Extension Model〉教了"改厂商字段的显示用 `fieldPatches`,不要在
`fields` 里重声明",但没有任何评测覆盖它;以后为付 token 棘轮而删掉这段,什么都不会红。这一例让这条教学有了守门。
- 风险与回滚:只加一个评测夹具用例与一条 changeset,不改技能文本、不改运行时;评测夹具不计入 token 棘轮(裁决
6513306068 B)。回滚即 revert。
- 先看:`skills/objectstack-data/evals/objects-fields-relationships.json` 第
7 例(`expected_output` 的每句都对照 `main` 上 `SKILL.md` 〈Object Extension
Model〉与 `packages/objectql/src/registry.ts` 的 `patchedField`
写成);`.changeset/28804-data-eval-field-patches.md`。
- 两分钟验证:`node scripts/check-skills-token-ratchet.mjs`,预期
`skills/objectstack-data/evals/objects-fields-relationships.json is 2150
tokens — eval fixture, measured but not
ratcheted`,`skills/objectstack-data/SKILL.md is 6087 tokens (ceiling
6123)` 不变;再 `grep -c "label: 'Sector'" skills/objectstack-data/SKILL.md`
得 1,证明每个必含 token 都在技能里教过。
- 需要你做的:本 PR 触 `skills/**`(Tier H),需要受管审批人在 GitHub 上 Approve 一次;之后席位落地。
## What changes
`skills/objectstack-data/evals/objects-fields-relationships.json`: case
7, appended after case 5's `crm_account` extension (the fixture whose
topic cluster holds object extensions;
`hooks-security-seeds-datasources.json` has no extension case).
- **Prompt:** HotCRM installed; its `crm_account` object's `industry`
field should read "Sector" instead of "Industry", without touching
HotCRM's source.
- **Expected output:** `defineObjectExtension({ extend: 'crm_account',
fieldPatches: { industry: { label: 'Sector' } } })` authored in
`hotcrm.custom` and registered in `objectExtensions`; a patch carries
display keys only (`label`, `description`, `inlineHelpText`,
`placeholder`), the field's type, values and rules stay HotCRM's, a
tenant-edited key keeps the tenant's text; never redeclare `industry` in
`fields` (takes the field over, cuts it off from upgrades, and an
unsuffixed field in a `.custom` extension is refused anyway); an
option's label rides the same patch keyed by the option's stored `value`
only for a field with its own `options`, a `picklist`-bound field's
options are never patchable, a patch naming a field or option value the
target lacks is refused at install and by `os validate`.
- **`must_contain`:** `hotcrm.custom`, `defineObjectExtension`, `extend:
'crm_account'`, `fieldPatches`, `label: 'Sector'`. Each appears as a
whole token in `skills/objectstack-data/SKILL.md` on `main` (1, 2, 1, 4,
1 hits; checked with the `IDENT_CHAR` boundary rule of
`ui/scripts/check-skill-eval-tokens.mjs`, whose own population is
`skills/objectui` only, so the check for this bundle is by hand).
- **`must_not_contain`:** `industry: Field.select(` (the take-over
spelling: HotCRM's field is `Field.select`), `overrides:` (replacing the
object whole), `name: 'crm_account'` (redeclaring the object). None
names a mechanism a right contrasting answer must spell.
`.changeset/28804-data-eval-field-patches.md`: `'@objectstack/skills':
patch`, both declaration lines.
Every sentence of the expected output states what `main` does:
`skills/objectstack-data/SKILL.md` 〈Object Extension Model〉 (the
whitelist, the take-over rule, the `__c` refusal, the picklist rule),
`packages/spec/src/data/object.zod.ts` (`FieldDisplayPatchSchema`,
`refuseFieldPatchOfReplacedField`, `fieldPatchesDescription`),
`packages/objectql/src/registry.ts` `patchedField` (the picklist-bound
`options` skip),
`packages/metadata-core/src/extension-field-patch-targets.ts` (the
`field` / `option` / `picklist-option` misses the install door and `os
validate` refuse by).
**Readings (os-dev rule for `skills/**`):**
| Reading | Before (`origin/main` `4d56914a`) | After |
|:--|:--|:--|
| `skills/objectstack-data/evals/objects-fields-relationships.json`
lines | 120 | 140 |
| same file, tokens (`check-skills-token-ratchet`, eval fixture:
measured, not ratcheted) | 1749 | 2150 |
| `skills/objectstack-data/SKILL.md` lines / tokens | 465 / 6087
(ceiling 6123) | unchanged |
| Package, all 11 `skills/*/SKILL.md`, lines | 4525 | unchanged |
No ceiling row moves; no skill text is added or deleted.
## Why
#28804: an out-of-scope finding of PR #28795 (card #28730, which added
the `fieldPatches` paragraph and is closed completed). With no eval, a
later trim made to pay the token ratchet could drop the paragraph and
nothing would fail. Evals sit outside the ratchet (ruling record
6513306068 B), so the case costs no skill text.
## Tests
No runtime code changes. The fixture parses as JSON (7 cases, ids 1–7);
the case's own `expected_output` contains every `must_contain` token and
none of the `must_not_contain` tokens (self-check script in the thread).
## Acceptance notes
- `skills/objectstack-data/evals/` has no runner in this repo; the
fixture is parsed as JSON and measured by `check-skills-token-ratchet`
(population 1b). The CI eval-token gate
(`ui/scripts/check-skill-eval-tokens.mjs`) walks `skills/objectui` only,
so the whole-token teaching check for this bundle was done by hand and
is recorded above.
- Out of scope, for the seat to judge (class c, noted, not filed): the
skill's own example `fieldPatches: { industry: { label: 'Sector',
options: { technology: { label: 'Tech' } } } }` (`SKILL.md` line 364,
and the same example in `fieldPatchesDescription()` of
`packages/spec/src/data/object.zod.ts`) patches an option of
`crm_account.industry`, which in HotCRM is `Field.select({ picklist:
'industry' })` (`hotcrm` `src/sales/objects/account.object.ts`). A
`picklist`-bound field's options are never patchable, so an author who
copies the example against the real HotCRM is refused by `os validate`
and the install door with the `picklist-option` miss
(`extension-field-patch-targets.ts`). The eval's expected output
therefore keeps the `options` form conditional ("only for a field that
declares its own `options`"). Reach read off the judge's code path, not
measured live.
- Overlap: seat 2's open PRs #30890 (`references/examples-objects.md`)
and #30921 (`rules/field-types.md`) touch other files; seat 1's #30805
declares `skills/**` wide. `origin/main` (`4d56914a`) had not moved at
push time, so there was nothing to merge; a later move is merged on the
next look.
## Verification
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` against the two-file diff at `73639a7c`
(branch base `origin/main` `4d56914a`, unchanged at push time, so no
merge was needed). Every line run with stdin closed, exit codes landed
on disk first: **40 derived families, 40 run, 40 exit 0**;
`dispatch-gates --ran` reconciliation: `40 derived, 40 run, 0
NOT-MEASURED, 0 UNRUN`. Ran list:
`skills-seat-2/out/28804-gates-ran-73639a7c.list` in the project files.
<details><summary>Gate readings at 73639a7</summary>
- `check-skills-token-ratchet`:
`skills/objectstack-data/evals/objects-fields-relationships.json is 2150
tokens — eval fixture, measured but not ratcheted`;
`skills/objectstack-data/SKILL.md is 6087 tokens (ceiling 6123; headroom
36)`, unchanged; `57 authored bundle file(s) within their ceilings`,
exit 0.
- `check:skill-identifier-liveness`, `check:skill-compatibility`,
`check:skill-frame-sync`, `check-empty-changeset --base origin/main`,
`check-changeset-no-major --base origin/main`,
`check-adr-0087-registration --base origin/main`,
`check:pm-governed-merges`, `check:doc-authoring`, `check:nul-bytes`,
`check:role-word`, `check-closing-keyword-parity`,
`check-comment-mask-corpus`, the rest of the 34 no-build families: exit
0.
- Six dist-reading families after a declarations build of
`./packages/**` under the verify lock (`VERDICT command-exit 0`, 7m27s):
`check:dual-build-cjs-loads` (`116 published require entry point(s)
across 71 package(s) load; 2456 emitted CommonJS file(s) parse`),
`check:lean-entry-closure`, `check:dts-closure` (`241/241 declared
declaration file(s) present`), `check:published-files`,
`check:sourcemap-no-sources-content`, `@objectstack/lint
check:doc-formula-expressions`: exit 0.
- `ui/scripts/check-skill-eval-tokens.mjs`: exit 0 (`Every must_contain
token is taught by its own skill bundle`; population `skills/objectui`
only, see Acceptance notes).
- Tier: `dispatch-gates --tier` on the two paths: `skills/**` clause ①,
`claude-fable-5-1` mandated, no one-line exit; this thread runs on it.
`check-governed-merges --test` on the two paths: Tier H.
</details>
CI families (`Lint & Repo Gates`, `Test Core`, the rest) are the PR's
check-runs, not re-run locally.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` is CI's run (no source file in
the diff).
- [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` 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 with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01L9qibyYUF3Rw1uw6uU1yUy
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 7c1eeb1 commit 1c34fd7
2 files changed
Lines changed: 30 additions & 0 deletions
File tree
- .changeset
- skills/objectstack-data/evals
| 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 | |
|---|---|---|---|
| |||
115 | 115 | | |
116 | 116 | | |
117 | 117 | | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
118 | 138 | | |
119 | 139 | | |
120 | 140 | | |
0 commit comments