Skip to content

docs(data-objectstack): point the two example baseUrls at a reserved placeholder host - #8858

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-8381-docs-dead-api-host
Sep 9, 2026
Merged

docs(data-objectstack): point the two example baseUrls at a reserved placeholder host#8858
os-zhuang merged 1 commit into
mainfrom
claude/issue-8381-docs-dead-api-host

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #8381

content/docs/utilities/data-objectstack.mdx named https://api.objectstack.dev as the example API host in two copyable code fences. That domain does not resolve, so a reader who copies either snippet gets a configuration pointed at nothing — and the failure arrives as a runtime network error rather than as anything a check catches.

What changed — the two named lines, plus the prose the ruling asked for

site before after
:155, the **Example:** fence baseUrl: 'https://api.objectstack.dev', baseUrl: 'https://api.example.com',
:364, the ### Custom fetch fence baseUrl: 'https://api.objectstack.dev', baseUrl: 'https://api.example.com',

Plus one paragraph directly under the first fence stating that the host is a placeholder, why it can never resolve, and that the reader should substitute their own. Nothing else in the file, and no other file: git diff --stat against the branch point is 1 file changed, 8 insertions(+), 2 deletions(-).

Why a reserved host, and why this one

The ruling asked for a host reserved for documentation and refused api.objectstack.ai: plausible is not established, and egress policy means nobody in these sessions can probe it. example.com is reserved by RFC 2606 for exactly this purpose — a documentation host that can never resolve to somebody's real service — so a reader who forgets to change it fails loudly instead of reaching a stranger's server.

Two measurements say api.example.com is not a new placeholder being introduced here, but the convention these two lines were the only stragglers from:

  • the same file already uses https://api.example.com at eleven other baseUrl sites, the first at :48 in Quick Start;
  • the package's own published JSDoc @example, in the shipped packages/data-objectstack/dist/index.d.ts, already reads baseUrl: 'https://api.example.com'.

Acceptance — three readings at 74781ff81

No gate proves this one. Both sites sit inside code fences and the link sweep does not extract links from fences, so it was never going to name them — a class the instrument does not see, not a gap in objectui#8128's fix. CI is green either way, so the readings are the acceptance.

Subject — api.objectstack.dev in that file falls to 0:

$ grep -oP 'api\.objectstack\.dev' content/docs/utilities/data-objectstack.mdx | wc -l
0
$ git grep -nP 'objectstack\.dev' -- .        # repo-wide, anchored
(no output, exit 1)

Lit control A — objectstack.ai in that file is untouched, so the probe runs rather than having purged the domain:

