Skip to content

docs(api): retire the compound-name spelling from the live docs (#12176 stage 4) - #12381

Merged
os-trump merged 1 commit into
mainfrom
claude/issue-12196-compound-name-docs-sweep
Aug 26, 2026
Merged

docs(api): retire the compound-name spelling from the live docs (#12176 stage 4)#12381
os-trump merged 1 commit into
mainfrom
claude/issue-12196-compound-name-docs-sweep

Conversation

@os-trump

Copy link
Copy Markdown
Collaborator

Fixes#12196
Part of #12176 — stage 4 (docs sweep).

D1 (#12194) declared the item-name grammar and refuses every slash-bearing name at the
publish door; D3 (#12195) un-mounted the three compound :section arities. D3's diff
touched zero docs files
, so the whole live-docs surface was still teaching names that
can no longer be created and routes that are no longer mounted. This corrects it.

FROM → TO

content/docs/api/client-sdk.mdx (lines 216-217)

FROM// Compound names (sub-resources) pass through unencoded
const view = await client.meta.getItem('object', 'views/all_leads');
TO// Sub-resource identity is DOT-qualified — `<object>.<viewKey>`, never a `/`
const view = await client.meta.getItem('view', 'crm_lead.pipeline');

Both halves of the old line were dead, for two different reasons. The name is refused
at the publish door by D1. The "unencoded" promise was retired by D3, which put
encodeURIComponent on every /meta item address to close the 10-unencoded / 4-encoded
split — there is no unencoded pass-through left to teach.

The replacement is not invented: crm_lead.pipeline is the grammar's own published
exemplar (METADATA_ITEM_NAME_PATTERN's TSDoc, ViewItemNameSchema's refusal message,
and the generated content/docs/references/api/protocol.mdx row D1 already landed), and
it is exactly ViewItemNameSchema's <object>.<viewKey> identity — so under type view
the example teaches the enforced shape rather than minting a second one.

content/docs/api/error-catalog.mdxINVALID_REQUEST — unmintable metadata type

FROM (line 576)the type segment, and the exemptions below decide whether it fires at all.
TOthe type segment, and the exemption below decides whether it fires at all.
FROM (line 592)**Two shapes reach this door and are served, not refused** — neither of them visible in
the message, so a caller who does not read this entry finds them by collision:
TO**One shape reaches this door and is served, not refused** — it is not visible in the
message, so a caller who does not read this entry finds it by collision:
FROM (lines 595-601)Numbered exemption 1. Compound arity — "A name containing / exempts the request… PUT /meta/lead/views/all_leads is type='lead', name='views/all_leads'PUT /meta/fieldz/a/b is therefore acceptedPUT /meta/lead/all_leads is still refused."
TODeleted, and replaced by a short retirement paragraph naming what changed: item names may no longer contain /, the compound arities are un-mounted, and PUT /meta/fieldz/a/b is no longer accepted and no longer reaches this verdict at all.
FROM (line 602)2. **Pre-existing namespace.** … (numbered list item)
TO- **Pre-existing namespace.** … (bullet — the list has one member now; wording otherwise unchanged)
FROM (line 626)door is what stops the first row from being written; the exemptions above are what keep
TOdoor is what stops the first row from being written; the exemption above is what keeps

Why the compound exemption is deleted rather than respelled. It has no dot-spelling —
it was an exemption from a verdict, not a name. And it was already false before this PR:
refuseUnmintableMetaType's own header in packages/metadata-protocol/src/protocol.ts
records that the slash exemption was removed by #12194 (D1), not by D3 —
refuseUngrammaticalMetaItemName runs first and refuses every slash-bearing name before
the probe is reached. The source names the corrected facts, including the residue that is
now shut, so the replacement text is pinned by landed code rather than by this PR's
judgement.

I kept a brief "retired" note rather than deleting silently: a caller who knew the old
behaviour would otherwise read the page as merely incomplete. It marks the spelling dead —
it does not teach it as usable.

Census — the population I measured

403.md/.mdx files under content/docs/** on the post-D3 ref (7986d973),
independently corroborated by check-doc-frontmatter's own count: "content/docs
(pageSchema, floor 1): 403 page(s) parse"
.

Instrument proven before trusting any zero — positive control views/all_leads fires
on exactly 2 lines, both censused pages. Patterns then swept: crm/task, :section,
compound/Compound, sub-resource, unencoded, %2F, all_leads, getItem(,
saveItem(, slash, quoted '<snake>/<snake>' shapes, and 3-segment
/meta/<x>/<y>/<z> paths.

Result: the two censused pages were the entire live surface. Everything else the
patterns caught is a true negative and was left alone —

  • 3-segment /meta/ hits are surviving literal routes (/publish, /rollback,
    /history, /audit, /diff, /layers, /references, /tree, /schema,
    /state/:field), all still mounted.
  • Quoted <a>/<b> hits are MIME types (application/json, image/jpeg), not item names.
  • compound hits are state-machine node types, compound DB indexes and compound view
    cells — unrelated vocabulary.
  • page:section / _sections are layout and i18n concepts, not the retired route segment.
  • content/docs/references/api/protocol.mdx:2336 already teaches the new grammar (landed
    by D1) — left untouched.

Fences honoured:content/docs/releases/** (v14/v16/v17 carry compound-era text) not
touched; no CHANGELOG touched; no code, no packages/**.

Verification

All gates run on the final commit e68376d4 and quoted by their own verdict lines; exit
codes captured before any pipe. Family list self-derived by
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (change set: 2
paths, committed 2 / working tree 0) — 24 matched families, all green, plus
check:nul-bytes:

  • check:error-status-conformance"✓ every derivable runtime status is documented, and every documented status is reachable." (the gate that owns this exact page)
  • check:docs-audit-scope"✓ docs-accuracy-audit scope is in sync with content/docs/: 189 hand-written doc(s)." · "✓ release-owned pages are in scope and read-only: 9 page(s)"
  • check:doc-authoring"✓ doc authoring guard: 390 files clean — no bare metadata literals."
  • check:doc-anchors"✅ 278 internal #fragment link(s) across 408 source file(s) all resolve to a real heading"
  • check:doc-route-spelling"✓ route-spelling guard: population clean — every shape-matched literal spells its ledger row."
  • @objectstack/spec check:skill-examples"✅ 260 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them" (this is what type-checks the edited client-sdk.mdx example against the real built @objectstack/client declarations)
  • check:doc-frontmatter, check:docs-single-h1, check:docs-redirects, check:docs-section-name, check:section-landing-index, check:published-readme-links, check:role-word, check:react-page-adapter-contract, check:cross-package-test-inputs, check:ci-filter-parity, spec check:docs/liveness/empty-state/variant-docs/strictness-ledger, lint check:doc-formula-expressions/doc-security-posture — all exit 0
  • check:nul-bytes"OK (scanned 6852 text file(s) … no raw ASCII control bytes)"

Four gates first exited 1 with "PREREQUISITE NOT MET — nothing was measured" (missing
packages/spec/json-schema, unbuilt spec/lint/formula/client-reactdist). Those
were build-artifact prerequisites, not findings; after turbo run build for those packages
all four are green above.

No ablation is owed. The change is prose plus one example — there is no guard here
whose failure mode a mutation would demonstrate. The one executable artifact, the SDK
example, is covered by check:skill-examples' semantic tsc pass rather than by a fixture I
could ablate. Stating that rather than inventing one.

No changeset: docs-only, releases no package. check-empty-changeset exits 0 ("✓ No
empty-frontmatter changeset introduced by this diff"
), and pr-automation.yml's
changeset-check exempts only the skip-changeset label — which lint.yml calls the
prescription for a PR that "releases nothing". Label applied.


Generated by Claude Code

… stage 4)
Stage 4 of the #12176 maintainer-ruled retirement of slash-bearing metadata
item names. Stage 1 (#12194) declared the item-name grammar and refuses every
slash-bearing name at the publish door; stage 3 (#12195) un-mounted the three
compound `:section` arities. These two pages were still teaching both.
content/docs/api/client-sdk.mdx:
- The `meta.getItem` example addressed `'views/all_leads'` and promised
compound names "pass through unencoded". Both halves are dead: the name
is refused at the publish door, and #12195 put encodeURIComponent on
every /meta item address, so there is no unencoded pass-through left.
Respelled to the grammar's own published exemplar, `crm_lead.pipeline`
under type `view` — which is exactly ViewItemNameSchema's `<object>.<viewKey>`
identity, so the example teaches the enforced shape rather than a new one.
content/docs/api/error-catalog.mdx:
- The unmintable-type entry documented TWO exemptions reaching the door.
The compound-arity exemption is gone from the source (it was removed by
#12194, not #12195 — `refuseUngrammaticalMetaItemName` runs before the
probe and refuses every slash-bearing name), so the page has been
describing a served behaviour that no longer exists. Reduced to the one
surviving exemption, with a short retirement note so a caller who knew
the old behaviour is not left guessing.
- The residue that exemption documented — `PUT /meta/fieldz/a/b` being
accepted — is closed with it, and the page now says so.
- Two plural references to "the exemptions" corrected to the singular.
No changeset: docs-only, releases nothing (the `skip-changeset` case the
workflow prescribes). No ablation is owed — the change is prose and one
example, and the example is covered by check:skill-examples' semantic pass.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9StxQgG2DPA26XzZZqnJB
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Aug 25, 2026
@os-trumpos-trump added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Aug 25, 2026 — with Claude
@os-trump
os-trump marked this pull request as ready for review August 25, 2026 23:50
@os-trump
os-trump enabled auto-merge August 25, 2026 23:50
@os-trump
os-trump added this pull request to the merge queueAug 25, 2026
Merged via the queue into main with commit d80439fAug 26, 2026
38 checks passed
@os-trump
os-trump deleted the claude/issue-12196-compound-name-docs-sweep branch August 26, 2026 00:21
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

D4: docs sweep for the retired compound-name convention (#12176 stage 4)

2 participants

@os-trump@claude