Skip to content

fix(spec): the two step-18 flow-binding D3 entries name only a text-slot hole and a CEL expression as the reads to rename - #23384

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-23338-d3-entry-single-brace-text
Oct 14, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-23338-d3-entry-single-brace-text

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #23338
Clause-②: no

Two ADR-0087 D3 semantic entries of protocol 18 still told an upgrading author to rename "a single-brace token in a value position" among the reads of a renamed variable. No protocol-18 value position reads a flow variable through a single-brace token, so this PR takes the phrase out of both replacement texts. It is a text-only change, following triage's direction (comment 6155971636): the card's "Wanted", as written.

Dispatched by the domain:spec seat 2 PM, session session_01BRQ9Mp1yH7R1az6MaUM18H, under its claim comment 6159719865.

What changes

  • packages/spec/src/migrations/entries/semantic/18.flow-binding-name-dollar-refused.ts and 18.flow-binding-variable-dollar-name-refused.ts: the last clause of replacement names a text-slot hole and a CEL expression, and nothing else. Each entry keeps its id, fromVersion, toVersion, surface, reason, acceptanceCriteria and every other field byte-identical. No schema, door, conversion or entry id changes.
  • .changeset/23338-flow-binding-d3-replacement-reads.md: an @objectstack/spec patch, with the FROM → TO sentence.
FROM TO
Rename every read of the old name with it — a text-slot hole, a CEL expression, a single-brace token in a value position Rename every read of the old name with it — a text-slot hole, a CEL expression

The new wording is the one PR #23252 gave both entries' changesets (22502 and 22572, now under .changeset/pre/), and the one PR #23336 put in the 18.0.0-next.0 entries of packages/spec/CHANGELOG.md: "(a text-slot hole, a CEL expression)". The generated upgrade guide and spec-changes.json now say the same as those release notes.

Why it is true: S6 (615c69604) made every CRUD filter operand a value slot, and S7 (7958bdf36) deleted the single-brace resolver. A value slot takes a CEL value envelope or a literal, and a {…} token there is refused. One measured nuance is stated in the changeset, so that its sentence stays true: a CRUD filter operand that is one whole query placeholder ({current_user_id}, {today}) is handed on to the query engine untouched (the filterOperand arm of valueSlotTemplateRefusals, judged by classifyFlowFilterOperandString). That placeholder reads no flow variable, so a renamed variable has no read there.

The grep over every step-18 entry

At base 713f23185, over packages/spec/src/migrations/entries/**/18.* (769 files):

  1. The card's phrase, git grep -n "single-brace token in a value position" over the whole repository: exactly 2 hits, the two entries above, and both are corrected here. At head 6bf205cb8 the only hit is the FROM cell of this PR's changeset.
  2. The same idea in other words, git grep -n -i -E "single[- ]brace|value position|\{token\}|brace token|\{var\}|single-curly|template dialect|template token": 22 hits in 9 entries. Apart from the two above, none reads the token as live:
    • 18.flow-builtin-node-config-values-refused.ts :40, :57, :86: a {token} in a number or boolean slot is refused as the wrong type; at a plain string key it parses and registers as a literal; http interpolated "once" and "interpolates nothing now". No read is claimed.
    • 18.flow-text-slot-single-brace-refused.ts (5 hits): the text-slot refusal.
    • 18.flow-text-slot-unbound-dollar-root-refused.ts :32, :35: "In 17.x the slot was a plain string read by the single-brace interpolator", in the past tense, and a refusal's remedy.
    • 18.flow-value-slot-template-dialect-refused.ts (4 hits): the value-slot refusal, with the query-placeholder carve-out named.
    • 18.flow-write-node-stored-metadata-target-refused.ts :37: a {token} objectName cannot be read as a name.
    • 18.translation-flow-screen-title-text-slot-refused.ts (4 hits): the translated-heading refusal.
    • 18.view-filter-rule-scalar-operator-array-refused.ts :25: a filter rule's "value position", which has nothing to do with templates.
  3. A third pass, brace or interpolat outside the two spellings above: 29 more hits in 13 entries. Each is in the past tense, a refusal, or another dialect (${…} in UI action URLs, a datasource secret, dashboard documents). None names a single-brace read as live.

The step-18 rationale fragments in registry.ts.template carry no such sentence either. Their single-brace hits are refusals, plus the statement that the single-brace interpolator is deleted.

Generated projections and pins

  • No tracked file embeds the old sentence. At base, git grep "Rename every read of the old name" finds only the two entries. registry.ts, spec-changes.json and the content/docs/protocol-upgrade/ pages are gitignored build output, so nothing was regenerated or committed.
  • The projections carry the new text, measured on this head. build-upgrade-guide.ts --out and build-spec-changes.ts --out were written to a scratch path. The old phrase has 0 hits in each (grep exit 1). The new sentence has 2 hits in the guide and 4 in spec-changes.json (exit 0). In the built dist/migrations/index.mjs and index.js, the old phrase is absent (exit 1) and the new sentence has 2 hits each.
  • No test reads either replacement text. flow-bound-variable-name.test.ts pins only these two entries' surface, conversionIds and rationale id, and migrations.test.ts judges the shape of every semantic entry. No new test is added for a text fix.

Verification

All at head 6bf205cb8, on base 713f23185.

  • pnpm --filter @objectstack/spec build, under the verify lock: VERDICT command-exit 0.
  • pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/migrations src/automation/flow-bound-variable-name.test.ts: 5 files, 323 tests passed.
  • pnpm --filter @objectstack/spec run typecheck (tsc --noEmit, check:scripts-typecheck, check:test-typecheck): exit 0.
  • pnpm turbo run build --filter=!@objectstack/docs --concurrency=2, under the lock: 75 successful, 75 total. This build is the prerequisite of three derived gates.
  • Derived gates. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, with no paths, gives 82 commands. Each ran with its exit code captured before any pipe.
    • First pass: 79 exited 0. 3 exited 3 (PREREQUISITE NOT MET, nothing built yet): check:doc-formula-expressions, check:dual-build-cjs-loads and check:lean-entry-closure. After the full build, all three exited 0.
    • Among the 82, all exit 0: check-adr-0087-registration, check-empty-changeset, check-changeset-no-major, check:upgrade-guide, check:spec-changes, check:authorable-surface, check:doc-authoring and check:nul-bytes.
    • --ran: "82 derived famil(ies) accounted for — 82 run, 0 NOT-MEASURED (a DERIVED zero — all 82 recorded an exit code and none of them is 3)."
  • ESLint, a measured narrowing. eslint --no-inline-config --format json over the 3 changed files. The 2 .ts files have 0 errors and 0 warnings. The config ignores the .md changeset. eslint.config.mjs enables no type-aware linting (no parserOptions.project), so the diff cannot move the verdict on an untouched file.
  • No consumer sweep. Only string values change, so no export, type or wire shape moves.

Acceptance notes

  • origin/main moved to 28e294f45 after the gates ran. Its one new commit (plugin-sharing and runtime) touches neither entry and nothing in packages/spec.

Generated by Claude Code

…lot hole and a CEL expression as the reads to rename

The replacement text of flow-binding-name-dollar-refused and
flow-binding-variable-dollar-name-refused still listed "a single-brace
token in a value position" among the reads of a renamed variable. No
protocol-18 value position reads a flow variable through a single-brace
token: a value slot is a CEL value envelope or a literal, and a token
there is refused. The generated upgrade guide and spec-changes.json
project this text. Text only; a spec patch changeset carries the
FROM -> TO sentence.

Claude-Session: https://claude.ai/code/session_01BRQ9Mp1yH7R1az6MaUM18H
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Oct 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs.

What this run could not see

Coarse fallback — 142 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 28e294f450c7878482e6845221328a40d7b4b2fb → packageMentionDocs.

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 38509435041 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Test Core (2/6) — 失败步骤: Run this shard's tests

    create-objectstack:test:  FAIL  src/banner-version.test.ts > the real CLI banner (#10325, wiring) > names the version create-objectstack's own package.json actually declares
      ↳ 失败原因: create-objectstack:test: Error: Test timed out in 20000ms.
    

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

  • src/banner-version.test.ts — 24h 窗口内只有本 PR 撞到过,暂不汇总(再有一个不同 PR 撞到就会自动开汇总 issue)。
  • ⚠️ 24h 评论账本没读完(超过 5 页仍未读到窗口尽头),所以上面的「不同 PR 数」是下界,不是全量。

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 1 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Queue note · domain:spec seat 2 (#18549) · os-justin · session session_01BRQ9Mp1yH7R1az6MaUM18H · 2026-10-14T04:34Z.

  • What failed: the merge queue removed this PR at 04:33Z with CI_FAILURE. In merge-group run 38509435041 (group base 0add8a49c), Test Core (2/6) failed in create-objectstack. The queue-triage extraction (6160961798) names one case: src/banner-version.test.ts › "the real CLI banner ([finding] create-objectstack@17.1.0 greets the user with a hardcoded "◆ Create ObjectStack v6.x" banner #10325, wiring) › names the version create-objectstack's own package.json actually declares", Test timed out in 20000ms. Test Core itself is the roster job failing on that shard.
  • Why this is read as not this PR's:
    • It is a timeout, not an assertion.
    • This PR changes only two migration entries' replacement strings in packages/spec and a changeset. Nothing in create-objectstack or its CLI banner moves.
    • The PR's own CI on 6bf205cb8 was green.
    • The same run's roster annotations show two other suites over their wall ceilings (@objectstack/runtime 938 s, @objectstack/cloud-connection 220 s), which is shared-runner load.
  • What the seat does: it re-queues this PR once. A second failure of the same case is read as real and root-caused. The queue-triage signature ledger opens the family issue if a second PR hits this file.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit e4ec6ec Oct 14, 2026
42 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-23338-d3-entry-single-brace-text branch October 14, 2026 05:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

2 participants