Skip to content

Ban / in metadata item names — retire compound-name addressing (maintainer-ruled direction): census, migration surface, staged plan #12176

Description

@os-trump

Filed by the PM session on the maintainer's direct-dispatch instruction (2026-08-25, PM chat, verbatim and untranslated: 「我认为斜杠不该存在」 · 「斜杠不该存在,现在就立卡,你负责派发,然后给我结果」). PM session session_01H9StxQgG2DPA26XzZZqnJB. Suggested lane for triage: domain:spec (name grammar is contract surface); filed and dispatched under the maintainer direct-dispatch channel.

The ruling (direction — not re-adjudicable on this card)

Metadata item names must not contain /. The compound-name addressing convention (views/all_leads, crm/task — "sub-resources spelled as a slash inside the name string") is to be retired: item names converge on the platform's standard identifier grammar (/^[a-z][a-z0-9_]*$/, the same class every other identifier on the platform already uses), and the sub-resource relationship, where real, is expressed by structure (separate section/parent parameter or containment), never by a separator inside the identity string.

Why (maintainer-endorsed reasoning, recorded for the implementer): identity-with-separator is the measured root cause of an entire defect family — URL arity mismatches (#12106: four SDK methods 404), dual-arity route mounting obligations (#7526, #11712, #11932/PR #12105), route-shadowing hazards (measured in PR #12105), and a two-rule URL-spelling split inside one SDK file. Every platform identifier except item names is already slash-free by declared grammar.

This card = phase 1 only: census + migration surface + staged plan. ⛔ Report-only

Named, falsifiable premise (per the third-tier ruling form): the slash lives at the addressing boundary (REST/dispatcher fold :section/:name back into ${section}/${name}; SDK docblocks/tests; a handful of store keys), not deep in engine identity. Early readings supporting it, to be verified rather than inherited: literal slash-names grep to SDK docs/tests + protocol docs only — zero hits in packages/platform-objects, engine packages, or examples/** authoring sources; the folds are at packages/rest/src/rest-server.ts:6552-6555 and packages/runtime/src/domains/meta.ts:336.

⛔ If the census falsifies the premise (slash-names are load-bearing engine identity, or the migration surface is explosive), report the fork with the evidence — do not soften the census to fit the ruling, and do not start implementing.

What to measure (each with commands the next reader can re-run; every zero beside a positive control)

  1. Producers. Every code path that can create a slash-name: metadata-protocol store keying (publishMetaItem et al.), sys_metadata rows written on publish, draft ledger keys, CLI build/extract outputs, engine registries/loaders, Studio/metadata-admin save paths, examples corpus. Who writes views/all_leads-shaped names, and is the section half ever semantic (a real namespace) vs redundant with type?
  2. Grammar status. Does spec/protocol constrain item names at all? Accept-probe the real protocol: a snake_case name (control, accepted), a one-slash name, a two-slash name, empty section. Believed unconstrained — measure, don't assume.
  3. Consumers of compound addressing. Full inventory: SDK methods (the 6 unencoded + 4 encoded per Four SDK metadata methods build compound-name URLs against routes mounted in one arity only — measured 404, and getHistory/deleteItem encode while getAudit/getReferences/diffItem/rollbackItem do not #12106), REST single-arity slash-through + the mounted compound arities (getItem/saveItem twins, /published Three ledgered /meta routes are never mounted and die in the /meta/:type catch-all — the route audit can't see this class because it treats the ledger as ground truth for what's mounted #7526, ?mode=draft PUT The compound-name PUT /meta/:type/:section/:name never threads ?mode=draft, while its single-segment twin does — the fourth divergence closed, a fifth left open #11712, /publish A compound-name draft has no REST promotion door — POST /meta/:type/:name/publish is mounted in one arity while its read twin /published is mounted in both #11932/PR feat(rest): mount the compound-name per-item promotion door POST /meta/:type/:section/:name/publish (#11932) #12105 — merged today), docs pages (client-sdk.mdx:213, error-catalog.mdx:599), tests pinning unencoded URLs (client.test.ts:325-334, meta-automation-descriptors.test.ts:30, protocol.unrecognised-meta-type.test.ts:297-311).
  4. Stored-data exposure. In a seeded/booted store (example apps): how many live rows/draft keys actually carry /? (A compound-name draft has no REST promotion door — POST /meta/:type/:name/publish is mounted in one arity while its read twin /published is mounted in both #11932's measurement seeded crm/task — is that shape test-only or does real authoring produce it?)

Deliverable

An os-dev-report (issue comment + JSON) carrying: the four census tables · the complete migration-surface inventory · a staged plan proposal with one card draft per stage (suggested shape, adjust to the evidence: D1 declare the name grammar in spec + loud publish-time refusal of NEW slash-names (Clause-② yes, contract tier) → D2 migrate existing stored slash-keys → D3 re-address REST/SDK (compound arities retired or re-keyed to explicit section params; the #12106 four-method defect dissolves here) → D4 docs/tests/changelog sweep) · per-stage Clause-② flags and blast radius · the premise verdict. Also state what phase 1 cannot see (cross-repo consumers in objectui/cloud; out-of-repo customer data).

⛔ No production code changes on this card. Out-of-scope findings filed as unassigned cards with back-links. ⛔ Do not revert or modify anything #11932/PR #12105 landed — supersession is D3's job, ruled separately.

Dispositions this card supersedes or blocks

Refs: #12106 · #11932 / PR #12105 · #11712 · #7526 · content/docs/api/client-sdk.mdx:213 · content/docs/api/error-catalog.mdx:599.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions