Skip to content

fix(spec): correct the repository name in the changesets config and the spec README badge - #12825

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-12488-changeset-repo-name
Aug 28, 2026
Merged

fix(spec): correct the repository name in the changesets config and the spec README badge#12825
os-zhuang merged 2 commits into
mainfrom
claude/issue-12488-changeset-repo-name

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #12488

Two places still named objectstack-ai/spec, a repository name this monorepo no longer
uses. The diff is exactly two lines plus one changeset.

file before after
.changeset/config.json changelog[1].repo = "objectstack-ai/spec" "objectstack-ai/objectstack"
packages/spec/README.md line 3 StackBlitz badge -> stackblitz.com/github/objectstack-ai/spec/tree/main/examples/app-todo .../objectstack-ai/objectstack/tree/main/examples/app-todo

examples/app-todo/objectstack.config.ts — the path the badge names — exists in this
repo, so correcting the owner/repo segment is the whole fix. README.md is in
@objectstack/spec's published files array, so that badge is what npm renders.

The repo key has no reader today — measured, not assumed

This was the card's central question, and it is the reason the wrong value has never
produced a wrong link. Read from the installed implementation, not from documentation:

  • @changesets/cli@3.0.0 dist/changelog.mjs is two lines: it re-exports
    @changesets/changelog-git as its default.
  • @changesets/changelog-git@1.0.0 dist/index.mjs declares
    getReleaseLine: (changeset) => ... and
    getDependencyReleaseLine: (changesets, dependenciesUpdated) => ....
  • @changesets/apply-release-plan@8.0.0 dist/index.mjs:315 takes
    const changelogOpts = config.changelog[1] and passes it as the third argument
    (getReleaseLine(cs, rls.type, changelogOpts), line 100). Neither function above
    declares or touches a third parameter.

So config.changelog[1].repo is read by nobody in this workspace.
@changesets/changelog-github, the generator that does read it, appears nowhere in
the tree: a repo-wide git grep -n changelog-github exits 1 with 0 lines, while the
control git grep -n changelog-git exits 0 with 3 lines, and pnpm-lock.yaml carries 0
occurrences of the first against 3 of the second.

That is what makes this worth fixing rather than leaving. The value is right-shaped
and in the right place, so nothing about it reads as wrong; the moment somebody swaps in
@changesets/changelog-github — which is the usual reason to touch that block — every
generated release line starts linking into another repository, and the diff that caused
it contains no visible mistake.

What is deliberately NOT claimed

Whether github.com/objectstack-ai/spec still resolves could not be measured from this
container: the egress proxy answers 403 for every host and path outside its allowlist,
and a control request for a repository name invented for this test
(objectstack-ai/definitely-not-a-repo-12488) returns the same 403 as
objectstack-ai/spec. An instrument that returns the same value for "absent" and for
"blocked" measures nothing, so this PR does not assert the old badge is a dead link — only
that it names a repository that is not the one this README ships from.

Documenting the inertness inside config.json — tried, then declined

Measured against @changesets/config@4.0.0 validateConfig() with this repo's real
config: an extra root key is accepted but silently dropped from the parsed config; an
extra key inside the changelog options object is accepted and preserved (the schema
types that slot as an open string-keyed record). So a note could have been added.

It is not added, because the note would say "the default generator ignores this" and would
become false at exactly the moment it mattered — the generator swap — with nothing gating
it. That is a fresh instance of the very hazard this card is about. Correcting the value
removes the hazard for both generators at once, which a comment cannot do.

Why a changeset rather than the skip-changeset label

Decided from precedent, not from a rule of thumb. Of the last 8 commits touching
packages/spec/README.md, 6 carry exactly one changeset — every one since 2026-07-28
(f65879345, 189373ba5, 923c42470, cd455c83b, 4d00b13f1, b098b0e15); the two
that carry none are from February 2026, before scripts/check-empty-changeset.mjs existed
(2026-08-07).

The closest precedent is cd455c83b, "docs: four published READMEs stop documenting
symbols that do not exist (#9544) (#9581)" — a README-only change across four published
packages, packages/spec/README.md among them. It shipped a patch changeset naming all
four, and its own body gives the reason: those packages ship README.md in files with
private unset, so those are the pages npm renders. scripts/pr-labels.mjs scopes
skip-changeset to "a PR that publishes nothing"; this one changes a page npm publishes.
Hence: one patch changeset naming @objectstack/spec, and no skip-changeset label.

Verification

Gate union re-run on the final commit f62ddf725 (after merging origin/main
c4ecf0c49), derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
— 26 families, unchanged before and after the merge. Exit codes captured directly, never
through a pipe.

25 of 26 exit 0. Verdict lines the gates printed themselves:

check:published-files    69 publishable package(s) ... declare a `files` whitelist that
                         covers every entry point plus CHANGELOG.md
check-changeset-fixed    .changeset/config.json "fixed" group is in sync with 69 public
                         workspace packages          (the 70-name table is untouched)
check-empty-changeset    No empty-frontmatter changeset introduced by this diff
                         (1 declaring changeset(s) added)
check-changeset-no-major This diff introduces no `major` bump
check:override-consistency  9 published-manifest declaration(s) ... all resolve
check-dev-prereqs        67 package build artifacts present; @objectstack/spec built from
                         the sources on disk

The 26th, scripts/pm/check-half-states.mjs, exits 3 with PREREQUISITE NOT MET — the token in the environment is not a valid GitHub credential, and its own output states
"Nothing was swept ... it is no reading at all". That is a refusal to measure in this
container, not a finding; it runs with a real token in half-state-patrol.yml.

Also run: pnpm --filter @objectstack/spec build, a full pnpm build (71/71 tasks
successful — the prerequisite check-dev-prereqs demanded), and
pnpm --filter @objectstack/spec check:generated — all 14 generated spec artifacts up to
date, no regeneration needed.

Lint was narrowed, and the narrowing is declared. Rather than the repo-wide
eslint ., the three changed files were linted directly with --format json: 3 files
resolved, and ESLint's own verdict for each is "File ignored because no matching
configuration was supplied"
— the population comes from eslint.config.mjs, whose every
files glob is {ts,tsx,mts,cts,js,jsx,mjs,cjs}, and this diff adds no file in any of
them. Control: the same command on scripts/check-changeset-fixed.mjs lints it for real
(0 warnings, no ignored-verdict), so the ignored verdict discriminates. Invariance: no
lint rule reads a .md or .json file, so no untouched file's verdict can move. CI runs
the full farm regardless.

Generated by Claude Code


Generated by Claude Code

claude added 2 commits August 28, 2026 00:18
…he spec README badge (#12488)

Two places still named `objectstack-ai/spec`, which is not the repository this
monorepo lives in:

- `.changeset/config.json` -> `changelog[1].repo`
- `packages/spec/README.md` -> the "Try Online" StackBlitz badge target

`README.md` is in `@objectstack/spec`'s published `files`, so the badge ships to
npm readers. The `repo` option currently has no reader: `@changesets/cli/changelog`
re-exports `@changesets/changelog-git`, which never reads the options object that
`@changesets/apply-release-plan` passes as `config.changelog[1]`. It acquires one
the moment anyone swaps in `@changesets/changelog-github`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PfaSTikked61BkcsB5Rn69
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/spec/README.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/README.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

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

Copy link
Copy Markdown
Contributor Author

✅ ACCEPT — PM 复核(domain:devx 席,#6023,session session_01PfaSTikked61BkcsB5Rn69,R19)

尚未武装。 CI 刚起跑,武装(draft:false → auto-merge)等所有 check 按名、翻完所有页读完再做。本条只裁工作本身。

我把 Zone 2 那条链自己走了一遍 —— 因为它是我转述的,不是我测过的

派发时我明写:「⚠️ 这一段是 PM 转述卡体,未独立实测」。既然你交回 zone2_result: confirmed,那本席有义务自己验,而不是拿你的结论覆盖我自己的空白。四环全部独立复现:

① node_modules/@changesets/cli/dist/changelog.mjs —— 全文两行
     import changelog_git_default from "@changesets/changelog-git";
     export { changelog_git_default as default };
② @changesets/changelog-git@1.0.0 dist/index.mjs
     :3  getReleaseLine: (changeset) => {
     :9  getDependencyReleaseLine: (changesets, dependenciesUpdated) => {
     ⇒ 两个函数都【没有】第三个形参
③ @changesets/apply-release-plan@8.0.0 dist/index.mjs
     :315  const changelogOpts = config.changelog[1];
     :100  ...getReleaseLine(cs, rls.type, changelogOpts)   ← 作为第三个实参传入
④ changelog-github:tracked 0 行 · pnpm-lock 0 次
   阳性对照 changelog-git:tracked 1 行 · pnpm-lock 3 次   ⇒ 这把 grep 会命中
   阴性对照(编造符号)= 0

config.changelog[1].repo 今天零读者,证实。 行号与你报告里的一字不差。⭐ 这条链的价值在于它把「惰性」从一个断言变成了一个有到期日的事实:它在有人换成 changelog-github 的那一刻获得读者,而那正是动这一段的通常理由。

⚠️ 一个过程上的自我记录:我第一次跑 ①②③ 时输出全空,而空输出不是「函数没有第三个参数」的证据 —— 是这个共享 checkout 从没 pnpm install 过。那是 PREREQUISITE NOT MET,是拒绝测量。我换到一个装了 node_modules 的 worktree(只读)才拿到真读数。⛔ 差一点就把空白读成确认。

diff 与 Zone 1 边界

.changeset/config.json          "objectstack-ai/spec" → "objectstack-ai/objectstack"   (1 行)
packages/spec/README.md:3       徽章 owner/repo 段                                      (1 行)
.changeset/changesets-repo-name-and-spec-badge.md                                       (新增,declaring)
  • ✅ 徽章指向的路径实测存在:examples/app-todo/objectstack.config.ts 在树上(阴性对照:一条编造的 examples/app-NO-SUCH/ = 0 条)。所以「只动 owner/repo 段就是全部修复」成立。
  • 那张 fixed 表逐字节未动 —— 我按 JSON 解析后哈希比对:mainhead 同为 4cf9e237b2eb2c0a
    ⚠️ 顺带更正我自己:我在派发单里写「70 项」,实际是 69 项,check-changeset-fixed.mjs 也说 69。你在 PR 正文里照我的说法写了「the 70-name table」—— 那是我的数字错了,不是你的。
  • ✅ Zone 1 的四条出范围边界(docs/notes/airtable-dashboard-analysis.mdxCONTRIBUTING.mdCHANGELOG.mdplugin-auth/**)全部未触碰,且没有在 PR 里论证该改 —— 后半条同样重要,你做到了。

判别子与对照(武装前双向预检)

main c4ecf0c49 head f62ddf725
判别子 objectstack-ai/objectstack/tree/main/examples/app-todo(README) 0 1
判别子 "repo": "objectstack-ai/objectstack"(config) 0 1
旧值 github/objectstack-ai/spec/tree 1 0
对照 Source of Truth(不在改动行上) 1 1
对照 strictly typed Zod schemas(不在改动行上) 1 1
阴性对照 0

git merge-tree 无冲突。

⚠️ 又一次记录我自己的仪器失误:我第一次测对照时用 git diff | grep,两个候选都显示「在 diff 中 = 1」,看起来像是被 PR 动过。实际是 diff 的上下文行也被 grep 命中了 —— 正确的检验是只看 ^[-+] 行,重测后两者都是 0。⛔ 「出现在 diff 输出里」≠「被这个 PR 改过」。

changeset:你按我要的方式回答了,而且答案与同批另一张相反 —— 都对

我给你的是「自己量先例再决定,两种结局都可以,只要给出据以判断的那个数字」,⛔ 而不是一条新硬约束。你量了:packages/spec/README.md 最近 8 个提交里 6 个带恰好一个 changeset,全部在 2026-07-28 之后;没带的两个来自 2026 年 2 月,早于 check-empty-changeset.mjs 存在(2026-08-07)。最近先例 cd455c83b 是四个已发布包的 README-only 改动,发了 patch changeset。

⇒ ✅ 采纳。而且值得记一笔:同一批里 #12782 量出的答案是不加 changeset(scripts/pm/ 不属任何 package),你量出的是(README 进 npm tarball)。同一个问题,两个相反答案,两个都由实测支撑 —— 这正是我把它降级成「自己量」而不是写成硬约束的原因。

Zone 3 与「拒绝主张」

  • 试过再拒绝,不是没试就拒绝:你对着 validateConfig() 实测了「根级多余键被静默丢弃 / changelog 选项对象内的多余键被保留」,证明注释加得进去,然后以「这条注释会在它最要紧的那一刻(换生成器)变成假话,而且没有任何门禁看着它」为由不加。⭐ 理由本身就是本卡的危险类型再来一次,这个判断是对的。
  • ⭐⭐ 最值得记的一条:你拒绝了一个测不了的主张。github.com/objectstack-ai/spec 是否还能解析」在这个容器里无法测量 —— 代理对白名单外一律 403,而你用一个编造的仓名(objectstack-ai/definitely-not-a-repo-12488)做对照,拿到同样的 403。「对『不存在』和『被拦截』返回同一个值的仪器,什么都没测到」。于是 PR 只主张「徽章指向的不是这个 README 所属的仓库」,⛔ 不主张它是死链。这与本班 §4 那条「PREREQUISITE NOT MET 是拒绝测量、不是发现」是同一条纪律,你把它用在了自己想要的结论上,那是更难的方向。

残留

  • packages/spec/README.md:195objectstack-ai/hotcrm 链接:✅ 交上来而不是立卡,理由正确 —— 同样的代理限制下你没有证据说它错,立一张无法验证的链接卡等于制造发现。本席记下,留给有真实出网的席位测。⛔ 本轮不立卡。
  • docs/audits/2026-06-...:40 已记录:✅ 确认无需新卡。

Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 28, 2026 00:51
@os-zhuang
os-zhuang enabled auto-merge August 28, 2026 00:51
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 28, 2026
Merged via the queue into main with commit f75a38a Aug 28, 2026
36 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-12488-changeset-repo-name branch August 28, 2026 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

2 participants