Repository navigation
Commit 74a19dd
docs(skills): the formula skill says the build refuses date subtraction (
<!-- claude-projects-attribution: {"github_login":"huangyiirene"} -->
_Requested by **Irene** · [project
thread](https://claude.ai/code/project/chan_01TJXtQ1tVD26ecLDZxFS67x?thread=cmsg_01TJXtQ1tVD26ecLDZxFS67xUVqqk5nMQrFBKFQ5V87Lo5)_
Fixes #29061
Clause-②: no
Metadata-protocol: none
Blocked-by: #29058
## 维护者速读
- 改了什么:formula 技能的「No date arithmetic」说明改为:构建拒收 `date + n` 和 `end -
start`(日期或日期时间相减、`today()`/`now()` 减日期字段),处方是 `daysBetween(a,
b)`;Want/Write 表不动。dashboards 规则、两个 eval 里写成日期相减的请假天数公式与说明同步改掉。
- 为什么改:#29058 让公式门禁拒收日期相减;旧说明写着 `end - start`「不报错、得到存成 `{}` 的
duration」,会教 AI 写出构建不过的公式。
- 风险与回滚:只改技能文字与 eval 文字,无代码;行数不变,token 净增 +26(两个受棘轮文件仍在上限内,上限未动)。必须在
#29058 合并后再落地,否则技能说的拒收在 main 上还不成立。回滚 = revert 本 PR。
- 先看:① `skills/objectstack-formula/SKILL.md` 第 151-153 行的说明;②
`skills/objectstack-ui/rules/dashboards.md` 第 100 行;③ 两个 eval 的一行改动。
- 两分钟验证:`node scripts/check-skills-token-ratchet.mjs`
全绿,`skills/objectstack-formula/SKILL.md` 为 5686/5997。
- 需要你做的:#29058 合并后,审批并合并本 PR(Tier H `skills/**`)。
## What changes
Text only, inside the claim's file surface. The wording follows PR
#29058 at head `e029ea772b1555ea33b2946e0978ff4175dbdd3e` (its gate in
`packages/formula/src/validate.ts`, its refusal messages, its changeset
and its new row in `content/docs/data-modeling/formulas.mdx`).
- `skills/objectstack-formula/SKILL.md`, the "No date arithmetic" note.
It said `end - start` "does not fault — it yields a `duration` stored as
`{}`". It now says the build refuses both `date + n` and `end - start`:
a date or date-time mixed with a number, or minus another, reads `null`,
and `today()` / `now()` minus a date field reads `{}`. It prescribes
`daysBetween(a, b)`. The Want / Write table is unchanged.
- `skills/objectstack-ui/evals/analytics-inline-vs-dataset.json`, eval
6. The stored `days_requested` formula is restated from `end_date -
start_date` to `daysBetween(record.start_date, record.end_date)`. Its
only `must_contain` token, `number`, is unchanged and still taught by
the skill.
- Item 3 sweep (`skills/**`, then `content/docs/**`), two more hits,
both fixed here:
- `skills/objectstack-ui/rules/dashboards.md` line 100 described the
same leave-days formula as `` `days_requested` (`end - start`) ``. It
now reads `` (`daysBetween(start, end)`) ``. The rule it teaches (never
`sum` a formula) is unchanged.
- `skills/objectstack-formula/evals/cel-predicates-formulas.json` eval 4
explained `record.close_date - today()` as "a duration stored as `{}`",
which reads as a shape that builds. It now says "the build refuses it".
Assertions unchanged.
- Outside `skills/**`: `content/docs/data-modeling/formulas.mdx` is
updated by #29058 itself; `content/docs/releases/v16.mdx` line 726 is
release history and stays as written. No other `content/docs/**` text
subtracts dates in a formula.
- `.changeset/29061-formula-skill-date-subtraction-refused.md`:
`@objectstack/skills` patch.
**Skills readings** (lines, then tokens from
`check-skills-token-ratchet`):
| | before | after |
|:--|--:|--:|
| `skills/objectstack-formula/SKILL.md` lines | 473 | 473 |
| `skills/objectstack-ui/rules/dashboards.md` lines | 463 | 463 |
| all `skills/*/SKILL.md` lines | 4550 | 4550 |
| `skills/objectstack-formula/SKILL.md` tokens (ceiling 5997) | 5668 |
5686 |
| `skills/objectstack-ui/rules/dashboards.md` tokens (ceiling 6262) |
6248 | 6251 |
| eval fixtures tokens (not ratcheted) | 29160 | 29165 |
| bundle total tokens | 222567 | 222593 |
No ceiling moved and no line was re-wrapped.
## Tests
No code changes. The claims in the new text were checked against the
gate itself, by calling `validateExpression('value', …)` from a built
`@objectstack/formula`, once at #29058's head (with this commit
cherry-picked on top) and once at `origin/main` `a4015ab4`:
<details><summary>#29058 head refuses every shape the note names and
accepts every daysBetween shape; origin/main accepts the
subtractions</summary>
```
-- #29058 head e029ea7
REFUSED date-arithmetic record.d + 1
REFUSED date-text-arithmetic record.end_date - record.start_date
REFUSED date-text-arithmetic record.end_at - record.start_at
REFUSED date-duration-value today() - record.start_date
REFUSED date-duration-value now() - record.start_at
REFUSED date-duration-value record.close_date - today()
accepted daysBetween(record.start_date, record.end_date)
accepted daysBetween(record.start_date, record.end_date) + 1
accepted daysBetween(today(), record.close_date)
-- origin/main a4015ab
REFUSED date-arithmetic record.d + 1
accepted record.end_date - record.start_date
accepted record.end_at - record.start_at
accepted today() - record.start_date
accepted now() - record.start_at
accepted record.close_date - today()
accepted daysBetween(record.start_date, record.end_date)
accepted daysBetween(record.start_date, record.end_date) + 1
accepted daysBetween(today(), record.close_date)
```
</details>
The `origin/main` half is why this PR is `Blocked-by: #29058`: before
that lands, the note would describe a refusal `main` does not make.
`check:doc-formula-expressions` (it judges the formula examples in
`skills/**` with the built `@objectstack/formula`) is green on both
trees: on this branch at `a36bf3ab`, and on #29058's head with this
commit cherry-picked (25 record-scoped examples across 548 files judged
clean).
## Acceptance notes
- The note says "never `end - start`" without carving out predicates.
#29058 still accepts a condition that compares a duration (`today() -
record.start_date > duration("72h")`). The skill keeps the simpler rule,
which is never wrong for a formula; adding the carve-out would cost
tokens for an edge the formula skill does not teach.
- If #29058's head moves before it merges, this PR re-reads it.
## Verification
Gates derived with `node scripts/pm/dispatch-gates.mjs --commands`
(merge base `a4015ab47`, 5 paths, +18/−6) and run one by one on head
`a36bf3ab`, the exit code captured before any pipe.
<details><summary>45 derived, 41 exit 0, 4 NOT MEASURED (exit 3,
whole-tree build prerequisite); --ran: 0 UNRUN</summary>
```
41 commands :: exit 0, including
node scripts/check-skills-token-ratchet.mjs :: exit 0
node scripts/check-skills-token-ratchet.mjs --self-test :: exit 0
node scripts/check-empty-changeset.mjs --base origin/main :: exit 0
node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0
node scripts/check-closing-keyword-parity.mjs :: exit 0
pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 (after building formula + lint)
pnpm --filter @objectstack/spec run check:skill-docs :: exit 0
pnpm check:skill-compatibility :: exit 0
pnpm check:skill-identifier-liveness :: exit 0
pnpm check:skill-frame-sync :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:published-files :: exit 0
NOT MEASURED, exit 3 (PREREQUISITE NOT MET: every package's dist), left to CI:
pnpm check:dts-closure
pnpm check:dual-build-cjs-loads
pnpm check:lean-entry-closure
pnpm check:sourcemap-no-sources-content
dispatch-gates --ran: 45 derived famil(ies) accounted for — 41 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3).
```
</details>
The four not measured are whole-tree families that read every package's
`dist/`; this diff touches no package source, so a full local build was
declared to CI rather than run.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01J8VVAjkjQLh4kZsuRAM4iV
---
_Generated by [Claude
Code](https://claude.ai/code/session_01J8VVAjkjQLh4kZsuRAM4iV)_
Co-authored-by: Claude <noreply@anthropic.com>end - start) (#29122)1 parent 67ee171 commit 74a19dd
5 files changed
Lines changed: 18 additions & 6 deletions
File tree
- .changeset
- skills
- objectstack-formula
- evals
- objectstack-ui
- evals
- rules
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
151 | | - | |
152 | | - | |
153 | | - | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
154 | 154 | | |
155 | 155 | | |
156 | 156 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
58 | | - | |
| 58 | + | |
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
97 | 97 | | |
98 | 98 | | |
99 | 99 | | |
100 | | - | |
| 100 | + | |
101 | 101 | | |
102 | 102 | | |
103 | 103 | | |
| |||
0 commit comments