Repository navigation
Commit 2d6402c
fix(spec): name timeRelative.object in the time-relative arm of the flow type-mismatch upgrade entry (#30637)
<!-- claude-projects-attribution: {"github_login":"os-sales"} -->
_Requested by **Sales** · [project
thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuV5cRafodM2YQHxeDkdiWJM)_
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P
Fixes #30279
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:只改升级指南条目 `flow-record-read-and-decision-type-mismatch-refused`
的两段文字(`surface` 与 `reason` 中对应的一句),写明时间相对流程的条件按被扫描对象
`config.timeRelative.object` 做类型检查:开始节点不写 `objectName` 时按它,开始节点的
`objectName` 就是被扫描对象时按 `objectName`。
- 为什么改:发布门(PR #30276 之后)已经这样检查并拒收,条目原文只说“扫描开始节点的
objectName”,比实际拒收范围窄,`os migrate meta` 与升级指南会把作者引向不完整的说明。
- 风险与回滚:纯文字更正,条目 id、kind、replacement、acceptanceCriteria 与任何判决都不变;回滚即撤
PR。
-
先看:`packages/spec/src/migrations/entries/semantic/18.flow-record-read-and-decision-type-mismatch-refused.ts`(`surface`
末段与 `reason` 中 time-relative
一句);`packages/spec/src/migrations/migrations.test.ts` 末尾新增的断言。
- 两分钟验证:`pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2
src/migrations/migrations.test.ts -t "names the object a time-relative
flow"`,预期 1 个用例通过。
- 需要你做的:无,席位落地。
## What changes
The entry's `surface` and one `reason` sentence, written from the gate
code (`packages/lint/src/validate-expressions.ts`, the flow walk:
`objectName = startObject ?? sweepObject`, where `sweepObject` is
`config.timeRelative.object` on a time-relative flow; the `run-fails`
outcome is declared when `sweepsTypedObject: sweepObject !== undefined
&& sweepObject === objectName`). Every other field (id, kind,
replacement, acceptanceCriteria) is byte-identical.
**`surface`, the time-relative tail**
- FROM: `…; and the same conditions, bare name included, of a
time-relative flow (start config.timeRelative) sweeping the start node's
objectName`
- TO: `…; and the same conditions, bare name included, of a
time-relative flow (start config.timeRelative) sweeping
config.timeRelative.object, typed against that object when the start
node names no objectName and against the start node's objectName when
that is the swept object`
**`reason`, the time-relative sentence**
- FROM: `A time-relative sweep launches each run with the swept row as
its record, the same total row of the same object, so its conditions get
the same refusal where 18.3.0 warned.`
- TO: `A time-relative sweep launches each run with a row of the object
it sweeps (config.timeRelative.object) as its record, the same total row
of one object, so its conditions are typed against that object when the
start node names no objectName, and against the start node's objectName
when that is the swept object, and get the same refusal: where 18.3.0
warned on a sweep of the start node's objectName, and where a start that
names no objectName got no verdict at all.`
**Test.** No test pinned the entry's text; a new top-level `describe` in
`packages/spec/src/migrations/migrations.test.ts` asserts the surface
matches `sweeping config.timeRelative.object`.
**Changeset.** `.changeset/30279-time-relative-entry-surface.md`,
`@objectstack/spec` `patch`, with both declaration lines.
## Verification
All readings on head `bc0dd484` unless named.
<details><summary>Build, tests, typecheck</summary>
- `pnpm --filter @objectstack/spec build` (under the verify lock):
VERDICT command-exit 0.
- `pnpm --filter @objectstack/spec check:generated`: exit 0, "All 14
generated artifacts are up to date"; no artifact carries the entry text,
nothing regenerated.
- `pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2
src/migrations/`: 5 files, 198/198.
- The whole `@objectstack/spec` `pnpm test`: NOT MEASURED locally,
reason: the shared verify lock answered queue-timeout (exit 99) twice
behind a sibling's dogfood run (held 1094 s at the second try). Declared
narrowing: the migrations directory above is the suite that reads the
entry; CI `Test Core` runs the whole package.
- `pnpm --filter @objectstack/spec typecheck` (under the lock): VERDICT
command-exit 0.
- `eslint --no-inline-config` over the entry file and the test file:
exit 0.
</details>
<details><summary>Ablation (scripts/ablation-replace.mjs; restored blob
== HEAD, git diff HEAD empty)</summary>
- Mutation: the surface's new three-line tail set back to the FROM text
(`sweeping the start node's objectName`). On disk: FROM phrase count 0 →
1, `sweeping config.timeRelative.object` 1 → 0, blob `f0920514` →
`01fd0df2`; `gen:migration-registry` rerun, FROM phrase present in the
generated `registry.ts` (1).
- Result: 1 red, `the surface names config.timeRelative.object as the
swept object: AssertionError: expected 'automation.Flow of a
record-triggered…' to match /sweeping config\.timeRelative\.object/`
(Tests 1 failed, 157 skipped).
- Restore: blob after restore == HEAD (`f0920514`), `git diff HEAD`
empty; registry regenerated; `migrations.test.ts` 158/158.
</details>
<details><summary>Derived gates</summary>
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` on `bc0dd484`: 80 families; all 80 run, exit
codes captured per command before any pipe; 77 exit 0 on the first pass.
Three answered exit 3 (PREREQUISITE NOT MET: an unbuilt
`@objectstack/formula`, unbuilt workspace `dist/`, unbuilt `objectql`
`dist/`) on the first pass: `check:doc-formula-expressions`,
`check:dual-build-cjs-loads`, `check:lean-entry-closure`; re-run after
the closure build `check:type-check-debt` performed, each exit 0.
- `--ran` reconciliation with coded exit lines: "80 derived famil(ies)
accounted for — 80 run, 0 NOT-MEASURED (a DERIVED zero — all 80 recorded
an exit code and none of them is 3)".
- Named in the dispatch and inside the derived set: `pnpm
check:adr-0087-registration` exit 0 ("this PR adds no declared-breaking
changeset"), `pnpm check:doc-authoring` exit 0.
</details>
## Acceptance notes
- **The code agrees with the card.** The gate types the conditions
against `config.timeRelative.object` when the start names no
`objectName`, and declares the `run-fails` outcome only when
`timeRelative.object` equals the typed object, so a start naming another
object keeps the warning; the TO sentences say exactly that.
- **A start that names another object.** Since the
`flow-time-relative-object-mismatch` readiness rule landed, a
time-relative start whose `objectName` is not `timeRelative.object` is
refused by that rule; this entry's `reason` still says "Any other flow
keeps a warning", which stays true of the expression verdict itself.
Noted, not changed.
- **No tracker id in a runtime string**: the entry's `surface` and
`reason` carry none; the test comment carries none either.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01L6bhgVugtCCwBs98FeR27P
Co-authored-by: Claude <noreply@anthropic.com>1 parent f3a52d3 commit 2d6402c
3 files changed
Lines changed: 33 additions & 3 deletions
File tree
- .changeset
- packages/spec/src/migrations
- entries/semantic
| 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 | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
| |||
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
26 | | - | |
27 | | - | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
28 | 34 | | |
29 | 35 | | |
30 | 36 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
802 | 802 | | |
803 | 803 | | |
804 | 804 | | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
0 commit comments