$ grep -nP 'objectstack\.ai' content/docs/utilities/data-objectstack.mdx
505:- **[ObjectStack Documentation](https://docs.objectstack.ai)** - Learn about ObjectStack
550:- [ObjectStack Documentation](https://docs.objectstack.ai)

Both are objectui#8128's landed work, carried through unchanged; the line numbers moved by +6 only because the new paragraph sits above them.

⚠️ One correction to this control's expected value, and it is the ruling's own instrument trap landing on the control itself. The brief expected 3; anchored, the file holds 2. The third hit is only reachable with an unanchored dot:

$ grep -nP 'objectstack.ai' content/docs/utilities/data-objectstack.mdx   # unanchored
505:...docs.objectstack.ai...
550:...docs.objectstack.ai...
551:- [GitHub Issues](https://github.com/objectstack-ai/objectui/issues)   [objectstack-ai = the ORG name]

The dot matched the hyphen in objectstack-ai. The control is still lit either way — an over-broad edit would have moved these lines — but its true anchored value is 2, not 3.

Lit control B — the CLI command objectstack dev (with a space) is byte-identical:

$ git grep -nP 'objectstack dev' -- . | wc -l
11

11 lines across 8 files, including both sites the brief named (content/docs/guide/ci-cd-pipeline.md:526 and packages/auth/src/__tests__/workspaceAdminPositions-5389.test.tsx:21) — and the brief's list was the smaller half: .github/workflows/live-e2e.yml, AGENTS.md x2, CHANGELOG.md, e2e/live/ci/start-backend.sh x3, e2e/live/record-history-display.spec.ts and examples/console-starter/README.md carry it too. That is the blast radius an unanchored objectstack.dev regex would have had. Every replacement here was an exact-literal match on the full line baseUrl: 'https://api.objectstack.dev', with an asserted match count of 2, never a regex; the git diff --stat above is the proof none of the 11 moved.

Gates run

gate exit reading
check:doc-snippets 0 Semantic phase: 637 of 637 block(s) judged, 0 failed. — run after its own scoped 34-package build (35/35 tasks, exit 0); its four harness controls all lit
check:doc-types 0 Every documented component type is registered. (188 doc files, 1108 code blocks)
docs:check-links 0 Links are valid across 17 scan roots.
check:doc-fences 0 every TypeScript block in 227 documents correctly fenced
check:doc-expression-carriage 0 report-only census, unchanged
check:docs-route-closure 0 unchanged
check:control-bytes 0 7058 tracked text files scanned
check-changeset-presence 0 see below
check-governed-queue-guard --test 0 subject / 3 control see below

Extraction invariance was measured directly rather than assumed: the gate's own exported scanFences() reports the same 15 blocks and 3 markers before and after, and the only byte difference in the whole extracted program set is the two string literals — the added paragraph moved no fence and consumed no fragment marker.

eslint does not cover this file at all — measured, not narrowed: npx eslint content/docs/utilities/data-objectstack.mdx --format json returns File ignored because no matching configuration was supplied.

Changeset — measured, not assumed

None owed. node scripts/check-changeset-presence.mjs exits 0 with:

Compared the working tree with 42df92809 (merge-base with origin/main): 1 file(s) changed,
0 of them published source of a package the release covers, 0 of them a manifest whose
published contract moved, 0 under a package changesets ignores, 0 changeset(s) added.

Governed surface

Not governed, with the required lit control:

$ node scripts/check-governed-queue-guard.mjs --test content/docs/utilities/data-objectstack.mdx
✅ NOT GOVERNED — 1 path(s) checked against 5 governed surface(s); none matched.     (exit 0)

$ node scripts/check-governed-queue-guard.mjs --test AGENTS.md
⛔ GOVERNED — 1 of 1 path(s) are on a governed surface                               (exit 3)

Clause-②: no
Contract-text: the published contract this page documents is baseUrl: string in packages/data-objectstack/dist/index.d.ts; substituting one string literal for another in an example neither widens an accept set nor expands a published surface, and check-changeset-presence measures 0 files of published source touched.

验收备注

  • The placeholder paragraph sits under the first changed fence (:155), not under the page's first baseUrl example (:48), to stay inside the two sites this card names. A page-level note in Quick Start would read slightly better; noted, not filed — no successor PR or person is queued on this file.
  • The brief's premise that a placeholder had to be chosen turned out to be already-decided by the corpus: 11 sites in this very file plus the shipped .d.ts example. The choice is therefore alignment, not a new convention.
  • Not touched, deliberately: :505 / :550 (objectui#8128's landed work), content/docs/guide/ci-cd-pipeline.md, packages/auth/**, and the single https://api.your-instance.com at content/docs/guide/data-source.md:72 (verified still there, 1 hit) that triage explicitly placed out of scope.

🤖 Generated with Claude Code

https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH


Generated by Claude Code

…d placeholder host

`content/docs/utilities/data-objectstack.mdx` named `https://api.objectstack.dev`
as the example API host in two copyable fences. That domain does not resolve, so a
reader who copies either snippet gets a configuration pointed at nothing and finds
out only as a runtime network error — no gate goes red and nothing points them back
at this page.

Both now read `https://api.example.com`, which the other eleven `baseUrl` examples
in the same file — and the package's own published `@example` in its shipped
`.d.ts` — already use. `example.com` is reserved by RFC 2606, so it can never
resolve to somebody's real service: a reader who forgets to change it fails loudly
instead of reaching a stranger's host. Adjacent prose now says so in words.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH
@os-zhuang
os-zhuang marked this pull request as ready for review September 9, 2026 15:20
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

PM 评审 — PR #8858(卡 #8381

结论:通过。 已翻 ready、auto-merge 已武装(squash)——两个调用都返回成功之后才写这句。

⛔ 我的裁决 ② 的对照值是错的,而且错在它自己警告的那个陷阱上

裁决 ② 要求「用锚定的点,别用裸 .」,并给了 lit control A 的期望值 3。dev 报回来:锚定读数是 2

我复测,确认 dev 是对的:

$ git grep -nP 'objectstack\.ai' pr8858 -- content/docs/utilities/data-objectstack.mdx
:505  - **[ObjectStack Documentation](https://docs.objectstack.ai)** …
:550  - [ObjectStack Documentation](https://docs.objectstack.ai)
                                                              ← 2,不是 3

第三个命中只有在不锚定时才出现::551github.com/objectstack-ai/objectui/issues,正则的 . 匹配到了组织名 objectstack-ai 里的连字符。⇒ 我写这条规则的时候,自己用的就是被这条规则禁止的读法,而且这是这一班同一个陷阱的第三次(前两次:objectstack.dev. 匹配 CLI 命令 objectstack dev 的空格)。对照灯是亮的,但它的期望值是我错标的。dev 指出来是对的。

三条读数我都独立复测过

SUBJECT   git grep -cP 'api\.objectstack\.dev' pr8858 -- …/data-objectstack.mdx   → 0(origin/main 上是 2)
          git grep -nP 'objectstack\.dev' pr8858 -- .                              → 无输出,exit 1(全仓锚定)
CONTROL A git grep -nP 'objectstack\.ai' pr8858 -- …/data-objectstack.mdx          → 2(:505 / :550,#8128 的既有成果,未动)
CONTROL B git grep -nP 'objectstack dev' pr8858 -- . | wc -l                       → 11
          同一命令在 origin/main 上                                                → 11   ← 逐字相等

CONTROL B 是这一班标准里那种真正的对照:它守的是「用了裸正则会怎样」,而一个裸 objectstack.dev 正则正好会打到这 11 行。所以它有能力因为那个失败模式而变红,不是一个「主体坏了它也红」的噪声灯。dev 还把这个数从我 brief 里点名的 2 处扩到实际的 11 行 / 8 个文件——那才是那条错误正则的真实爆炸半径。

diff 我也读了:+8/-2,一个文件,两处是逐字整行替换,六行是新段落。与 git diff --stat 自洽。

一处我要替 dev 把话说准

报告写「the package's own PUBLISHED JSDoc @example in packages/data-objectstack/dist/index.d.ts already reads baseUrl: 'https://api.example.com'」。

⚠️ dist/ 不在版本控制里——干净检出里它不存在(git ls-files packages/data-objectstack/dist 无输出)。dev 为跑 doc-snippets 门做过一次范围构建,所以他们的 worktree 里确实有那个文件;但这条读数在一个干净检出上不可复现,形状和这一班 #8443 那次「探针和对照同时为零,因为这个检出没有 node_modules」是同一种。

结论本身成立,我在能活过干净检出的载体上验到了它:

packages/data-objectstack/src/index.ts:2657:  *   baseUrl: 'https://api.example.com',

——这正是那段会被编译成 .d.ts 的 JSDoc @example。⇒ 「api.example.com 是这个包既有的约定、不是本 PR 新引入的占位符」为真;请把出处记在源文件上,别记在构建产物上。

同页 api.example.com 的既有站点我按自己的读法数了一遍(不是 baseUrl: 行数,是字符串出现数):origin/main 11、PR 头 14。11 + 两处替换 + 新段落里的一次提及 = 14,自洽。

判定

  • 裁决 ① (要一个保留给文档的主机、⛔ 拒绝 api.objectstack.ai):example.com 是 RFC 2606 保留域,段落把「为什么它永远不会解析」写进了正文,不是只换了个字符串。✅
  • 裁决 ② (锚定、逐字、⛔ 不用 sed/正则批改):两处都是整行 exact-literal 匹配、断言命中数为 2。✅ 而这条裁决自己的对照值被 dev 证伪了,见上。
  • Clause-② nocheck-changeset-presence 实测 0 个已发布源文件,改的是文档里的字符串字面量,既没有新导出符号,也没有已发布载荷上的新键。复核同意。
  • 治理面守卫带 AGENTS.md 亮灯对照跑过(subject exit 0 / control exit 3)。✅

验收备注里两条我确认保留

  • content/docs/guide/data-source.md:72https://api.your-instance.com 分诊明确划在范围外,没有被顺手改——正确。想统一整页集合的话是另一张卡。
  • 新段落放在被改的第一个 fence 下面而不是 Quick Start 的 :48,是为了留在这张卡点名的两个站点里。同意;不要为了「读起来更顺」把 PR 撑大。

Generated by Claude Code

Merged via the queue into main with commit 8a388ee Sep 9, 2026
31 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-8381-docs-dead-api-host branch September 9, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants