docs(spec,metadata): point the four stale cluster-semantics.mdx citations at the live page - #17554
Conversation
…ions at the live page `content/docs/concepts/cluster-semantics.mdx` is no longer in the tree; `apps/docs/redirects.mjs` redirects `/docs/concepts/cluster-semantics` to `/docs/kernel/cluster`. Four in-source citations still named the dead file, so retrieval by filename found nothing even though following a link worked. The two halves get different spellings on purpose: - `packages/spec/src/kernel/events/core.zod.ts` and `service-registry.zod.ts` `.describe()` strings -> the SITE URL `/docs/kernel/cluster` (§4 / §5). `gen:docs` copies these into published reference pages and they also ship in `json-schema/` and `dist/`, so a repo path would send a site reader to a file they do not have. - `packages/metadata/src/metadata-manager.ts` source comments -> house style `` `content/docs/kernel/cluster.mdx` §6.2, lane 1 ``, matching the correction already merged a few hundred lines above in the same file. Both metadata comments are about `metadata.changed` / `ClusterMetadataChangedPayload` / cache invalidation, which is the §6.2 lane-1 row, not §5 (service registration and leader election). `apps/docs/redirects.mjs` is deliberately untouched, and the two reference pages under `content/docs/references/kernel/` are regenerated output (`build` then `check:generated --fix`), not hand edits. Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 2 package(s): 4 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 138 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 64af6b859c5a5b010ab2c98d1db35f64d40e8d1f && git checkout 64af6b859c5a5b010ab2c98d1db35f64d40e8d1f
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin ad715aca57b44bbe745a20cf20f339cd5195df14 bf55c7a9e96283f11de509485dd96205f4308ea8 && git checkout -B drift-repro ad715aca57b44bbe745a20cf20f339cd5195df14 && git merge --no-ff bf55c7a9e96283f11de509485dd96205f4308ea8
node scripts/docs-audit/affected-docs.mjs --json ad715aca57b44bbe745a20cf20f339cd5195df14
|
Fixes #15141
Four in-source citations named
content/docs/concepts/cluster-semantics.mdx, a page that is no longer in the tree.apps/docs/redirects.mjs:98redirects/docs/concepts/cluster-semanticsto/docs/kernel/cluster, so a reader following a link was fine; what was broken is retrieval by filename, which finds nothing.The two halves get different spellings, on purpose
packages/spec/src/kernel/events/core.zod.ts.describe()/docs/kernel/cluster§4packages/spec/src/kernel/service-registry.zod.ts.describe()/docs/kernel/cluster§5packages/metadata/src/metadata-manager.ts(x2)`content/docs/kernel/cluster.mdx` §6.2, lane 1The
.describe()half is the one that matters.gen:docscopies those strings into published reference pages, and they also ship as JSON Schemadescriptionvalues and as string literals in the package tarball — so a repo path there would tell a docs-site reader to open acontent/docs/...file they do not have. That is the same class of unfollowable reference as #15150, pointed the other way. The site URL is additionally redirect-independent: it is the redirect's target, so the reference survives the redirect being retired.There is no in-repo precedent for a docs-citing
.describe()— these two are the only ones in all ofpackages/spec/src— so the source-comment convention was deliberately not carried over to them.The card's §5 is wrong for the two metadata comments — they are §6.2 lane 1
Measured per-site against
content/docs/kernel/cluster.mdx, the four sites are not one answer:Both metadata comments are about
metadata.changed/ClusterMetadataChangedPayload/ cache invalidation. The §6.2 lane-1 row atcluster.mdx:334names exactly those three:metadata.changed·ClusterMetadataChangedPayload·@objectstack/metadata· convergesMetadataManager's registry/list caches. §5 is service registration and leader election, unrelated.Corroboration, verified rather than assumed: PR #15139 already corrected a fifth pointer in this same file, at
metadata-manager.ts:235, and it cites`content/docs/kernel/cluster.mdx` §6.2, lane 1. Following the card would have contradicted an already-merged correction a few hundred lines above.Four more sites exist repo-wide and are deliberately untouched
apps/docs/redirects.mjs:98— the redirect itself. It stays; deleting it is the opposite of this change.content/docs/references/kernel/events-core.mdx(x2) andservice-registry.mdx—gen:docsoutput, converged by regeneration, never hand-edited.Regeneration was part of the change:
pnpm --filter @objectstack/spec buildthencheck:generated --fix. It rewrote exactly those three rows in those two pages and nothing else. After the change, the only remainingcluster-semanticsstring repo-wide is the redirect.Changeset: MEASURED, and one is owed
The claim comment deliberately did not assert this. Measured against the published
files[]rosters, with a positive control on every reading:@objectstack/spec— publishes the change, so a changeset is owed. Itsfiles[]is["dist","json-schema","liveness","prompts","llms.txt","README.md","src/**/*.zod.ts","CHANGELOG.md","api-surface","spec-changes.json"]. Both edited files match thesrc/**/*.zod.tsentry and ship verbatim in the tarball. The new string is also present in 4 shipped bundles underpackages/spec/dist/and as adescriptionin 6 files under the shippedpackages/spec/json-schema/tree.@objectstack/metadata— publishes nothing here, so it is not in the changeset. Itsfiles[]is["dist","README.md","CHANGELOG.md"]; the comment text has zero hits inpackages/metadata/dist/, while two positive controls from the same source file (CLUSTER_CHANNEL,metadata.changed) are lit in 4-6 dist files each. Comments are stripped by the build.One reading correction worth recording, because it is the reason the controls exist: the first grep of
packages/spec/dist/for the new string returned zero — a false zero. The build emits§as an escaped\xA7, so the literal did not match. The positive control was lit, which is what prompted the re-grep that found it. A zero is not an absence.Changeset:
@objectstack/spec: patch.Contract review scope
Clause-②: no
Re-derived from what shipped, not inherited. No accept set moves in either direction, no authorable key is added or removed, no closed-set member or published export changes. The diff is two
.describe()description strings, two source comments, three regenerated table rows and a changeset. The.describe()strings are published prose, not a published contract — parse behaviour and exported types are byte-identical.Verification
All at final head
bf55c7a9e9.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, re-derived after the changeset existed (it grew from 96 to 101 commands — the changeset families apply only once the file exists). All 101 run; reconciled with--ran:101 derived, 101 run, 0 NOT-MEASURED, 0 UNRUN.check:skill-examplesexited 1 withpackages/client-react/dist holds no .d.ts declarations — the package is not built. That is a gate refusing its own prerequisite, not a verdict. It type-checks spec source TSDoc, which this diff edits, so the prerequisite was built and it was re-run: green, 258 prose examples across 3 surfaces.check:dual-build-cjs-loadsandcheck:lean-entry-closureexited 3 withPREREQUISITE NOT MET; both need a whole-repo build (58+ packages with nodist/). NOT MEASURED — neither a pass nor a failure. Left to CI, which builds the tree. This diff moves no entry point or export, so neither gate has a path to move.check:docsgreen — the gate this change is measured by:222 generated files in sync with packages/spec.check:generated,check:docs-redirects,check:nul-bytes,check:published-filesalso green at final head.pnpm --filter @objectstack/spec --filter @objectstack/metadata test— specTest Files 472 passed (472)/Tests 13368 passed (13368); metadataTest Files 53 passed (53)/Tests 788 passed (788). (The metadata log contains ERROR lines by design — a test drives a loader outage.)packages/spec typecheck$ tsc --noEmit && ...,packages/metadata typecheck$ tsc --noEmit) so this is not a zero-script no-op.eslint . --no-inline-config --format jsoncompleted in budget atbf55c7a9e9: 6588 files, 0 errors, 0 warnings. The file count is read from eslint's own JSON output, and the population is eslint's own config resolution rather than a hand-built path list, so no narrowing claim is needed here.验收备注
noted, not filed—packages/services/service-cluster/src/cluster.ts:78throws a runtime error whose text endsSee content/docs/kernel/cluster.mdx §6.That is a repo path handed to an application developer consuming the published@objectstack/service-clusterpackage, who does not have the repo — arguably the same unfollowable-reference class this PR removes from the two.describe()strings. Not filed: it meets none of the three filing classes (it is not a reproducible defect, breaches no declared contract, and is not a trap producing metadata the runtime refuses). It is also outside this card's scope and outside the claim's declared file face. Successor: none known — no in-flight PR or queued card that I can name touches this file.Generated by Claude Code