docs(changelog): correct three false sentences in the published 17.3.0 release text — the reversed depends_on justification and the ListView binding paragraph in both CHANGELOGs - #16881
Conversation
…0 release text Two cards were filed against pending .changeset/*.md files. A release consumed both, so the false prose now lives in packages/spec/CHANGELOG.md and packages/lint/CHANGELOG.md, which ship to npm inside the tarballs (CHANGELOG.md is listed in files[] for both packages). Released CHANGELOG text is treated as release-owned, so this is a dedicated docs-only PR riding on no code change. Card 15058, packages/spec/CHANGELOG.md. The option-description bullet justified not declaring dependsOn with "the canonical field-level depends_on already exists". That is backwards. @objectstack/spec declares dependsOn, refuses depends_on with a rename hint pointing the other way, and declares no depends_on key anywhere. Measured at the entry's own commit 86e765a: git grep for depends_on across packages/spec/src/**/*.zod.ts returns exactly one hit, the false claim itself in a comment, against a positive control of six dependsOn hits over three files at the same ref. So the claim was false when it was written, not merely overtaken. The replacement matches the wording PR 15055 already landed at the source site in field.zod.ts rather than inventing a fifth phrasing of the same fact. Card 15026, both files, one byte-identical sentence in each. The 5383fa6 entry told authors the lint accepts either ListView spelling as satisfying the required binding, resolves field-name props against whichever is present, and prefers canonical when both are. All three clauses are the other way round today, and were already so at the moment this text shipped: 22b0081 landed 2026-09-03 and 8a1bad8 cut 17.3.0 on 2026-09-04, both ancestors of the cut (git merge-base --is-ancestor, exit 0, with a control leg on 5383fa6 also exit 0). Measured in packages/lint/src/validate-react-page-props.ts on this tree: boundObjectName reads objectName only; objectProviderBindsNothing makes a provider:'object' data binding fail the required binding; and the docblock states the renderer reads objectName when an author writes both. Step 3 of the ruling, which retires the aliases, has not landed - card 14791 is open and the UNFOLDED_DEPRECATIONS set it deletes is still present, so the corrected text says objectName / viewType remain the spellings to write. Both corrections keep the true half of each sentence and preserve the record of what shipped, naming the card that moved the fact - the shape PR 16856 and PR 16874 used on the same file family. Nothing is restated as though it had always been so. Docs-only: the diff touches two files and three lines. Zero paths under content/docs/releases/ (grep count 0 exit 1, with a positive control of 2 on ^packages/ over the same pipeline, and that directory holds 10 entries). No code, no test, no changeset. No test or gate parses CHANGELOG.md content; the two that name it exclude it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
📓 Docs Drift Check
What this run could not see
Coarse fallback — 131 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
…carries it, and reconcile the entry's closing sentence
Seat finding on the draft: the corrected ListView paragraph said "retiring the
aliases is step 3 of this ruling, unlanded and still open as 14791", which
understated the state and left the paragraph contradicting its own closing
sentence ("Removal of the deprecated aliases is a later card after the
deprecation window") - one paragraph making two incompatible claims about
whether that card exists.
Measured rather than assumed, because two sources disagreed. Card 14791's TITLE
is the renderer-half finding, but the maintainer ruled option B ON that card on
2026-09-07 (comment 5572008848, verbatim "同意"): "step 3 retires objectName /
viewType on the ListView block now; no deprecation window". It was dispatched
2026-09-08T02:36Z and implemented as PR 16777, "feat(spec)!: retire the
ListView objectName / viewType react-tier aliases - data / type are the only
spellings", read from the API as open, draft, head 5b010e0, awaiting a
maintainer merge because it touches governed skills/**. So 14791 is both, and
naming the PR gives a reader the precise artifact instead of a title about
something else.
Also measured, and it falsified the other half of the old clause: the renderer
fold has already landed. At the pinned .objectui-sha 53ded82bf, git grep for
"provider === 'object'" in packages/core/src/utils/normalize-list-view.ts
returns 2 hits, exit 0 - :263 is a comment and :315 is the substantive fold
(dataConfig?.provider === 'object' && typeof dataConfig.object === 'string'),
the trap card 14791 names in its own body. Positive control at the same pin:
normalizeListViewSchema, 1 hit. So "until the renderer folds the canonical data
source in" was no longer a pending condition and is dropped.
The closing sentence is corrected under the bounded in-place exemption, all
four conditions holding: same defect class as this card (a false sentence in
this exact published entry), mechanical and in the register already pinned by
this PR, no other claim holds these files, and no new verification surface. It
is declared in the PR body rather than left silent.
Both copies moved together - the replacement is byte-identical in
packages/spec/CHANGELOG.md and packages/lint/CHANGELOG.md, sha1
482ecf56686847ed419e482c75ed04dde917bcc0, cmp exit 0, 1899 bytes. Fixing one
and leaving the other is this card's signature failure mode. Still docs-only:
2 files, +3/-3, zero paths under content/docs/releases/.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
ACCEPT — and the seat's finding that triggered this round was half wrong, which the dev caught by measuring instead of obeying
⭐ I told this dev that #14791 is not the retirement card. It is.My finding said: "#14791 is the RENDERER half … It is NOT the alias-retirement card." The dev did not take that at face value. It read the card's comments and found the maintainer's ruling, which I verified myself before writing this — comment
⇒ #14791 carries the ruled retirement. What made a bare The second half of the old clause, also measured and also gone"until the renderer folds the canonical data source in" was carried as a pending condition. The dev measured the pinned The closing sentence, corrected under the bounded in-place exemption — ⭐ and correctly, because leaving it would have made my own requested edit produce a contradictionThe entry ended "Removal of the deprecated aliases is a later card after the deprecation window". The 2026-09-07 ruling removed the deprecation window, and the card exists. Left alone, the corrected paragraph would have said both "the retirement is ruled and authored" and "a later card after the deprecation window" — exactly the internal inconsistency I sent this back to fix, reintroduced one clause over. Correcting it in the same pass, declared in the PR body, is the right call. Verified by this seat, ⛔ not accepted on the report
On the two things the dev refused to settle
⛔ Not enqueued yet: 34 checks, 17 still running on Generated by Claude Code |
Fixes #15058
Fixes #15026
A dedicated docs-only PR, riding on no code change. Both cards were filed against pending
.changeset/*.mdfiles; a release consumed both, and the false prose now lives in published CHANGELOGs that ship to npm. Triage ruled the successor route on 2026-09-08 (#15058 T10:39:49Z, #15026 T10:40:36Z): released CHANGELOG text is release-owned, so it is never modified from a code PR.Diff: 2 files, 3 lines. No code, no test, no changeset, no
.changeset/**edit.Premise re-verified on this branch's base
a5d4e286b, not read from the card bodiesthe canonical field-level depends_on already existspackages/spec/CHANGELOG.mdThe lint accepts either spellingpackages/spec/CHANGELOG.mdThe lint accepts either spellingpackages/lint/CHANGELOG.mdPositive controls that the files are live: 81752 and 17812 lines. All four sites sit under the same released heading
## 17.3.0, cut by8a1bad8b8.Correction 1 — #15058,
packages/spec/CHANGELOG.mdThe bullet justified not declaring
dependsOnwith "the canonical field-leveldepends_onalready exists". It is backwards:@objectstack/specdeclares the camelCasedependsOnand refusesdepends_onwith a rename hint that points the other way;depends_onis objectui's own consumer-sideBaseFieldMetadataspelling.Triage's probe table is quoted, not re-derived. What this PR did measure is that the claim was false when it was written, which the correction now states — at the entry's own commit
86e765a:Wording matches PR #15055, which already landed the same fact at its source in
field.zod.ts, rather than inventing a fifth phrasing. Confirmed landed:d261cefaaonorigin/main.Correction 2 — #15026, both
packages/spec/CHANGELOG.mdandpackages/lint/CHANGELOG.mdFixing one and leaving the other is this card's exact failure mode, so the replacement is byte-identical in both files at every revision — after the seat correction,
sha1 482ecf56686847ed419e482c75ed04dde917bcc0,cmpexit 0, 1899 bytes.All three clauses of the published sentence are the other way round, and were already so at the moment the text shipped:
Measured in
packages/lint/src/validate-react-page-props.tson this tree:boundObjectNamereadsobjectNameonly;objectProviderBindsNothingmakes aprovider: 'object'data binding fail the required binding; and the docblock states the renderer readsobjectNamewhen an author writes both. Inpackages/lint/CHANGELOG.mdthe true account is already adjacent at the22b0081entry, in the same release.Step 3 measured, as the dispatch required — and re-measured after a seat finding on the draft. The first draft said "retiring the aliases is step 3 of this ruling, unlanded and still open as #14791". That understated the state and left the paragraph contradicting the entry's own closing sentence, "Removal of the deprecated aliases is a later card after the deprecation window" — one paragraph, two incompatible claims about whether that card exists. Two of my sources disagreed, so I measured instead of picking one:
objectName/viewTypeon ListView in favour ofdata={{ provider: 'object', object }}/type, and the lint blesses that spelling — but objectui's ListView reads neither, so the canonical spelling validates green and renders an empty list #14791's title is the renderer-half finding, which is what made the reference misleading. But the maintainer ruled option B on that same card on 2026-09-07 (comment5572008848, verbatim 「同意」): "step 3 retiresobjectName/viewTypeon the ListView block now; no deprecation window". So [finding] The #11284 convergence shipped only its producer half: the react-blocks contract deprecatesobjectName/viewTypeon ListView in favour ofdata={{ provider: 'object', object }}/type, and the lint blesses that spelling — but objectui's ListView reads neither, so the canonical spelling validates green and renders an empty list #14791 is both, and it is genuinely the retirement's card.5b010e03, awaiting a maintainer merge because it touches governedskills/**. Naming the PR gives a reader the precise artifact instead of a title about something else..objectui-sha53ded82bf:git grep "provider === 'object'" -- packages/core/src/utils/normalize-list-view.tsreturns 2 hits, exit 0 —:263is a comment and:315is the substantive fold (dataConfig?.provider === 'object' && typeof dataConfig.object === 'string'), the exact trap [finding] The #11284 convergence shipped only its producer half: the react-blocks contract deprecatesobjectName/viewTypeon ListView in favour ofdata={{ provider: 'object', object }}/type, and the lint blesses that spelling — but objectui's ListView reads neither, so the canonical spelling validates green and renders an empty list #14791 names in its own body. Positive control at the same pin:normalizeListViewSchema, 1 hit. So "until the renderer folds the canonical data source in" was no longer a pending condition and is gone.Bounded in-place fix, declared not silent. The entry's closing sentence is corrected in the same pass, because leaving it would have made my own edit produce the contradiction. All four conditions hold: same defect class as this card (a false sentence in this exact published entry), mechanical and in the register this PR already pinned, no other claim holds these files, and no new verification surface. The corrected tail now states the ruling, the landed renderer fold, and the awaiting-merge PR, and says the deprecated spellings remain the working ones within this release — which keeps it consistent with the binding clauses above it.
Shape of the correction
Both follow the model of PR #16856 and PR #16874 on the same file family: keep the true half, replace the false half with what actually happened, name the card that moved the fact. Neither correction restates history as though it had always been so — #15026's keeps the published claim in the past tense as the record of what the entry asserted, #15058's quotes the false justification verbatim before correcting it.
In-place edit was safe here, and that was checked rather than assumed. #15058's sentence was false when written, so there is no true historical record to preserve. #15026's was true at its own commit and false by publication, so the correction preserves it in the past tense with its dates. Neither case destroys a record a reader needs, so the in-place-vs-erratum convention question stays with #16849 and is not settled from inside a card.
Fences honoured
field.zod.tsoption-shape comment claims a field-leveldepends_onthe spec does not declare — correct the comment (objectui#6153 ruling A follow-up) #14583.content/docs/releases/untouched, measured.git diff --name-only | grep -c '^content/docs/releases/'-> count 0, exit 1, with a positive control of 2 fromgrep -c '^packages/'over the same pipeline, and the directory holds 10 entries. So the zero is a reading.Verification
Gates run locally on the final commit
ec23b0b17, all exit 0:check:nul-bytes,check:published-files,check:release-notes,check:release-page-status,check-release-section-coverage.mjs,check-changeset-fixed.mjs,check:doc-authoring,check-adr-0087-registration.mjs --base origin/main,check-closing-keyword-parity.mjs,check:partof-closing-keyword,check-affected-docs.mjs,check-keyed-text-bounds.mjs.No package test or typecheck is owed, and the narrowing is proven, not asserted. No test or gate parses
CHANGELOG.mdcontent: of the 21 code-file references to the path, every one is a prose mention or an explicit exclusion (:(exclude)**/CHANGELOG.mdintemplate-consistency.test.ts,if (entry.name === 'CHANGELOG.md') continueincompliance-families-retirement.test.ts). The repo-wideeslint . --no-inline-configcannot move either: run against both edited files it reports "File ignored because no matching configuration was supplied" — zero jurisdiction over.md, read from eslint's own configuration — against a positive control onvalidate-react-page-props.ts, which it does own and did lint.One flagged reading:
CHANGELOG.mdis listed infiles[]for both packages, so this diff does move published bytes.skip-changesethere rests on the triage ruling and the PR #16856 / PR #16874 precedent (both carried it), not on the "nothing published moves" test. Adding a changeset would itself be an erratum — #16849's question, not this PR's.Generated by Claude Code