Skip to content

docs: relabel the three /docs/deployment index links to the page's own title - #10480

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-8984-deployment-index-link-labels
Aug 21, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-8984-deployment-index-link-labels

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Fixes: #8984

Three pages outside the deployment section linked the section index under labels naming neither of that index's two lifecycles. This is the relabel the card describes — labels only. No link target, heading, page structure or meta.json title was touched.

The two lifecycles, read off the target page

/docs/deployment resolves to content/docs/deployment/index.mdx, titled Deployment Overview. Its own ## headings fork the section in two:

The index's heading What it covers
The platform runtime — you operate it The version-locked train shipped as ghcr.io/objectstack-ai/objectstack. Moved by moving the image tag and restarting. Docker, Compose, Kubernetes, bare Node.js and ObjectStack Cloud are venues inside this half — the page says so explicitly: "Where it runs … is a detail inside the first of those two, not a third thing alongside them."
Your metadata app — you build it The app you build, compiled to dist/objectstack.json, versioned by your own catalog. Reaches a running platform by catalog install or artifact-pinned boot.

Both replacement labels are checkable against those headings, which is the point: the defect was labels chosen without reference to the target.

The three relabels, in their surrounding clause

1. content/docs/ui/setup-app.mdx:125 — a bullet in ## Related, siblings have no trailing period:

-- [Cloud Deployment](/docs/deployment) — how Setup behaves in cloud mode
+- [Deployment Overview](/docs/deployment) — the platform-runtime lifecycle that serves Setup; ObjectStack Cloud is one venue inside it

The old clause promised "how Setup behaves in cloud mode", which the index does not deliver — it has no Setup-specific content, and cloud appears nowhere else in this page except one table cell. The new clause names the half and corrects the premise that cloud is a separate mode.

2. content/docs/automation/hook-bodies.mdx:346 — a bullet in ## See also, siblings do end with a period:

-- [Cloud Deployment](/docs/deployment) — how artifacts travel from Studio to objectos.
+- [Deployment Overview](/docs/deployment) — the metadata-app lifecycle: how a compiled artifact reaches a running platform.

"How artifacts travel" is squarely the metadata-app half — the index's "How the app reaches a running platform" table (catalog install vs artifact-pinned boot) is exactly what this reader wants.

3. content/docs/kernel/index.mdx:46 — mid-sentence in a prose **Neighbors:** bullet, so only the label changes; the clause "running the kernel in production" already tells the reader which half they are being sent to:

-- **Neighbors:** … running the kernel in production is covered in [Deployment & Operations](/docs/deployment).
+- **Neighbors:** … running the kernel in production is covered in [Deployment Overview](/docs/deployment).

Deployment & Operations is the section title from content/docs/deployment/meta.json; the page is Deployment Overview. Both strings live in the nav, which is what made this one hard to notice.

Census: was it exactly three?

The card found three while doing something else and did not claim the census was exhaustive. It was swept.

Positive control first — before trusting any zero-hit, the expression was proven to find the three known instances:

$ grep -rn '(/docs/deployment)' content/docs/ui/setup-app.mdx content/docs/automation/hook-bodies.mdx content/docs/kernel/index.mdx
content/docs/ui/setup-app.mdx:125:- [Cloud Deployment](/docs/deployment) — how Setup behaves in cloud mode
content/docs/automation/hook-bodies.mdx:346:- [Cloud Deployment](/docs/deployment) — how artifacts travel from Studio to objectos.
content/docs/kernel/index.mdx:46:- … covered in [Deployment & Operations](/docs/deployment).

Then the whole tree, with a pattern that matches the index itself and not its subpages — /docs/deployment not followed by /, a word character, or -.

The run used grep -rnP with a negative lookahead. GitHub's body sanitizer strips the exclamation mark out of that construct, so the literal cannot be carried in this text; the POSIX form below was verified to produce byte-identical output (9 lines each, diff clean) and is the one to copy:

$ grep -rnE '/docs/deployment([^/[:alnum:]_-]|$)' content/

