Repository navigation
The withdrawn dist/index.d.ts byte-identity sentence survives verbatim in five released CHANGELOGs — decide whether released records get amended #5913
Description
Activity
- addeddomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seat
on Aug 24, 2026 claude commented
on Aug 24, 2026 claudeboton Aug 24, 2026 – with ClaudeContributorAuthorMore actions分诊落箱(session
session_01Kktexqp6uVuFMztvvTMf3V,2026-08-24)。一句话问题:一句后来被撤回的技术断言,原样留在五份已发布的更新日志里 —— 要不要去改已经发出去的历史记录。选项 × 真实代价:
- A. 不改,关卡:源头注释已由 [finding] #4580's "dist/index.d.ts is byte-identical" justification is a vacuous measurement, and it is written into the repo as evidence #5673 纠正;发布记录如实保留「当时怎么认为」。业务上 = 更新日志继续可信为「发布当时的记录」,无人被它引导做任何动作。
- B. 逐行授权加更正注:照 docs(changeset,plugin-detail): date the two rotted release-note sentences and correct the born-false parity-test claim (objectui#9637) #9734 先例,五处各加一行「post-publication correction」。代价:动 append-only 记录五处,先例扩大;业务上 = 读旧日志的人多一行提示。
四棱:① 长远:append-only 纪律本身比这句话值钱 —— #9734 的授权是针对「教读者跑一条不存在的命令」的活害,本句是历史性描述,无活害,先例不应扩大。② 业务拉动:零 —— 没有客户会因这句旧断言做出任何错误动作(它描述的是当时的构建产物对比)。③ 防 AI:批量改 CHANGELOG 正是 #9734 裁决点名的错误工具;A 让「历史记录不许碰」保持为简单可教的规则。④ 创业:零拉动的编辑不做。
推荐 A(关卡,not planned,源头修正已足);回退 B。置信缺口:无法测 npm 侧是否有消费者把该句当作现行契约在依赖(byte-identity 承诺若被外部工具断言过,A 的「无活害」前提失效)。回「A」/「B」即可。裁后执行:A ⇒ 关 not planned,理由引本块;B ⇒ 立五行编辑卡带逐行授权引文。
Generated by Claude Code
分诊席四维分析(维护者 2026-08-24 点名要求;裁决仍归维护者——立卡人刻意未给推荐)。
os-decision-facets
一句话问题:#5673 撤回的「dist/index.d.ts 字节同一」空洞测量句,原样留在五份已发布的 CHANGELOG 里。改不改已发布的记录?A=不动(源码 docstring 已更正);B=五处各补一行更正注;C=在耐久处(如
check-changeset-presence.mjs头部,本仓惯例位)记录一次更正,五份原文不动。① 实际业务需求:零用户影响——npm 上的文本无论如何收不回;风险只是翻旧 release notes 的读者信了一个空洞测量。边际。→ A/C。
② 项目长远合理性:本仓 CHANGELOG 是 changeset 编译产物——手改编译产物偏离发布管线纪律(B 的实质代价);C 在守卫脚本头记一次,既留下更正痕迹又不动管线。→ C。
③ 防 AI 犯错:agent 引用这句话作证据的路径主要是源码 docstring——那里 #5673 已更正;考古路径(翻 CHANGELOG)由 C 的耐久注记兜住。B 只多覆盖"只读 CHANGELOG 不读别处"的窄场景。→ C。
④ 创业阶段不扩散需求:A 零成本,C 一段注释,B 五个 append-heavy 文件的 diff。→ A/C。推荐:C(四轴同向,A 可接受)。 裁后执行:C ⇒ 一张 S 级机械卡(守卫头部注记 + 指向 #5673),本卡关;A ⇒ 直接关,理由记录在案。本分析看不见什么:您对「已发布记录的事实准确性」的重视程度本身——若您认为发布记录必须逐字可信,B 才是对的,那就接受五文件 diff 的代价。
Generated by Claude Code
Maintainer ruling recorded — C: record the correction once, durably; released records stand
Provenance: maintainer, 2026-08-24, live PM chat, verbatim: 「接受你的建议。」 on the aligned four-facet analysis above.
Ruled: the five released CHANGELOG entries are not edited (compiled release artifacts stay on the changeset pipeline; npm copies are immutable anyway). The correction is recorded once in a durable, greppable place: the header of
scripts/check-changeset-presence.mjs(this repo's established home for findings of this shape), stating that the #4580 changeset's "dist/index.d.ts is byte-identical" sentence was a vacuous measurement withdrawn by #5673, with the file list so an archaeologist landing on any of the five copies can find the withdrawal.This card converts to that S-grade mechanical task. State:
needs-user-decision→pm:queue(ui lane), type Task — closes via the one-comment-block PR.
Generated by Claude Code
Claim: PM loop round 37
Session:session_01CSoz9uGhaaSgiq3hshtN7L
Branch:claude/issue-5913-changelog-correction-record
Worktree:objectui-issue-5913
Domain:domain:ui
File surface: the header comment block ofscripts/check-changeset-presence.mjs, and nothing else in the repo (stop on breach; explain in the report)
Container & model:Smechanical,mode:subagent,model: opus
Clause-②: no — a comment block in a script header. No schema, no runtime, no published surface.
Serial constraints cleared:scripts/**— no in-flight claim in this lane. Concurrent siblings #5631 / #5853 (packages/types+packages/components), #5293 (packages/plugin-view), #5325 (packages/fields) — all disjoint by full path.⛔ RULED 2026-08-24 — option C, and the ruling is mostly about what NOT to do
Maintainer, verbatim: 「接受你的建议。」
Ruled: ⛔ the five released CHANGELOG entries are not edited. Compiled release artifacts stay on the changeset pipeline, and the npm copies are immutable anyway — a repo-side edit cannot recall what shipped, it only makes the repo disagree with it.
The deliverable is one durable, greppable record, in the header of
scripts/check-changeset-presence.mjs— this repo's established home for findings of this shape. It must state:- that the finding(types): two competing SchemaNode declarations — core's interface vs types' union #4580 changeset's "Core's entry surface is unchanged:
dist/index.d.tsis byte-identical across the change" sentence was a vacuous measurement, withdrawn by [finding] #4580's "dist/index.d.ts is byte-identical" justification is a vacuous measurement, and it is written into the repo as evidence #5673; - why it is vacuous —
core/dist/index.d.tsis emitted from a barrel that only forwards the symbol, so it is byte-identical under any change to a re-exported declaration's shape (PR [finding] #4580's "dist/index.d.ts is byte-identical" justification is a vacuous measurement, and it is written into the repo as evidence #5673 proved this with a probe that moved the declaring module's.d.tsand left both core files unmoved); - the file list, so an archaeologist who lands on any one of the five copies can find the withdrawal.
The five, per the card:
packages/components/CHANGELOG.md:1472,packages/core/CHANGELOG.md:1021,packages/plugin-dashboard/CHANGELOG.md:581,packages/react/CHANGELOG.md:450,packages/types/CHANGELOG.md:705.What makes this an S that still needs judgement
⛔ Verify the five line references before writing them down. A correction record whose own pointers are wrong is worse than none — it is the same defect class as the sentence it corrects. The card's search method is good and reusable:
git grep -nIfor the exact sentence, with the known-present controlis byte-identical across the change(which returned six files — the five plus one unrelated i18n test) and a known-absent control returning exit 1, so an empty result is distinguishable from a broken search. Re-run it; CHANGELOGs are append-heavy and line numbers move.⛔ Do not add a check, a test, or an
UNGATEDentry — the deliverable is a comment block. The script's behaviour must not change; say so in the report and show the gate still passes.A changeset is owed only if
node scripts/check-changeset-presence.mjsasks for one (an empty-frontmatter changeset is this repo's declared "releases nothing" form). Note the mild irony that the gate deciding this is the file you are editing — run it and quote its verdict either way.Draft PR,
Fixes #5913. Post the terminal report here (plain-text first-line marker) and return it.
Generated by Claude Code
- that the finding(types): two competing SchemaNode declarations — core's interface vs types' union #4580 changeset's "Core's entry surface is unchanged:
os-dev-report
{ "issue": 5913, "status": "done", "branch": "claude/issue-5913-changelog-correction-record", "pr": "https://github.com/objectstack-ai/objectui/pull/6005", "premise_still_valid": true, "summary": "Implemented the 2026-08-24 option-C ruling: added one section to the header comment of scripts/check-changeset-presence.mjs recording that #4580's \"Core's entry surface is unchanged: dist/index.d.ts is byte-identical across the change\" sentence was a vacuous measurement withdrawn by #5673, why it is vacuous (core's entry .d.ts is emitted from a barrel that only forwards the symbol, so it cannot move for any re-exported declaration's shape change — #5673's PR probe moved @object-ui/types' dist/base.d.ts and left both core files on one hash across all three legs), and the file list of the five released copies so an archaeologist landing on any one of them finds the withdrawal. The five released CHANGELOG entries are NOT edited, and the record says why, so the next reader does not re-open it as an oversight. Zone 3 held: no check, no test, no UNGATED entry — the diff is 51 insertions / 0 deletions in one file and every added line is a comment line, so the gate's behaviour cannot have changed. Fence held exactly: git diff --name-only against the branch point lists scripts/check-changeset-presence.mjs and nothing else.", "tests": "All gate runs captured by redirect-then-capture (never an exit code read through a pipe); union re-run AFTER the final commit at ea197938b. (1) The Zone 2 verification, re-run at the branch point 8d3a5294a rather than trusted from the card: exact-sentence grep exit 0 returning the five files at the card's line numbers, all five unchanged — packages/components/CHANGELOG.md:1472, packages/core/CHANGELOG.md:1021, packages/plugin-dashboard/CHANGELOG.md:581, packages/react/CHANGELOG.md:450, packages/types/CHANGELOG.md:705; known-present control 'is byte-identical across the change' exit 0 returning six files (the five plus packages/fields/src/__tests__/PercentCellRenderer.locale.test.tsx, an unrelated i18n PIN whose byte-identity claim is about rendered output and can genuinely fail — not a second instance of this defect); known-absent control exit 1 with zero lines, so an empty result is distinguishable from a broken search. (2) The changeset question, answered by the very file being edited — `node scripts/check-changeset-presence.mjs` exit 0, its own verdict lines: 'Compared the working tree with 8d3a5294a (merge-base with origin/main): 1 file(s) changed, 0 of them under the src/ of a package the release covers, 0 under a package changesets ignores, 0 changeset(s) added.' then 'No source of a released package changed in this range, so no changeset is owed.' None owed, so none added — not even the empty-frontmatter form, and no skip-changeset label (that mechanism does not exist in this repo). (3) Gate union at ea197938b: scripts/__tests__/check-changeset-presence.test.ts exit 0, 'Test Files 1 passed (1) / Tests 31 passed (31)' — this is the dedicated pin on the edited script and it still passes, which is the mechanical form of 'behaviour unchanged'; node scripts/check-control-bytes.mjs exit 0, 'check-control-bytes: OK (scanned 4970 tracked text file(s); skipped 85 binary)'; tsc -p tsconfig.scripts.json exit 0, clean; eslint over the FULL lint:root scope (not narrowed) exit 0, '26 problems (0 errors, 26 warnings)' with every warning pre-existing and none in the edited file. (4) Two pre-insertion byte checks against traps this header itself documents: grep -F for a comment-terminator sequence in the drafted text returned exit 1 (none — the header records that such a sequence closes the block early), and grep -naP for control bytes returned exit 1. No ablation was applicable: the deliverable is a comment block with no executable behaviour to mutate. Gate family derived by hand from the root package.json scripts and .github/workflows/changeset-presence.yml — this repo has no scripts/pm/dispatch-gates.mjs; CI runs the full farm and PM reads its convergence.", "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
ACCEPT — PR #6005 (R37,
domain:ui)Reviewed against the diff and
origin/main.Checklist:
Fixes #5913✅ · one file, 51 insertions, 0 deletions, every added line a comment ✅ · ⛔ no check, no test, noUNGATEDentry added ✅ · the five released CHANGELOGs untouched, per the ruling ✅ · no changeset — the gate being edited says none is owed, quoted from its own verdict ✅.The load-bearing claim, verified by me
A correction record whose own pointers are wrong is the same defect class as the sentence it corrects, so I re-derived all five rather than accepting them:
packages/components/CHANGELOG.md:1472 hit packages/core/CHANGELOG.md:1021 hit packages/plugin-dashboard/CHANGELOG.md:581 hit packages/react/CHANGELOG.md:450 hit packages/types/CHANGELOG.md:705 hitKnown-present control returns six files; known-absent control exits 1 with zero lines. Both behave.
✅ And the sixth hit was judged, not just noted.
packages/fields/src/__tests__/PercentCellRenderer.locale.test.tsxalso carries the phrase — you established it is an unrelated i18n pin whose byte-identity claim is about rendered output and can genuinely fail, so it is not a second instance of this defect. Checking whether a stray hit is another instance of the bug is the difference between a search and an answer.What lifts this above a transcription
The record explains the mechanism rather than asserting the verdict. "Forwarding never restates a shape … only the module that DECLARES the symbol can move" — so the file is byte-identical under any change to a re-exported declaration's shape, "including one that breaks every consumer, and a gauge that cannot fail for the change class it is quoted against has discharged nothing." That is the reusable lesson; the withdrawn sentence is just the instance.
It states that the five copies are NOT edited and that this is a ruling, not an omission — which is what I asked for, and it is what stops the next reader re-opening it as an oversight and hand-editing compiled release notes.
And the best line is the one that survives its own rot:
Six files means the search worked; zero means it broke, not that the copies are gone.
Line numbers in append-heavy CHANGELOGs decay. Handing the next reader a re-derivation recipe that is its own control — rather than five numbers that will be wrong in a month — is the difference between a record and a fossil. That is a better artifact than the ruling strictly required.
Behaviour-unchanged, proven mechanically
scripts/__tests__/check-changeset-presence.test.ts— the dedicated pin on the edited script — still passes 31/31. For a comment-only diff there is no ablation to stage and you said so plainly instead of staging theatre; the pin passing is the mechanical form of the claim. The two pre-insertion byte checks (a grep for a comment-terminator sequence, which this header itself documents as a hazard that closes the block early, and a control-byte scan) are the right paranoia for text going into a block comment.Nicely circular and correctly handled: the gate deciding whether a changeset is owed is the file you edited. You ran it and quoted its verdict either way.
Landing
Not governed (
scripts/**is not on the governed path list). Gates read by name, once, at ~11 min past this PR's own runstarted_at; enqueue requires every check green, not the required subset.
Generated by Claude Code
Found while implementing #5673 (the docstring correction). Filing rather than absorbing:
#5673's fence is the comment carrying the claim, and this half is a question about
released records, which is a ruling rather than an edit.
What is there
The sentence #5673 withdrew from
packages/core/src/types/index.tswas also written intothe #4580 changeset, and the release tooling copied that changeset verbatim into every
dependent package's CHANGELOG. Five copies are in the tree today, all identical, all
carrying the last sentence:
Search scope:
git grep -nIover all 5001 tracked files, patternsindex\.d\.ts(144 hits),
byte.identical,entry (type )?surface, and the exact sentence. Control:is byte-identical across the change— a phrase known present — returned six files(the five above plus one unrelated i18n test), searched the same way; a
known-absent control string returned exit 1 with zero lines, so an empty result is
distinguishable from a broken search.
Why it is not just noise
The measurement is vacuous for the reason #5673 records:
core/dist/index.d.tsisemitted from a barrel that only forwards the symbol, so it is byte-identical under any
change to a re-exported declaration's shape — measured again in #5673's PR with a probe
that moved the declaring module's
.d.tsand left both core files unmoved. A reader whofinds the claim in a CHANGELOG has no way to know it was withdrawn.
Why #5673's PR did not rewrite them
Stated so the decision is made on purpose rather than by omission:
to npm on five packages. A repo-side edit cannot recall what shipped; it only makes the
repo disagree with it.
.changeset/*.mdat release time. Hand-editing thecompiled artifact is off that path.
Options
accepts that a reader of the release notes sees the withdrawn claim.
Keeps history readable and marks it corrected; five-file diff, and it edits compiled
release notes.
scripts/check-changeset-presence.mjs, where this repo already keeps findings of thisshape) and leave the five entries alone.
No recommendation offered — the trade is "accuracy of a released record" against "release
notes are compiled, not edited", and that is a maintainer call.
Filed unassigned.
Generated by Claude Code