Repository navigation
Commit 987ff33
docs(skills): teach that a save and os validate refuse titleFormat (#30096)
domain:skills#1 · huangyiirene · session_01J8VVAnMUWA9rufXzFaEh4J
<!-- claude-projects-attribution: {"github_login":"huangyiirene"} -->
_Requested by **Irene** · [project
thread](https://claude.ai/code/project/chan_01TJXtQ1tVD26ecLDZxFS67x?thread=cmsg_01TJXtQ1tVD26ecLDZxFS67x7p5hEJsCWtDpFXteTCt847)_
Fixes #29506
Clause-②: no
Metadata-protocol: none
The maintainer waived the model-tier mandate for `skills/**` while that
tier had no quota; this PR was developed below it.
## 维护者速读
- 改了什么:两个技能不再把 `titleFormat` 讲成「已弃用但未移除」,改为「保存和 `os validate`
会拒绝它(`title-format-retired`),改用 `nameField`」;ADR-0079 D3
加一条带日期的修订说明,引用裁决 6574393684 和 PR #29499。决定本身不动。
- 为什么改:PR #29499 已让保存门和 `os validate` 拒绝写了 `titleFormat`
的对象,三处文本还在教旧规则(「advisory, not an error」)。
- 风险与回滚:纯文本 + changeset,无代码改动。两个技能文件都变小(data 6119 → 6116 tokens,formula
5956 → 5950),无 re-wrap,上限未动。回滚即 revert。
- 先看:`skills/objectstack-data/SKILL.md` 的 `titleFormat`
行;`docs/adr/0079-record-display-name.md` D3 下的 Amendment 块。
- 需要你做的:Tier H 受管面(`skills/**`),契约复审后需要 `GOVERNED_APPROVERS` 批准;PR 保持
draft。
## What changes
The refusal is read off main, not the card:
`packages/lint/src/validate-record-title.ts`
(`validateTitleFormatRetired`, severity `error`, rule
`title-format-retired`, registered in `authoring-rules.ts` with
`surfaces: CLI_AND_RUNTIME`) and
`packages/spec/src/migrations/entries/semantic/18.object-title-format-refused.ts`
("`os validate`, `os build`, `os lint` and the metadata save gate (`422
INVALID_METADATA`) refuse the key as `title-format-retired`, an error").
- `skills/objectstack-data/SKILL.md`, the `titleFormat` row of the
optional-properties table:
- Before: `**Deprecated, not removed (ADR-0079)** — render-only: the
server can't return or query it. Use `nameField` (it wins); a composite
title follows the `nameField` row`
- After: `**Refused (ADR-0079)**: a save and `os validate` refuse it
(`title-format-retired`). Move it to `nameField`; a composite title
follows the `nameField` row`
- The render-only reason is dropped: its home is `os explain
title-format-retired` (the lint fix line points there,
`validate-record-title.ts` [#22161] comment) and ADR-0079 D3. "(it
wins)" is dropped because precedence no longer matters once the key is
refused.
- `skills/objectstack-formula/SKILL.md`, the `template` row's carriers
cell: `Object.titleFormat` (deprecated → `nameField`, ADR-0079) becomes
`Object.titleFormat` (a save and `os validate` refuse it; move it to
`nameField`, ADR-0079). Paid by deleting the sentence below the table "a
template holds a path and a formatter, nothing else.", which restates
the same row's Grammar cell (`{{ path }}` or `{{ path | formatter[:arg]
}}`, no conditionals). "Move logic into a CEL field" stays; the two
lines around the cut are otherwise byte-identical, no re-wrap.
- `docs/adr/0079-record-display-name.md`: a dated amendment block
directly under the D3 heading, citing ruling 6574393684 (#29007, letter
B) and PR #29499 (`3557366c02`). It says the key is *refused, not
removed* (the schema still parses it, so a stored object keeps loading
until its next save), which keeps the wording consistent with Open
question 3's remark that "retired" is used for a key that is still live.
It names the "deprecated and lint-warned" and "advisory, not an error"
sentences as describing the code before #29499, and notes D8's "never
errors" no longer covers `title-format-retired`. D8 carries a one-line
`Amended (2026-11-04, #29506)` pointer back to the D3 note (D8's own
text is unchanged), and the status line gains `· **Amended**
(2026-11-04, #29506, ruling 6574393684 …)` in the ADR-0045 form. D3's
decision and its quoted citation are left as they are.
- `.changeset/29506-title-format-refused-teaching.md`:
`'@objectstack/skills': patch`, with `Clause-②: no` and
`Metadata-protocol: none`.
### Token ratchet (no ceiling row moved, no re-wrap)
| file | tokens before / after / ceiling | bytes before / after |
|:--|:--|:--|
| `skills/objectstack-data/SKILL.md` | 6119 / 6116 / 6123 | 24493 /
24482 |
| `skills/objectstack-formula/SKILL.md` | 5956 / 5950 / 5997 | 23842 /
23819 |
## Why
PR #29499 made a save and `os validate` refuse an authored `titleFormat`
(ruling 6574393684). The skills still taught "deprecated, not removed"
and the ADR still said "advisory, not an error", so an author following
them would write a key the platform refuses.
## Verification
Head `f27efd1d` (two commits on `d79eecfe`: `c2236e37`, then the S1 ADR
follow-up).
<details><summary>Local gates on f27efd1 (and on c2236e3 before it):
50 derived, 50 run with exit 0, 0 NOT MEASURED (`dispatch-gates
--ran`)</summary>
- `pnpm install --frozen-lockfile` and a full `pnpm build` (exit 0) ran
first (on c2236e3; f27efd1 touches only the ADR, so the build was
reused), then every command from `node scripts/pm/dispatch-gates.mjs
--commands --repo objectstack-ai/objectstack`, each with a 900 s timeout
and its exit code captured before any pipe.
- All 50 exited 0, among them `check-skills-token-ratchet.mjs` (and
`--self-test`), `check-adr-links.mjs`, `check:adr-anchors`,
`check:adr-index`, `check:adr-symbol-anchors`,
`check-changeset-no-major.mjs`, `check-empty-changeset.mjs`,
`check:changeset-gate-self-tests`, `check-comment-mask-corpus.mjs`,
`check:corpus-claim-drift`, `check:cross-package-test-inputs`,
`check:doc-authoring`, `check:doc-formula-expressions`,
`check:skill-docs`, `check:skill-identifier-liveness`,
`check:skill-frame-sync`, `check:skill-compatibility`,
`check:dts-closure`, `check:dual-build-cjs-loads` and `check:role-word`.
- `--ran` printed: `50 derived famil(ies) accounted for — 50 run, 0
NOT-MEASURED`.
- `node scripts/check-commit-card-trailers.mjs --range
origin/main..HEAD`: exit 0.
- Writes: two `git push` (c2236e3, f27efd1); one relay `pr_create`; no
GitHub MCP write.
</details>
## 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` is CI's repo-wide run.
- [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 (the 维护者速读 block is the
repo's own Chinese reading aid).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01J8VVAkUoyAGLYtHWmyX2YW
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 1f13eb3 commit 987ff33
4 files changed
Lines changed: 31 additions & 5 deletions
File tree
- .changeset
- docs/adr
- skills
- objectstack-data
- objectstack-formula
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
129 | 141 | | |
130 | 142 | | |
131 | 143 | | |
| |||
222 | 234 | | |
223 | 235 | | |
224 | 236 | | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
225 | 240 | | |
226 | 241 | | |
227 | 242 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
90 | | - | |
| 90 | + | |
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
456 | 456 | | |
457 | 457 | | |
458 | 458 | | |
459 | | - | |
| 459 | + | |
460 | 460 | | |
461 | 461 | | |
462 | | - | |
463 | | - | |
| 462 | + | |
| 463 | + | |
464 | 464 | | |
465 | 465 | | |
466 | 466 | | |
| |||
0 commit comments