9 links across 8 files — 3 defective, 1 examined and cleared, 5 already correct. Nothing outside content/ links the index (the same expression over *.md, *.mdx, *.ts, *.tsx, *.json excluding node_modules returned nothing). There are no trailing-slash (/docs/deployment/) or fragment (/docs/deployment#…) forms.

# Site Label Verdict
1 ui/setup-app.mdx:125 Cloud Deployment fixed
2 automation/hook-bodies.mdx:346 Cloud Deployment fixed
3 kernel/index.mdx:46 Deployment & Operations fixed
4 api/environment-routing.mdx:128 Deployment Overview already correct
5 index.mdx:51 a Card component, title="Deployment & Operations" examined, left alone — see below
6 deployment/single-project-mode.mdx:113 Deployment Overview already correct
7 deployment/self-hosting.mdx:14 Deployment Overview already correct
8 deployment/self-hosting.mdx:436 Deployment Overview + a clause naming both lifecycles already correct — the in-repo precedent these three now follow
9 deployment/publish-and-preview.mdx:221 Deployment Overview already correct

Why row 5 is not a fourth fix

content/docs/index.mdx:51 is one card in the ## Platform modules grid, and that grid uses section titles for section-root links throughout — including where they diverge from the landing page's title:

Card label (section title) Page it lands on
Views & Apps → /docs/ui UI Engine
API & SDK → /docs/api API Overview
Deployment & Operations → /docs/deployment Deployment Overview

Changing only the deployment card would break a deliberate, uniform convention across nine cards — and re-titling the grid is a restructure, not a relabel. Left as-is on purpose.

Out-of-scope finding, filed not fixed

The sweep turned up the same shape against a different target, on the very same line as fix 3: [Plugins & Packages](/docs/plugins) labels a page whose own title is Plugin System. It is not fixed here — different link target, and whether it is even wrong depends on an unmade judgement (section reference vs page reference) that the grid convention above actively argues both ways on. Filed unassigned as #10476 with both readings laid out. Naming it explicitly so the untouched label on an edited line does not read as an oversight.

Changeset: none, judged by publish surface

Checked rather than defaulted. content/ sits outside every workspace glob in pnpm-workspace.yaml (packages/*, packages/*/*, apps/*, examples/*); the only consumer is apps/docs, which is "private": true and publishes nothing. These three files are not a published package surface, so this PR releases nothing and carries the skip-changeset label instead.

Gates

All of the below were run after the final commit and measured at 6cdb7a9c10 with a clean working tree.

Gate families derived with node scripts/pm/dispatch-gates.mjs (no paths passed — it derives its own change set from the merge base), re-derived at the final commit: the same 12 families, no additions. All green, plus check:nul-bytes.

Gate Its own verdict line
check:doc-anchors ✅ check-doc-anchors: 256 internal #fragment link(s) across 400 source file(s) all resolve to a real heading
check:docs-redirects check-docs-redirects: OK (apps/docs/redirects.mjs: 92 entries -- 89 page destination(s) resolved against content/docs …)
check:runtime-services-index ✓ check-runtime-services-index: 8 chapter page(s) vs meta.json "pages", 8 chapter-list bullet(s) and 8 kernel/index.mdx table row(s) … all enumerations agree
check:docs-audit-scope ✓ docs-accuracy-audit scope is in sync with content/docs/: 181 hand-written doc(s).
check:role-word check-role-word: OK, no new occurrences of the reserved word.
check:published-readme-links ✓ check:published-readme-links — 152 outbound link(s) across 60 published markdown file(s)
check:cross-package-test-inputs exit 0 (also run raw as node scripts/check-cross-package-test-inputs.mjs)
spec: check:liveness · check:empty-state · check:strictness-ledger · check:variant-docs all ✓ — each echoed @objectstack/spec@17.1.0 check:…, so none was a zero-match --filter no-op
check:nul-bytes check-nul-bytes: OK (scanned 6141 text file(s) … no raw ASCII control bytes).

lychee link-checking runs in CI and is not reproducible locally; no link target changed, so no destination moved.


Generated by Claude Code

…n title

Three pages outside the deployment section linked the section index under
labels naming neither of its two lifecycles. The target page is titled
"Deployment Overview" and forks into "The platform runtime — you operate it"
and "Your metadata app — you build it".

- ui/setup-app.mdx and automation/hook-bodies.mdx said "Cloud Deployment".
  The page is not cloud-specific; ObjectStack Cloud is one venue inside the
  platform-runtime half. Both now use the page title plus a trailing clause
  naming which half the reader is sent to.
- kernel/index.mdx used the section title ("Deployment & Operations", from
  content/docs/deployment/meta.json) as the label for the page. Both strings
  live in the nav, which is what made the mismatch hard to notice.

Labels only — no link target, heading or page structure changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
@github-actions github-actions Bot added size/xs documentation Improvements or additions to documentation labels Aug 21, 2026
@os-zhuang os-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 21, 2026 — with Claude

Copy link
Copy Markdown
Contributor Author

PM review — ⭐ accepted. The census is what lifts this above a three-line edit.

Reviewed against the diff.

You read the target before relabelling, which was the one thing that could have gone quietly wrong. The page is Deployment Overview, forking into "The platform runtime — you operate it" and "Your metadata app — you build it", with Docker/Compose/K8s/Cloud as venues inside the first half. A label chosen without opening that page could easily have named a venue again and repeated the defect in new words.

⭐ And each replacement was fitted to its own clause rather than globally substituted — setup-app's Related bullets take no trailing period, hook-bodies' See-also bullets do, and kernel/index.mdx:46 is mid-sentence prose whose surrounding words ("running the kernel in production") already name the half, so only the label token moved. Three files, +3/−3. A sed would have been wrong in at least two of them.

⭐ The census changed what the card means

The card presented three sites. You swept and found 9 links across 8 files — 3 defective, 1 examined and cleared, 5 already correct — and stated the conclusion plainly: "three was what the card noticed, not the count." The five correct ones all say "Deployment Overview", so the repo already had a convention and these three were the outliers, not the pioneers. Using self-hosting.mdx:436 — which already carries a trailing clause naming both lifecycles — as the in-repo precedent for your two rewritten clauses is better than inventing a phrasing.

✅ Positive control before the zero-hit, as asked: the expression was made to return the three known instances first. And the sweep extended outside content/ (*.md/*.mdx/*.ts/*.tsx/*.json) returning nothing, including trailing-slash and #fragment forms.

⭐ The examined-and-cleared row is the judgement I'd have wanted

content/docs/index.mdx:51 labels its card "Deployment & Operations" — the section title, not the page title — and you left it, because that grid uses section titles for section-root links throughout, including where they diverge (Views & Apps → UI Engine, API & SDK → API Overview). Changing one card would break a uniform nine-card convention, and re-titling the grid is a restructure, not a relabel. ⛔ Correctly out of scope, and recorded rather than silently skipped.

Same restraint on #10476: an adjacent wrong-looking label on the very same line you edited (/docs/plugins → "Plugins & Packages" vs the page's "Plugin System"), filed with both readings because section-reference vs page-reference is an unmade judgement — and named in the PR body so an untouched label on an edited line doesn't read as an oversight. That last touch is the kind of thing that saves a reviewer a round trip.

Verified

  • ✅ ⛔ Labels only — no link target, heading, page structure or meta.json title touched.
  • ✅ ⛔ content/docs/releases/** untouched; record-view-auditing.mdx (held by docs(plugin-audit): document the os serve opt-in, and rule out a config-derived audit options helper #10450) untouched.
  • ✅ skip-changeset correct here and reasoned, not assumed: content/ is outside every pnpm-workspace glob and its only consumer apps/docs is private: true.
  • ⚠️ Line drift caught and reported — hook-bodies is at 346 on current main, not the card's 345 (card was written against 8b9eba51b).
  • ⭐ 12 gate families, and you checked the gates themselves weren't vacuous: the four spec-filtered ones each echoed @objectstack/spec@17.1.0 check:…, "confirming a real run rather than a zero-match --filter no-op that would have exited 0 having run nothing." Applying the anti-vacuity rule to your own verification tooling is the right instinct.
  • ✅ Edits proven on disk in both directions rather than trusted from an editor's exit code.

⚠️ One note on the earlier Check Changeset red: that gate ran at 00:31:44 and skip-changeset landed at 00:32:28 — it re-ran itself at 00:32:32 and returned skipped, correctly. Not your failure, and nothing to do; I briefly miscounted the superseded run as live.

Nothing for you to change. Flipping ready and arming once the last check clears.


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 21, 2026 00:41
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 21, 2026
Merged via the queue into main with commit 724437c Aug 21, 2026
31 of 32 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-8984-deployment-index-link-labels branch August 21, 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/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: three pages link the deployment section index under labels that name neither of its two lifecycles

2 participants