Skip to content

docs(skills): mark the two non-canonical row-predicate spellings as deprecated - #6865

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note
Aug 30, 2026
Merged

docs(skills): mark the two non-canonical row-predicate spellings as deprecated#6865
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes#5759

Prose-only annotation of the three-way row-predicate sentence in the published skills guide skills/objectui/guides/schema-expressions.md (List-view/CEL tier). It presented record.status, bare status and data.status as peers, labelling record.* merely "canonical" — a word that reads as a style preference — while since Phase 1 (#5330 / PR #5737) the other two emit a one-time dev-console deprecation warning and retire once a stored-metadata survey sizes the window.

What changed

One sentence, at :307. record.* is now stated as the canon; bare status and data.status are stated as deprecated here (still bound, warned once in dev, retiring after the survey), pointing at packages/core/src/evaluator/rowPredicateCanon.ts; and the card's sharper point is carried: data.* is the trap — the server's authoring oracle accepts it silently and it then binds nothing at runtime, a constant false rather than an error.

"Deprecated here" is deliberate, not hedging: rowPredicateCanon.ts scopes the deprecation to the runtime record layer, because data is the canonical root of a metadata-editing form (ADR-0089 D3). An unqualified sentence in this corpus would contradict that.

No example was rewritten — the nearby data-model-tier and conditional-formatting examples are already record.*.

State verified on this branch, not taken from the card

The card was filed 2026-08-23; the words had to describe what is measurable now. Read at base aca70f6:

  • listConditional.ts:273 still binds all three — { ...(opts.scope ?? {}), ...rowObj, data: rowObj, record: rowObj }. No spelling has been retired or turned into a refusal, so "still bound" is accurate and "retiring after a stored-metadata survey" is the correct tense.
  • listConditional.ts:317 calls warnNonCanonicalRowSpelling(predicateText, rowObj, !opts.rowless, opts.label) on the CEL path, so both non-canonical spellings do warn on this tier, and data names the row here (not rowless), which is the condition the detector needs.
  • rowPredicateCanon.ts still reads Phase 1: "the binding is UNCHANGED and every spelling still resolves", warn-once, "removable only after a stored-metadata survey".

Phase 2 (#5741) has not advanced past "warned".

Three-engine boundary held

Only the List-view/CEL row-predicate tier changed. The ${…}/On-suffix tier earlier in the file (SafeExpressionParser, where data.* is correct) and the flow tier (isFieldVisibleWhen, previews/screen-spec.ts) are untouched. The one-time-warning sentence at :316-317 belongs to legacy-syntax routing, a different mechanism from these spellings, and is untouched — the diff hunk stops above it.

Line-count readings (2026-08-21 whole-package ruling)

PM-set budget for this card: +4 lines max net on the file.

readingbeforeafternet
skills/objectui/guides/schema-expressions.md (whole file)621625+4
published bundle — all 18 .md under skills/56825686+4

git diff --stat: 1 file changed, 7 insertions(+), 3 deletions(-). The budget is met exactly; the wording was cut three times to reach it (measured by wrapping each candidate at the file's 78-column prose width before editing).

Gates — each line is the gate's own verdict, re-run on the final commit 7bcfefc

check-skills-paths ✅ OK (94/95 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-control-bytes ✅ OK (scanned 5714 tracked text file(s); skipped 85 binary).
check:doc-fences ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript ...
check-doc-links Links are valid across 17 scan roots.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
check-doc-component-types ✅ Every documented component type is registered.
check-shell-escape-residue ✅ OK (4/4 root(s) resolved -- ... skills: 18 file(s), 235 fence(s) ...).
vitest (4 files) Test Files 4 passed (4) · Tests 107 passed (107)

The vitest set is every test file that reads this corpus: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx, scripts/__tests__/check-skills-paths.test.ts, scripts/__tests__/check-control-bytes.test.ts, scripts/__tests__/doc-version-claims.test.ts.

check-skills-paths got a positive control rather than a bare green: calling its own exported extractPathTokens on the edited file returns the new token — { line: 310, token: 'packages/core/src/evaluator/rowPredicateCanon.ts', pattern: false } — so the 94/95 verdict demonstrably includes the path this PR added.

No changeset: skills/** is not published source of a released package, and the gate says so in its own words above.

Two declared narrowings

check:doc-snippets was NOT RUN. Its own exit is 2 — "PRECONDITION NOT MET ... This is 'I could not run', NOT 'I ran and found errors'" — because it needs 21 package build closures, a repo-wide build this shared box cannot host in a foreground window. Instead its judged population was measured directly through its own exported extractor, scanFences:

  • population read from the gate itself, not guessed: scanFences collects only ts/tsx fenced blocks; this file has exactly 1, at line 250 — above the edited hunk (307-313).
  • count from that output: 1 block at base aca70f6 and 1 at head, same fenceLine 250, bodies byte-identical.
  • counter-probe: appending a line to that block's body does change the extracted population, so "identical" is a measurement that could have failed rather than a vacuous pass.

pnpm lint was narrowed to nothing, on eslint's own answer.eslint --no-inline-config --format json on the changed file reports "File ignored because no matching configuration was supplied" — the repo's flat config matches no .md file at all, so the file count eslint judges in this diff is 0. No type-aware linting is configured, and the diff is one markdown file, so no untouched file's verdict can move either.

CI runs the full farm regardless; these two are the cheap local half, declared rather than silently skipped.

Governed-face handling

Left as draft for the PM's review chain — not flipped ready, not queued, no auto-merge. Note for the record: this repo's AGENTS.md §"受管面" explicitly places root skills/**outside the governed surface (only .claude/**, AGENTS.md, CLAUDE.md, docs/adr/** are governed there) and would permit self-merge on green. The dispatch treats the published skills corpus as governed for this fleet's review chain, which is the stricter of the two, so draft-only satisfies both. Flagged so the divergence is visible rather than assumed.


Generated by Claude Code

…eprecated
The List-view/CEL row-predicate sentence in the published skills guide still
presented `record.status`, bare `status` and `data.status` as peers, labelling
`record.*` merely "canonical" — a word that reads as a style preference. Since
Phase 1 (objectui#5330) the other two emit a one-time dev-console deprecation
warning and retire once a stored-metadata survey sizes the window, and
`data.*` is the arm the server's authoring oracle accepts silently while
binding nothing at runtime (a constant `false`, not an error).
Prose only, +4 lines net, scoped to the List-view/CEL tier: the `${…}`/`On`
tier (SafeExpressionParser, where `data.*` is correct) and the flow tier are
different engines and are untouched, as is the legacy-syntax routing sentence
below. The deprecation is stated as layer-scoped ("deprecated **here**"),
matching rowPredicateCanon.ts — `data` stays canonical in a metadata-editing
form per ADR-0089 D3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
@zhuangjianguo
zhuangjianguo marked this pull request as ready for review August 30, 2026 07:26
@zhuangjianguo
zhuangjianguo added this pull request to the merge queueAug 30, 2026
Merged via the queue into main with commit 3355239Aug 30, 2026
28 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-5759-row-predicate-deprecation-note branch August 30, 2026 07:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published skills corpus still presents the row-predicate three-way binding as peers, with no sign that two of the three now warn (Phase 1 shipped)

3 participants

@zhuangjianguo@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
docs(skills): mark the two non-canonical row-predicate spellings as deprecated by zhuangjianguo · Pull Request #6865 · objectstack-ai/objectui · GitHub
Skip to content

docs(skills): mark the two non-canonical row-predicate spellings as deprecated - #6865

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note
Aug 30, 2026
Merged

docs(skills): mark the two non-canonical row-predicate spellings as deprecated#6865
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes#5759

Prose-only annotation of the three-way row-predicate sentence in the published skills guide skills/objectui/guides/schema-expressions.md (List-view/CEL tier). It presented record.status, bare status and data.status as peers, labelling record.* merely "canonical" — a word that reads as a style preference — while since Phase 1 (#5330 / PR #5737) the other two emit a one-time dev-console deprecation warning and retire once a stored-metadata survey sizes the window.

What changed

One sentence, at :307. record.* is now stated as the canon; bare status and data.status are stated as deprecated here (still bound, warned once in dev, retiring after the survey), pointing at packages/core/src/evaluator/rowPredicateCanon.ts; and the card's sharper point is carried: data.* is the trap — the server's authoring oracle accepts it silently and it then binds nothing at runtime, a constant false rather than an error.

"Deprecated here" is deliberate, not hedging: rowPredicateCanon.ts scopes the deprecation to the runtime record layer, because data is the canonical root of a metadata-editing form (ADR-0089 D3). An unqualified sentence in this corpus would contradict that.

No example was rewritten — the nearby data-model-tier and conditional-formatting examples are already record.*.

State verified on this branch, not taken from the card

The card was filed 2026-08-23; the words had to describe what is measurable now. Read at base aca70f6:

  • listConditional.ts:273 still binds all three — { ...(opts.scope ?? {}), ...rowObj, data: rowObj, record: rowObj }. No spelling has been retired or turned into a refusal, so "still bound" is accurate and "retiring after a stored-metadata survey" is the correct tense.
  • listConditional.ts:317 calls warnNonCanonicalRowSpelling(predicateText, rowObj, !opts.rowless, opts.label) on the CEL path, so both non-canonical spellings do warn on this tier, and data names the row here (not rowless), which is the condition the detector needs.
  • rowPredicateCanon.ts still reads Phase 1: "the binding is UNCHANGED and every spelling still resolves", warn-once, "removable only after a stored-metadata survey".

Phase 2 (#5741) has not advanced past "warned".

Three-engine boundary held

Only the List-view/CEL row-predicate tier changed. The ${…}/On-suffix tier earlier in the file (SafeExpressionParser, where data.* is correct) and the flow tier (isFieldVisibleWhen, previews/screen-spec.ts) are untouched. The one-time-warning sentence at :316-317 belongs to legacy-syntax routing, a different mechanism from these spellings, and is untouched — the diff hunk stops above it.

Line-count readings (2026-08-21 whole-package ruling)

PM-set budget for this card: +4 lines max net on the file.

readingbeforeafternet
skills/objectui/guides/schema-expressions.md (whole file)621625+4
published bundle — all 18 .md under skills/56825686+4

git diff --stat: 1 file changed, 7 insertions(+), 3 deletions(-). The budget is met exactly; the wording was cut three times to reach it (measured by wrapping each candidate at the file's 78-column prose width before editing).

Gates — each line is the gate's own verdict, re-run on the final commit 7bcfefc

check-skills-paths ✅ OK (94/95 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-control-bytes ✅ OK (scanned 5714 tracked text file(s); skipped 85 binary).
check:doc-fences ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript ...
check-doc-links Links are valid across 17 scan roots.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
check-doc-component-types ✅ Every documented component type is registered.
check-shell-escape-residue ✅ OK (4/4 root(s) resolved -- ... skills: 18 file(s), 235 fence(s) ...).
vitest (4 files) Test Files 4 passed (4) · Tests 107 passed (107)

The vitest set is every test file that reads this corpus: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx, scripts/__tests__/check-skills-paths.test.ts, scripts/__tests__/check-control-bytes.test.ts, scripts/__tests__/doc-version-claims.test.ts.

check-skills-paths got a positive control rather than a bare green: calling its own exported extractPathTokens on the edited file returns the new token — { line: 310, token: 'packages/core/src/evaluator/rowPredicateCanon.ts', pattern: false } — so the 94/95 verdict demonstrably includes the path this PR added.

No changeset: skills/** is not published source of a released package, and the gate says so in its own words above.

Two declared narrowings

check:doc-snippets was NOT RUN. Its own exit is 2 — "PRECONDITION NOT MET ... This is 'I could not run', NOT 'I ran and found errors'" — because it needs 21 package build closures, a repo-wide build this shared box cannot host in a foreground window. Instead its judged population was measured directly through its own exported extractor, scanFences:

  • population read from the gate itself, not guessed: scanFences collects only ts/tsx fenced blocks; this file has exactly 1, at line 250 — above the edited hunk (307-313).
  • count from that output: 1 block at base aca70f6 and 1 at head, same fenceLine 250, bodies byte-identical.
  • counter-probe: appending a line to that block's body does change the extracted population, so "identical" is a measurement that could have failed rather than a vacuous pass.

pnpm lint was narrowed to nothing, on eslint's own answer.eslint --no-inline-config --format json on the changed file reports "File ignored because no matching configuration was supplied" — the repo's flat config matches no .md file at all, so the file count eslint judges in this diff is 0. No type-aware linting is configured, and the diff is one markdown file, so no untouched file's verdict can move either.

CI runs the full farm regardless; these two are the cheap local half, declared rather than silently skipped.

Governed-face handling

Left as draft for the PM's review chain — not flipped ready, not queued, no auto-merge. Note for the record: this repo's AGENTS.md §"受管面" explicitly places root skills/**outside the governed surface (only .claude/**, AGENTS.md, CLAUDE.md, docs/adr/** are governed there) and would permit self-merge on green. The dispatch treats the published skills corpus as governed for this fleet's review chain, which is the stricter of the two, so draft-only satisfies both. Flagged so the divergence is visible rather than assumed.


Generated by Claude Code

…eprecated
The List-view/CEL row-predicate sentence in the published skills guide still
presented `record.status`, bare `status` and `data.status` as peers, labelling
`record.*` merely "canonical" — a word that reads as a style preference. Since
Phase 1 (objectui#5330) the other two emit a one-time dev-console deprecation
warning and retire once a stored-metadata survey sizes the window, and
`data.*` is the arm the server's authoring oracle accepts silently while
binding nothing at runtime (a constant `false`, not an error).
Prose only, +4 lines net, scoped to the List-view/CEL tier: the `${…}`/`On`
tier (SafeExpressionParser, where `data.*` is correct) and the flow tier are
different engines and are untouched, as is the legacy-syntax routing sentence
below. The deprecation is stated as layer-scoped ("deprecated **here**"),
matching rowPredicateCanon.ts — `data` stays canonical in a metadata-editing
form per ADR-0089 D3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
@zhuangjianguo
zhuangjianguo marked this pull request as ready for review August 30, 2026 07:26
@zhuangjianguo
zhuangjianguo added this pull request to the merge queueAug 30, 2026
Merged via the queue into main with commit 3355239Aug 30, 2026
28 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-5759-row-predicate-deprecation-note branch August 30, 2026 07:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published skills corpus still presents the row-predicate three-way binding as peers, with no sign that two of the three now warn (Phase 1 shipped)

3 participants

@zhuangjianguo@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(skills): mark the two non-canonical row-predicate spellings as deprecated by zhuangjianguo · Pull Request #6865 · objectstack-ai/objectui · GitHub
Skip to content

docs(skills): mark the two non-canonical row-predicate spellings as deprecated - #6865

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note
Aug 30, 2026
Merged

docs(skills): mark the two non-canonical row-predicate spellings as deprecated#6865
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes#5759

Prose-only annotation of the three-way row-predicate sentence in the published skills guide skills/objectui/guides/schema-expressions.md (List-view/CEL tier). It presented record.status, bare status and data.status as peers, labelling record.* merely "canonical" — a word that reads as a style preference — while since Phase 1 (#5330 / PR #5737) the other two emit a one-time dev-console deprecation warning and retire once a stored-metadata survey sizes the window.

What changed

One sentence, at :307. record.* is now stated as the canon; bare status and data.status are stated as deprecated here (still bound, warned once in dev, retiring after the survey), pointing at packages/core/src/evaluator/rowPredicateCanon.ts; and the card's sharper point is carried: data.* is the trap — the server's authoring oracle accepts it silently and it then binds nothing at runtime, a constant false rather than an error.

"Deprecated here" is deliberate, not hedging: rowPredicateCanon.ts scopes the deprecation to the runtime record layer, because data is the canonical root of a metadata-editing form (ADR-0089 D3). An unqualified sentence in this corpus would contradict that.

No example was rewritten — the nearby data-model-tier and conditional-formatting examples are already record.*.

State verified on this branch, not taken from the card

The card was filed 2026-08-23; the words had to describe what is measurable now. Read at base aca70f6:

  • listConditional.ts:273 still binds all three — { ...(opts.scope ?? {}), ...rowObj, data: rowObj, record: rowObj }. No spelling has been retired or turned into a refusal, so "still bound" is accurate and "retiring after a stored-metadata survey" is the correct tense.
  • listConditional.ts:317 calls warnNonCanonicalRowSpelling(predicateText, rowObj, !opts.rowless, opts.label) on the CEL path, so both non-canonical spellings do warn on this tier, and data names the row here (not rowless), which is the condition the detector needs.
  • rowPredicateCanon.ts still reads Phase 1: "the binding is UNCHANGED and every spelling still resolves", warn-once, "removable only after a stored-metadata survey".

Phase 2 (#5741) has not advanced past "warned".

Three-engine boundary held

Only the List-view/CEL row-predicate tier changed. The ${…}/On-suffix tier earlier in the file (SafeExpressionParser, where data.* is correct) and the flow tier (isFieldVisibleWhen, previews/screen-spec.ts) are untouched. The one-time-warning sentence at :316-317 belongs to legacy-syntax routing, a different mechanism from these spellings, and is untouched — the diff hunk stops above it.

Line-count readings (2026-08-21 whole-package ruling)

PM-set budget for this card: +4 lines max net on the file.

readingbeforeafternet
skills/objectui/guides/schema-expressions.md (whole file)621625+4
published bundle — all 18 .md under skills/56825686+4

git diff --stat: 1 file changed, 7 insertions(+), 3 deletions(-). The budget is met exactly; the wording was cut three times to reach it (measured by wrapping each candidate at the file's 78-column prose width before editing).

Gates — each line is the gate's own verdict, re-run on the final commit 7bcfefc

check-skills-paths ✅ OK (94/95 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-control-bytes ✅ OK (scanned 5714 tracked text file(s); skipped 85 binary).
check:doc-fences ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript ...
check-doc-links Links are valid across 17 scan roots.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
check-doc-component-types ✅ Every documented component type is registered.
check-shell-escape-residue ✅ OK (4/4 root(s) resolved -- ... skills: 18 file(s), 235 fence(s) ...).
vitest (4 files) Test Files 4 passed (4) · Tests 107 passed (107)

The vitest set is every test file that reads this corpus: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx, scripts/__tests__/check-skills-paths.test.ts, scripts/__tests__/check-control-bytes.test.ts, scripts/__tests__/doc-version-claims.test.ts.

check-skills-paths got a positive control rather than a bare green: calling its own exported extractPathTokens on the edited file returns the new token — { line: 310, token: 'packages/core/src/evaluator/rowPredicateCanon.ts', pattern: false } — so the 94/95 verdict demonstrably includes the path this PR added.

No changeset: skills/** is not published source of a released package, and the gate says so in its own words above.

Two declared narrowings

check:doc-snippets was NOT RUN. Its own exit is 2 — "PRECONDITION NOT MET ... This is 'I could not run', NOT 'I ran and found errors'" — because it needs 21 package build closures, a repo-wide build this shared box cannot host in a foreground window. Instead its judged population was measured directly through its own exported extractor, scanFences:

  • population read from the gate itself, not guessed: scanFences collects only ts/tsx fenced blocks; this file has exactly 1, at line 250 — above the edited hunk (307-313).
  • count from that output: 1 block at base aca70f6 and 1 at head, same fenceLine 250, bodies byte-identical.
  • counter-probe: appending a line to that block's body does change the extracted population, so "identical" is a measurement that could have failed rather than a vacuous pass.

pnpm lint was narrowed to nothing, on eslint's own answer.eslint --no-inline-config --format json on the changed file reports "File ignored because no matching configuration was supplied" — the repo's flat config matches no .md file at all, so the file count eslint judges in this diff is 0. No type-aware linting is configured, and the diff is one markdown file, so no untouched file's verdict can move either.

CI runs the full farm regardless; these two are the cheap local half, declared rather than silently skipped.

Governed-face handling

Left as draft for the PM's review chain — not flipped ready, not queued, no auto-merge. Note for the record: this repo's AGENTS.md §"受管面" explicitly places root skills/**outside the governed surface (only .claude/**, AGENTS.md, CLAUDE.md, docs/adr/** are governed there) and would permit self-merge on green. The dispatch treats the published skills corpus as governed for this fleet's review chain, which is the stricter of the two, so draft-only satisfies both. Flagged so the divergence is visible rather than assumed.


Generated by Claude Code

…eprecated
The List-view/CEL row-predicate sentence in the published skills guide still
presented `record.status`, bare `status` and `data.status` as peers, labelling
`record.*` merely "canonical" — a word that reads as a style preference. Since
Phase 1 (objectui#5330) the other two emit a one-time dev-console deprecation
warning and retire once a stored-metadata survey sizes the window, and
`data.*` is the arm the server's authoring oracle accepts silently while
binding nothing at runtime (a constant `false`, not an error).
Prose only, +4 lines net, scoped to the List-view/CEL tier: the `${…}`/`On`
tier (SafeExpressionParser, where `data.*` is correct) and the flow tier are
different engines and are untouched, as is the legacy-syntax routing sentence
below. The deprecation is stated as layer-scoped ("deprecated **here**"),
matching rowPredicateCanon.ts — `data` stays canonical in a metadata-editing
form per ADR-0089 D3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
@zhuangjianguo
zhuangjianguo marked this pull request as ready for review August 30, 2026 07:26
@zhuangjianguo
zhuangjianguo added this pull request to the merge queueAug 30, 2026
Merged via the queue into main with commit 3355239Aug 30, 2026
28 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-5759-row-predicate-deprecation-note branch August 30, 2026 07:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published skills corpus still presents the row-predicate three-way binding as peers, with no sign that two of the three now warn (Phase 1 shipped)

3 participants

@zhuangjianguo@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(skills): mark the two non-canonical row-predicate spellings as deprecated by zhuangjianguo · Pull Request #6865 · objectstack-ai/objectui · GitHub
Skip to content

docs(skills): mark the two non-canonical row-predicate spellings as deprecated - #6865

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note
Aug 30, 2026
Merged

docs(skills): mark the two non-canonical row-predicate spellings as deprecated#6865
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes#5759

Prose-only annotation of the three-way row-predicate sentence in the published skills guide skills/objectui/guides/schema-expressions.md (List-view/CEL tier). It presented record.status, bare status and data.status as peers, labelling record.* merely "canonical" — a word that reads as a style preference — while since Phase 1 (#5330 / PR #5737) the other two emit a one-time dev-console deprecation warning and retire once a stored-metadata survey sizes the window.

What changed

One sentence, at :307. record.* is now stated as the canon; bare status and data.status are stated as deprecated here (still bound, warned once in dev, retiring after the survey), pointing at packages/core/src/evaluator/rowPredicateCanon.ts; and the card's sharper point is carried: data.* is the trap — the server's authoring oracle accepts it silently and it then binds nothing at runtime, a constant false rather than an error.

"Deprecated here" is deliberate, not hedging: rowPredicateCanon.ts scopes the deprecation to the runtime record layer, because data is the canonical root of a metadata-editing form (ADR-0089 D3). An unqualified sentence in this corpus would contradict that.

No example was rewritten — the nearby data-model-tier and conditional-formatting examples are already record.*.

State verified on this branch, not taken from the card

The card was filed 2026-08-23; the words had to describe what is measurable now. Read at base aca70f6:

  • listConditional.ts:273 still binds all three — { ...(opts.scope ?? {}), ...rowObj, data: rowObj, record: rowObj }. No spelling has been retired or turned into a refusal, so "still bound" is accurate and "retiring after a stored-metadata survey" is the correct tense.
  • listConditional.ts:317 calls warnNonCanonicalRowSpelling(predicateText, rowObj, !opts.rowless, opts.label) on the CEL path, so both non-canonical spellings do warn on this tier, and data names the row here (not rowless), which is the condition the detector needs.
  • rowPredicateCanon.ts still reads Phase 1: "the binding is UNCHANGED and every spelling still resolves", warn-once, "removable only after a stored-metadata survey".

Phase 2 (#5741) has not advanced past "warned".

Three-engine boundary held

Only the List-view/CEL row-predicate tier changed. The ${…}/On-suffix tier earlier in the file (SafeExpressionParser, where data.* is correct) and the flow tier (isFieldVisibleWhen, previews/screen-spec.ts) are untouched. The one-time-warning sentence at :316-317 belongs to legacy-syntax routing, a different mechanism from these spellings, and is untouched — the diff hunk stops above it.

Line-count readings (2026-08-21 whole-package ruling)

PM-set budget for this card: +4 lines max net on the file.

readingbeforeafternet
skills/objectui/guides/schema-expressions.md (whole file)621625+4
published bundle — all 18 .md under skills/56825686+4

git diff --stat: 1 file changed, 7 insertions(+), 3 deletions(-). The budget is met exactly; the wording was cut three times to reach it (measured by wrapping each candidate at the file's 78-column prose width before editing).

Gates — each line is the gate's own verdict, re-run on the final commit 7bcfefc

check-skills-paths ✅ OK (94/95 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-control-bytes ✅ OK (scanned 5714 tracked text file(s); skipped 85 binary).
check:doc-fences ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript ...
check-doc-links Links are valid across 17 scan roots.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
check-doc-component-types ✅ Every documented component type is registered.
check-shell-escape-residue ✅ OK (4/4 root(s) resolved -- ... skills: 18 file(s), 235 fence(s) ...).
vitest (4 files) Test Files 4 passed (4) · Tests 107 passed (107)

The vitest set is every test file that reads this corpus: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx, scripts/__tests__/check-skills-paths.test.ts, scripts/__tests__/check-control-bytes.test.ts, scripts/__tests__/doc-version-claims.test.ts.

check-skills-paths got a positive control rather than a bare green: calling its own exported extractPathTokens on the edited file returns the new token — { line: 310, token: 'packages/core/src/evaluator/rowPredicateCanon.ts', pattern: false } — so the 94/95 verdict demonstrably includes the path this PR added.

No changeset: skills/** is not published source of a released package, and the gate says so in its own words above.

Two declared narrowings

check:doc-snippets was NOT RUN. Its own exit is 2 — "PRECONDITION NOT MET ... This is 'I could not run', NOT 'I ran and found errors'" — because it needs 21 package build closures, a repo-wide build this shared box cannot host in a foreground window. Instead its judged population was measured directly through its own exported extractor, scanFences:

  • population read from the gate itself, not guessed: scanFences collects only ts/tsx fenced blocks; this file has exactly 1, at line 250 — above the edited hunk (307-313).
  • count from that output: 1 block at base aca70f6 and 1 at head, same fenceLine 250, bodies byte-identical.
  • counter-probe: appending a line to that block's body does change the extracted population, so "identical" is a measurement that could have failed rather than a vacuous pass.

pnpm lint was narrowed to nothing, on eslint's own answer.eslint --no-inline-config --format json on the changed file reports "File ignored because no matching configuration was supplied" — the repo's flat config matches no .md file at all, so the file count eslint judges in this diff is 0. No type-aware linting is configured, and the diff is one markdown file, so no untouched file's verdict can move either.

CI runs the full farm regardless; these two are the cheap local half, declared rather than silently skipped.

Governed-face handling

Left as draft for the PM's review chain — not flipped ready, not queued, no auto-merge. Note for the record: this repo's AGENTS.md §"受管面" explicitly places root skills/**outside the governed surface (only .claude/**, AGENTS.md, CLAUDE.md, docs/adr/** are governed there) and would permit self-merge on green. The dispatch treats the published skills corpus as governed for this fleet's review chain, which is the stricter of the two, so draft-only satisfies both. Flagged so the divergence is visible rather than assumed.


Generated by Claude Code

…eprecated
The List-view/CEL row-predicate sentence in the published skills guide still
presented `record.status`, bare `status` and `data.status` as peers, labelling
`record.*` merely "canonical" — a word that reads as a style preference. Since
Phase 1 (objectui#5330) the other two emit a one-time dev-console deprecation
warning and retire once a stored-metadata survey sizes the window, and
`data.*` is the arm the server's authoring oracle accepts silently while
binding nothing at runtime (a constant `false`, not an error).
Prose only, +4 lines net, scoped to the List-view/CEL tier: the `${…}`/`On`
tier (SafeExpressionParser, where `data.*` is correct) and the flow tier are
different engines and are untouched, as is the legacy-syntax routing sentence
below. The deprecation is stated as layer-scoped ("deprecated **here**"),
matching rowPredicateCanon.ts — `data` stays canonical in a metadata-editing
form per ADR-0089 D3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
@zhuangjianguo
zhuangjianguo marked this pull request as ready for review August 30, 2026 07:26
@zhuangjianguo
zhuangjianguo added this pull request to the merge queueAug 30, 2026
Merged via the queue into main with commit 3355239Aug 30, 2026
28 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-5759-row-predicate-deprecation-note branch August 30, 2026 07:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published skills corpus still presents the row-predicate three-way binding as peers, with no sign that two of the three now warn (Phase 1 shipped)

3 participants

@zhuangjianguo@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' docs(skills): mark the two non-canonical row-predicate spellings as deprecated by zhuangjianguo · Pull Request #6865 · objectstack-ai/objectui · GitHub
Skip to content

docs(skills): mark the two non-canonical row-predicate spellings as deprecated - #6865

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note
Aug 30, 2026
Merged

docs(skills): mark the two non-canonical row-predicate spellings as deprecated#6865
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes#5759

Prose-only annotation of the three-way row-predicate sentence in the published skills guide skills/objectui/guides/schema-expressions.md (List-view/CEL tier). It presented record.status, bare status and data.status as peers, labelling record.* merely "canonical" — a word that reads as a style preference — while since Phase 1 (#5330 / PR #5737) the other two emit a one-time dev-console deprecation warning and retire once a stored-metadata survey sizes the window.

What changed

One sentence, at :307. record.* is now stated as the canon; bare status and data.status are stated as deprecated here (still bound, warned once in dev, retiring after the survey), pointing at packages/core/src/evaluator/rowPredicateCanon.ts; and the card's sharper point is carried: data.* is the trap — the server's authoring oracle accepts it silently and it then binds nothing at runtime, a constant false rather than an error.

"Deprecated here" is deliberate, not hedging: rowPredicateCanon.ts scopes the deprecation to the runtime record layer, because data is the canonical root of a metadata-editing form (ADR-0089 D3). An unqualified sentence in this corpus would contradict that.

No example was rewritten — the nearby data-model-tier and conditional-formatting examples are already record.*.

State verified on this branch, not taken from the card

The card was filed 2026-08-23; the words had to describe what is measurable now. Read at base aca70f6:

  • listConditional.ts:273 still binds all three — { ...(opts.scope ?? {}), ...rowObj, data: rowObj, record: rowObj }. No spelling has been retired or turned into a refusal, so "still bound" is accurate and "retiring after a stored-metadata survey" is the correct tense.
  • listConditional.ts:317 calls warnNonCanonicalRowSpelling(predicateText, rowObj, !opts.rowless, opts.label) on the CEL path, so both non-canonical spellings do warn on this tier, and data names the row here (not rowless), which is the condition the detector needs.
  • rowPredicateCanon.ts still reads Phase 1: "the binding is UNCHANGED and every spelling still resolves", warn-once, "removable only after a stored-metadata survey".

Phase 2 (#5741) has not advanced past "warned".

Three-engine boundary held

Only the List-view/CEL row-predicate tier changed. The ${…}/On-suffix tier earlier in the file (SafeExpressionParser, where data.* is correct) and the flow tier (isFieldVisibleWhen, previews/screen-spec.ts) are untouched. The one-time-warning sentence at :316-317 belongs to legacy-syntax routing, a different mechanism from these spellings, and is untouched — the diff hunk stops above it.

Line-count readings (2026-08-21 whole-package ruling)

PM-set budget for this card: +4 lines max net on the file.

readingbeforeafternet
skills/objectui/guides/schema-expressions.md (whole file)621625+4
published bundle — all 18 .md under skills/56825686+4

git diff --stat: 1 file changed, 7 insertions(+), 3 deletions(-). The budget is met exactly; the wording was cut three times to reach it (measured by wrapping each candidate at the file's 78-column prose width before editing).

Gates — each line is the gate's own verdict, re-run on the final commit 7bcfefc

check-skills-paths ✅ OK (94/95 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-control-bytes ✅ OK (scanned 5714 tracked text file(s); skipped 85 binary).
check:doc-fences ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript ...
check-doc-links Links are valid across 17 scan roots.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
check-doc-component-types ✅ Every documented component type is registered.
check-shell-escape-residue ✅ OK (4/4 root(s) resolved -- ... skills: 18 file(s), 235 fence(s) ...).
vitest (4 files) Test Files 4 passed (4) · Tests 107 passed (107)

The vitest set is every test file that reads this corpus: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx, scripts/__tests__/check-skills-paths.test.ts, scripts/__tests__/check-control-bytes.test.ts, scripts/__tests__/doc-version-claims.test.ts.

check-skills-paths got a positive control rather than a bare green: calling its own exported extractPathTokens on the edited file returns the new token — { line: 310, token: 'packages/core/src/evaluator/rowPredicateCanon.ts', pattern: false } — so the 94/95 verdict demonstrably includes the path this PR added.

No changeset: skills/** is not published source of a released package, and the gate says so in its own words above.

Two declared narrowings

check:doc-snippets was NOT RUN. Its own exit is 2 — "PRECONDITION NOT MET ... This is 'I could not run', NOT 'I ran and found errors'" — because it needs 21 package build closures, a repo-wide build this shared box cannot host in a foreground window. Instead its judged population was measured directly through its own exported extractor, scanFences:

  • population read from the gate itself, not guessed: scanFences collects only ts/tsx fenced blocks; this file has exactly 1, at line 250 — above the edited hunk (307-313).
  • count from that output: 1 block at base aca70f6 and 1 at head, same fenceLine 250, bodies byte-identical.
  • counter-probe: appending a line to that block's body does change the extracted population, so "identical" is a measurement that could have failed rather than a vacuous pass.

pnpm lint was narrowed to nothing, on eslint's own answer.eslint --no-inline-config --format json on the changed file reports "File ignored because no matching configuration was supplied" — the repo's flat config matches no .md file at all, so the file count eslint judges in this diff is 0. No type-aware linting is configured, and the diff is one markdown file, so no untouched file's verdict can move either.

CI runs the full farm regardless; these two are the cheap local half, declared rather than silently skipped.

Governed-face handling

Left as draft for the PM's review chain — not flipped ready, not queued, no auto-merge. Note for the record: this repo's AGENTS.md §"受管面" explicitly places root skills/**outside the governed surface (only .claude/**, AGENTS.md, CLAUDE.md, docs/adr/** are governed there) and would permit self-merge on green. The dispatch treats the published skills corpus as governed for this fleet's review chain, which is the stricter of the two, so draft-only satisfies both. Flagged so the divergence is visible rather than assumed.


Generated by Claude Code

…eprecated
The List-view/CEL row-predicate sentence in the published skills guide still
presented `record.status`, bare `status` and `data.status` as peers, labelling
`record.*` merely "canonical" — a word that reads as a style preference. Since
Phase 1 (objectui#5330) the other two emit a one-time dev-console deprecation
warning and retire once a stored-metadata survey sizes the window, and
`data.*` is the arm the server's authoring oracle accepts silently while
binding nothing at runtime (a constant `false`, not an error).
Prose only, +4 lines net, scoped to the List-view/CEL tier: the `${…}`/`On`
tier (SafeExpressionParser, where `data.*` is correct) and the flow tier are
different engines and are untouched, as is the legacy-syntax routing sentence
below. The deprecation is stated as layer-scoped ("deprecated **here**"),
matching rowPredicateCanon.ts — `data` stays canonical in a metadata-editing
form per ADR-0089 D3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
@zhuangjianguo
zhuangjianguo marked this pull request as ready for review August 30, 2026 07:26
@zhuangjianguo
zhuangjianguo added this pull request to the merge queueAug 30, 2026
Merged via the queue into main with commit 3355239Aug 30, 2026
28 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-5759-row-predicate-deprecation-note branch August 30, 2026 07:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published skills corpus still presents the row-predicate three-way binding as peers, with no sign that two of the three now warn (Phase 1 shipped)

3 participants

@zhuangjianguo@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(skills): mark the two non-canonical row-predicate spellings as deprecated by zhuangjianguo · Pull Request #6865 · objectstack-ai/objectui · GitHub
Skip to content

docs(skills): mark the two non-canonical row-predicate spellings as deprecated - #6865

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note
Aug 30, 2026
Merged

docs(skills): mark the two non-canonical row-predicate spellings as deprecated#6865
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes#5759

Prose-only annotation of the three-way row-predicate sentence in the published skills guide skills/objectui/guides/schema-expressions.md (List-view/CEL tier). It presented record.status, bare status and data.status as peers, labelling record.* merely "canonical" — a word that reads as a style preference — while since Phase 1 (#5330 / PR #5737) the other two emit a one-time dev-console deprecation warning and retire once a stored-metadata survey sizes the window.

What changed

One sentence, at :307. record.* is now stated as the canon; bare status and data.status are stated as deprecated here (still bound, warned once in dev, retiring after the survey), pointing at packages/core/src/evaluator/rowPredicateCanon.ts; and the card's sharper point is carried: data.* is the trap — the server's authoring oracle accepts it silently and it then binds nothing at runtime, a constant false rather than an error.

"Deprecated here" is deliberate, not hedging: rowPredicateCanon.ts scopes the deprecation to the runtime record layer, because data is the canonical root of a metadata-editing form (ADR-0089 D3). An unqualified sentence in this corpus would contradict that.

No example was rewritten — the nearby data-model-tier and conditional-formatting examples are already record.*.

State verified on this branch, not taken from the card

The card was filed 2026-08-23; the words had to describe what is measurable now. Read at base aca70f6:

  • listConditional.ts:273 still binds all three — { ...(opts.scope ?? {}), ...rowObj, data: rowObj, record: rowObj }. No spelling has been retired or turned into a refusal, so "still bound" is accurate and "retiring after a stored-metadata survey" is the correct tense.
  • listConditional.ts:317 calls warnNonCanonicalRowSpelling(predicateText, rowObj, !opts.rowless, opts.label) on the CEL path, so both non-canonical spellings do warn on this tier, and data names the row here (not rowless), which is the condition the detector needs.
  • rowPredicateCanon.ts still reads Phase 1: "the binding is UNCHANGED and every spelling still resolves", warn-once, "removable only after a stored-metadata survey".

Phase 2 (#5741) has not advanced past "warned".

Three-engine boundary held

Only the List-view/CEL row-predicate tier changed. The ${…}/On-suffix tier earlier in the file (SafeExpressionParser, where data.* is correct) and the flow tier (isFieldVisibleWhen, previews/screen-spec.ts) are untouched. The one-time-warning sentence at :316-317 belongs to legacy-syntax routing, a different mechanism from these spellings, and is untouched — the diff hunk stops above it.

Line-count readings (2026-08-21 whole-package ruling)

PM-set budget for this card: +4 lines max net on the file.

readingbeforeafternet
skills/objectui/guides/schema-expressions.md (whole file)621625+4
published bundle — all 18 .md under skills/56825686+4

git diff --stat: 1 file changed, 7 insertions(+), 3 deletions(-). The budget is met exactly; the wording was cut three times to reach it (measured by wrapping each candidate at the file's 78-column prose width before editing).

Gates — each line is the gate's own verdict, re-run on the final commit 7bcfefc

check-skills-paths ✅ OK (94/95 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-control-bytes ✅ OK (scanned 5714 tracked text file(s); skipped 85 binary).
check:doc-fences ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript ...
check-doc-links Links are valid across 17 scan roots.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
check-doc-component-types ✅ Every documented component type is registered.
check-shell-escape-residue ✅ OK (4/4 root(s) resolved -- ... skills: 18 file(s), 235 fence(s) ...).
vitest (4 files) Test Files 4 passed (4) · Tests 107 passed (107)

The vitest set is every test file that reads this corpus: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx, scripts/__tests__/check-skills-paths.test.ts, scripts/__tests__/check-control-bytes.test.ts, scripts/__tests__/doc-version-claims.test.ts.

check-skills-paths got a positive control rather than a bare green: calling its own exported extractPathTokens on the edited file returns the new token — { line: 310, token: 'packages/core/src/evaluator/rowPredicateCanon.ts', pattern: false } — so the 94/95 verdict demonstrably includes the path this PR added.

No changeset: skills/** is not published source of a released package, and the gate says so in its own words above.

Two declared narrowings

check:doc-snippets was NOT RUN. Its own exit is 2 — "PRECONDITION NOT MET ... This is 'I could not run', NOT 'I ran and found errors'" — because it needs 21 package build closures, a repo-wide build this shared box cannot host in a foreground window. Instead its judged population was measured directly through its own exported extractor, scanFences:

  • population read from the gate itself, not guessed: scanFences collects only ts/tsx fenced blocks; this file has exactly 1, at line 250 — above the edited hunk (307-313).
  • count from that output: 1 block at base aca70f6 and 1 at head, same fenceLine 250, bodies byte-identical.
  • counter-probe: appending a line to that block's body does change the extracted population, so "identical" is a measurement that could have failed rather than a vacuous pass.

pnpm lint was narrowed to nothing, on eslint's own answer.eslint --no-inline-config --format json on the changed file reports "File ignored because no matching configuration was supplied" — the repo's flat config matches no .md file at all, so the file count eslint judges in this diff is 0. No type-aware linting is configured, and the diff is one markdown file, so no untouched file's verdict can move either.

CI runs the full farm regardless; these two are the cheap local half, declared rather than silently skipped.

Governed-face handling

Left as draft for the PM's review chain — not flipped ready, not queued, no auto-merge. Note for the record: this repo's AGENTS.md §"受管面" explicitly places root skills/**outside the governed surface (only .claude/**, AGENTS.md, CLAUDE.md, docs/adr/** are governed there) and would permit self-merge on green. The dispatch treats the published skills corpus as governed for this fleet's review chain, which is the stricter of the two, so draft-only satisfies both. Flagged so the divergence is visible rather than assumed.


Generated by Claude Code

…eprecated
The List-view/CEL row-predicate sentence in the published skills guide still
presented `record.status`, bare `status` and `data.status` as peers, labelling
`record.*` merely "canonical" — a word that reads as a style preference. Since
Phase 1 (objectui#5330) the other two emit a one-time dev-console deprecation
warning and retire once a stored-metadata survey sizes the window, and
`data.*` is the arm the server's authoring oracle accepts silently while
binding nothing at runtime (a constant `false`, not an error).
Prose only, +4 lines net, scoped to the List-view/CEL tier: the `${…}`/`On`
tier (SafeExpressionParser, where `data.*` is correct) and the flow tier are
different engines and are untouched, as is the legacy-syntax routing sentence
below. The deprecation is stated as layer-scoped ("deprecated **here**"),
matching rowPredicateCanon.ts — `data` stays canonical in a metadata-editing
form per ADR-0089 D3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
@zhuangjianguo
zhuangjianguo marked this pull request as ready for review August 30, 2026 07:26
@zhuangjianguo
zhuangjianguo added this pull request to the merge queueAug 30, 2026
Merged via the queue into main with commit 3355239Aug 30, 2026
28 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-5759-row-predicate-deprecation-note branch August 30, 2026 07:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published skills corpus still presents the row-predicate three-way binding as peers, with no sign that two of the three now warn (Phase 1 shipped)

3 participants

@zhuangjianguo@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(skills): mark the two non-canonical row-predicate spellings as deprecated by zhuangjianguo · Pull Request #6865 · objectstack-ai/objectui · GitHub
Skip to content

docs(skills): mark the two non-canonical row-predicate spellings as deprecated - #6865

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note
Aug 30, 2026
Merged

docs(skills): mark the two non-canonical row-predicate spellings as deprecated#6865
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes#5759

Prose-only annotation of the three-way row-predicate sentence in the published skills guide skills/objectui/guides/schema-expressions.md (List-view/CEL tier). It presented record.status, bare status and data.status as peers, labelling record.* merely "canonical" — a word that reads as a style preference — while since Phase 1 (#5330 / PR #5737) the other two emit a one-time dev-console deprecation warning and retire once a stored-metadata survey sizes the window.

What changed

One sentence, at :307. record.* is now stated as the canon; bare status and data.status are stated as deprecated here (still bound, warned once in dev, retiring after the survey), pointing at packages/core/src/evaluator/rowPredicateCanon.ts; and the card's sharper point is carried: data.* is the trap — the server's authoring oracle accepts it silently and it then binds nothing at runtime, a constant false rather than an error.

"Deprecated here" is deliberate, not hedging: rowPredicateCanon.ts scopes the deprecation to the runtime record layer, because data is the canonical root of a metadata-editing form (ADR-0089 D3). An unqualified sentence in this corpus would contradict that.

No example was rewritten — the nearby data-model-tier and conditional-formatting examples are already record.*.

State verified on this branch, not taken from the card

The card was filed 2026-08-23; the words had to describe what is measurable now. Read at base aca70f6:

  • listConditional.ts:273 still binds all three — { ...(opts.scope ?? {}), ...rowObj, data: rowObj, record: rowObj }. No spelling has been retired or turned into a refusal, so "still bound" is accurate and "retiring after a stored-metadata survey" is the correct tense.
  • listConditional.ts:317 calls warnNonCanonicalRowSpelling(predicateText, rowObj, !opts.rowless, opts.label) on the CEL path, so both non-canonical spellings do warn on this tier, and data names the row here (not rowless), which is the condition the detector needs.
  • rowPredicateCanon.ts still reads Phase 1: "the binding is UNCHANGED and every spelling still resolves", warn-once, "removable only after a stored-metadata survey".

Phase 2 (#5741) has not advanced past "warned".

Three-engine boundary held

Only the List-view/CEL row-predicate tier changed. The ${…}/On-suffix tier earlier in the file (SafeExpressionParser, where data.* is correct) and the flow tier (isFieldVisibleWhen, previews/screen-spec.ts) are untouched. The one-time-warning sentence at :316-317 belongs to legacy-syntax routing, a different mechanism from these spellings, and is untouched — the diff hunk stops above it.

Line-count readings (2026-08-21 whole-package ruling)

PM-set budget for this card: +4 lines max net on the file.

readingbeforeafternet
skills/objectui/guides/schema-expressions.md (whole file)621625+4
published bundle — all 18 .md under skills/56825686+4

git diff --stat: 1 file changed, 7 insertions(+), 3 deletions(-). The budget is met exactly; the wording was cut three times to reach it (measured by wrapping each candidate at the file's 78-column prose width before editing).

Gates — each line is the gate's own verdict, re-run on the final commit 7bcfefc

check-skills-paths ✅ OK (94/95 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-control-bytes ✅ OK (scanned 5714 tracked text file(s); skipped 85 binary).
check:doc-fences ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript ...
check-doc-links Links are valid across 17 scan roots.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
check-doc-component-types ✅ Every documented component type is registered.
check-shell-escape-residue ✅ OK (4/4 root(s) resolved -- ... skills: 18 file(s), 235 fence(s) ...).
vitest (4 files) Test Files 4 passed (4) · Tests 107 passed (107)

The vitest set is every test file that reads this corpus: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx, scripts/__tests__/check-skills-paths.test.ts, scripts/__tests__/check-control-bytes.test.ts, scripts/__tests__/doc-version-claims.test.ts.

check-skills-paths got a positive control rather than a bare green: calling its own exported extractPathTokens on the edited file returns the new token — { line: 310, token: 'packages/core/src/evaluator/rowPredicateCanon.ts', pattern: false } — so the 94/95 verdict demonstrably includes the path this PR added.

No changeset: skills/** is not published source of a released package, and the gate says so in its own words above.

Two declared narrowings

check:doc-snippets was NOT RUN. Its own exit is 2 — "PRECONDITION NOT MET ... This is 'I could not run', NOT 'I ran and found errors'" — because it needs 21 package build closures, a repo-wide build this shared box cannot host in a foreground window. Instead its judged population was measured directly through its own exported extractor, scanFences:

  • population read from the gate itself, not guessed: scanFences collects only ts/tsx fenced blocks; this file has exactly 1, at line 250 — above the edited hunk (307-313).
  • count from that output: 1 block at base aca70f6 and 1 at head, same fenceLine 250, bodies byte-identical.
  • counter-probe: appending a line to that block's body does change the extracted population, so "identical" is a measurement that could have failed rather than a vacuous pass.

pnpm lint was narrowed to nothing, on eslint's own answer.eslint --no-inline-config --format json on the changed file reports "File ignored because no matching configuration was supplied" — the repo's flat config matches no .md file at all, so the file count eslint judges in this diff is 0. No type-aware linting is configured, and the diff is one markdown file, so no untouched file's verdict can move either.

CI runs the full farm regardless; these two are the cheap local half, declared rather than silently skipped.

Governed-face handling

Left as draft for the PM's review chain — not flipped ready, not queued, no auto-merge. Note for the record: this repo's AGENTS.md §"受管面" explicitly places root skills/**outside the governed surface (only .claude/**, AGENTS.md, CLAUDE.md, docs/adr/** are governed there) and would permit self-merge on green. The dispatch treats the published skills corpus as governed for this fleet's review chain, which is the stricter of the two, so draft-only satisfies both. Flagged so the divergence is visible rather than assumed.


Generated by Claude Code

…eprecated
The List-view/CEL row-predicate sentence in the published skills guide still
presented `record.status`, bare `status` and `data.status` as peers, labelling
`record.*` merely "canonical" — a word that reads as a style preference. Since
Phase 1 (objectui#5330) the other two emit a one-time dev-console deprecation
warning and retire once a stored-metadata survey sizes the window, and
`data.*` is the arm the server's authoring oracle accepts silently while
binding nothing at runtime (a constant `false`, not an error).
Prose only, +4 lines net, scoped to the List-view/CEL tier: the `${…}`/`On`
tier (SafeExpressionParser, where `data.*` is correct) and the flow tier are
different engines and are untouched, as is the legacy-syntax routing sentence
below. The deprecation is stated as layer-scoped ("deprecated **here**"),
matching rowPredicateCanon.ts — `data` stays canonical in a metadata-editing
form per ADR-0089 D3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
@zhuangjianguo
zhuangjianguo marked this pull request as ready for review August 30, 2026 07:26
@zhuangjianguo
zhuangjianguo added this pull request to the merge queueAug 30, 2026
Merged via the queue into main with commit 3355239Aug 30, 2026
28 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-5759-row-predicate-deprecation-note branch August 30, 2026 07:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published skills corpus still presents the row-predicate three-way binding as peers, with no sign that two of the three now warn (Phase 1 shipped)

3 participants

@zhuangjianguo@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); docs(skills): mark the two non-canonical row-predicate spellings as deprecated by zhuangjianguo · Pull Request #6865 · objectstack-ai/objectui · GitHub
Skip to content

docs(skills): mark the two non-canonical row-predicate spellings as deprecated - #6865

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note
Aug 30, 2026
Merged

docs(skills): mark the two non-canonical row-predicate spellings as deprecated#6865
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-5759-row-predicate-deprecation-note

Conversation

@zhuangjianguo

Copy link
Copy Markdown
Collaborator

Fixes#5759

Prose-only annotation of the three-way row-predicate sentence in the published skills guide skills/objectui/guides/schema-expressions.md (List-view/CEL tier). It presented record.status, bare status and data.status as peers, labelling record.* merely "canonical" — a word that reads as a style preference — while since Phase 1 (#5330 / PR #5737) the other two emit a one-time dev-console deprecation warning and retire once a stored-metadata survey sizes the window.

What changed

One sentence, at :307. record.* is now stated as the canon; bare status and data.status are stated as deprecated here (still bound, warned once in dev, retiring after the survey), pointing at packages/core/src/evaluator/rowPredicateCanon.ts; and the card's sharper point is carried: data.* is the trap — the server's authoring oracle accepts it silently and it then binds nothing at runtime, a constant false rather than an error.

"Deprecated here" is deliberate, not hedging: rowPredicateCanon.ts scopes the deprecation to the runtime record layer, because data is the canonical root of a metadata-editing form (ADR-0089 D3). An unqualified sentence in this corpus would contradict that.

No example was rewritten — the nearby data-model-tier and conditional-formatting examples are already record.*.

State verified on this branch, not taken from the card

The card was filed 2026-08-23; the words had to describe what is measurable now. Read at base aca70f6:

  • listConditional.ts:273 still binds all three — { ...(opts.scope ?? {}), ...rowObj, data: rowObj, record: rowObj }. No spelling has been retired or turned into a refusal, so "still bound" is accurate and "retiring after a stored-metadata survey" is the correct tense.
  • listConditional.ts:317 calls warnNonCanonicalRowSpelling(predicateText, rowObj, !opts.rowless, opts.label) on the CEL path, so both non-canonical spellings do warn on this tier, and data names the row here (not rowless), which is the condition the detector needs.
  • rowPredicateCanon.ts still reads Phase 1: "the binding is UNCHANGED and every spelling still resolves", warn-once, "removable only after a stored-metadata survey".

Phase 2 (#5741) has not advanced past "warned".

Three-engine boundary held

Only the List-view/CEL row-predicate tier changed. The ${…}/On-suffix tier earlier in the file (SafeExpressionParser, where data.* is correct) and the flow tier (isFieldVisibleWhen, previews/screen-spec.ts) are untouched. The one-time-warning sentence at :316-317 belongs to legacy-syntax routing, a different mechanism from these spellings, and is untouched — the diff hunk stops above it.

Line-count readings (2026-08-21 whole-package ruling)

PM-set budget for this card: +4 lines max net on the file.

readingbeforeafternet
skills/objectui/guides/schema-expressions.md (whole file)621625+4
published bundle — all 18 .md under skills/56825686+4

git diff --stat: 1 file changed, 7 insertions(+), 3 deletions(-). The budget is met exactly; the wording was cut three times to reach it (measured by wrapping each candidate at the file's 78-column prose width before editing).

Gates — each line is the gate's own verdict, re-run on the final commit 7bcfefc

check-skills-paths ✅ OK (94/95 stated path(s) resolve across 18 guide file(s); 1 baselined).
check-control-bytes ✅ OK (scanned 5714 tracked text file(s); skipped 85 binary).
check:doc-fences ✅ every TypeScript block in 223 document(s) is fenced ts/tsx/typescript ...
check-doc-links Links are valid across 17 scan roots.
check-changeset-presence ✅ No source of a released package changed in this range, so no changeset is owed.
check-doc-component-types ✅ Every documented component type is registered.
check-shell-escape-residue ✅ OK (4/4 root(s) resolved -- ... skills: 18 file(s), 235 fence(s) ...).
vitest (4 files) Test Files 4 passed (4) · Tests 107 passed (107)

The vitest set is every test file that reads this corpus: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx, scripts/__tests__/check-skills-paths.test.ts, scripts/__tests__/check-control-bytes.test.ts, scripts/__tests__/doc-version-claims.test.ts.

check-skills-paths got a positive control rather than a bare green: calling its own exported extractPathTokens on the edited file returns the new token — { line: 310, token: 'packages/core/src/evaluator/rowPredicateCanon.ts', pattern: false } — so the 94/95 verdict demonstrably includes the path this PR added.

No changeset: skills/** is not published source of a released package, and the gate says so in its own words above.

Two declared narrowings

check:doc-snippets was NOT RUN. Its own exit is 2 — "PRECONDITION NOT MET ... This is 'I could not run', NOT 'I ran and found errors'" — because it needs 21 package build closures, a repo-wide build this shared box cannot host in a foreground window. Instead its judged population was measured directly through its own exported extractor, scanFences:

  • population read from the gate itself, not guessed: scanFences collects only ts/tsx fenced blocks; this file has exactly 1, at line 250 — above the edited hunk (307-313).
  • count from that output: 1 block at base aca70f6 and 1 at head, same fenceLine 250, bodies byte-identical.
  • counter-probe: appending a line to that block's body does change the extracted population, so "identical" is a measurement that could have failed rather than a vacuous pass.

pnpm lint was narrowed to nothing, on eslint's own answer.eslint --no-inline-config --format json on the changed file reports "File ignored because no matching configuration was supplied" — the repo's flat config matches no .md file at all, so the file count eslint judges in this diff is 0. No type-aware linting is configured, and the diff is one markdown file, so no untouched file's verdict can move either.

CI runs the full farm regardless; these two are the cheap local half, declared rather than silently skipped.

Governed-face handling

Left as draft for the PM's review chain — not flipped ready, not queued, no auto-merge. Note for the record: this repo's AGENTS.md §"受管面" explicitly places root skills/**outside the governed surface (only .claude/**, AGENTS.md, CLAUDE.md, docs/adr/** are governed there) and would permit self-merge on green. The dispatch treats the published skills corpus as governed for this fleet's review chain, which is the stricter of the two, so draft-only satisfies both. Flagged so the divergence is visible rather than assumed.


Generated by Claude Code

…eprecated
The List-view/CEL row-predicate sentence in the published skills guide still
presented `record.status`, bare `status` and `data.status` as peers, labelling
`record.*` merely "canonical" — a word that reads as a style preference. Since
Phase 1 (objectui#5330) the other two emit a one-time dev-console deprecation
warning and retire once a stored-metadata survey sizes the window, and
`data.*` is the arm the server's authoring oracle accepts silently while
binding nothing at runtime (a constant `false`, not an error).
Prose only, +4 lines net, scoped to the List-view/CEL tier: the `${…}`/`On`
tier (SafeExpressionParser, where `data.*` is correct) and the flow tier are
different engines and are untouched, as is the legacy-syntax routing sentence
below. The deprecation is stated as layer-scoped ("deprecated **here**"),
matching rowPredicateCanon.ts — `data` stays canonical in a metadata-editing
form per ADR-0089 D3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
@zhuangjianguo
zhuangjianguo marked this pull request as ready for review August 30, 2026 07:26
@zhuangjianguo
zhuangjianguo added this pull request to the merge queueAug 30, 2026
Merged via the queue into main with commit 3355239Aug 30, 2026
28 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-5759-row-predicate-deprecation-note branch August 30, 2026 07:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The published skills corpus still presents the row-predicate three-way binding as peers, with no sign that two of the three now warn (Phase 1 shipped)

3 participants

@zhuangjianguo@os-zhuang@claude