Skip to main content

Workspace Composition Namespace, Diagnostics, And Versioning

This document is the canonical v0 spec for WCP-003: Write namespace, diagnostics, and versioning spec.

It locks the machine-readable contracts needed by @maya/assistant-composition, render runtimes, module packages, and future conformance tests.

Primary linked decisions:

  • WCP-ADR-003: opaque render handles
  • WCP-ADR-006: module contributions are namespaced
  • WCP-ADR-015: diagnostics are product inputs

Adjacent decisions referenced by the registry:

  • WCP-ADR-004: scoped React render runtime
  • WCP-ADR-010: explicit v0 composition policy
  • WCP-ADR-012: no default text message override in v0

Scope

This spec owns:

  • canonical ID grammar
  • contribution namespace grammar
  • route path validation and effective path conflict semantics
  • renderer claim grammar and conflict semantics
  • structured diagnostic object semantics
  • diagnostic code registry
  • schema version field names
  • golden fixture case inventory

This spec does not own:

  • composeWorkspace() result object shape, which belongs to WCP-005
  • full CompositionPolicy JSON shape, which belongs to WCP-005 and WCP-010
  • React render runtime behavior, which belongs to WCP-006
  • trust, grant redaction, and security enforcement policy, which belongs to WCP-004
  • exported TypeScript API implementation, which starts in WCP-007, WCP-008, WCP-009, WCP-010, and WCP-011

Canonical Namespace Grammar

The unit of enablement is a module instance, not a package.

canonicalContributionKey = `${ownerId}:${contributionKind}/${localId}`

ownerId is:

  • a module instanceId for module-owned contributions
  • a built-in owner id for product-owned contributions

Built-ins must use the same owner model as modules. They are not special merge cases.

type ContributionOwner = {
ownerKind: 'module' | 'builtin';
ownerId: string;
packageId?: string;
packageVersion?: string;
};

instanceId

instanceId identifies one enabled module instance.

Grammar:

instanceId = lower-alnum *( lower-alnum | "-" )

Rules:

  • must start with lowercase ASCII letter or digit
  • may contain lowercase ASCII letters, digits, and hyphens
  • length must be 3 to 64 characters
  • must not contain colon, slash, dot, whitespace, uppercase letters, or random suffixes
  • must be globally unique within one composed workspace

Examples:

  • valid: data-lab-prod
  • valid: github-staging
  • valid: mcp2
  • invalid: DataLab
  • invalid: data/lab
  • invalid: data:lab
  • invalid: dl

Built-In Owner IDs

Built-in owner ids use the reserved prefix builtin-.

Examples:

  • builtin-claude-chat
  • builtin-claude-projects
  • builtin-claude-settings

Modules must not use an instanceId starting with builtin-.

contributionKind

contributionKind identifies the contribution collection.

Allowed v0 values:

  • routes
  • sidebar-items
  • configuration-surfaces
  • integration-surfaces
  • message-renderers
  • message-appenders
  • tool-renderers
  • activity-renderers
  • fallback-surfaces

New contribution kinds require a decision or spec update before implementation.

localId

localId is only unique inside one owner and contribution kind.

Grammar:

localId = lower-alnum *( lower-alnum | "-" | "." )

Rules:

  • must start with lowercase ASCII letter or digit
  • may contain lowercase ASCII letters, digits, hyphens, and dots
  • length must be 1 to 80 characters
  • must not contain colon, slash, whitespace, uppercase letters, or random suffixes
  • may repeat across different module instances

Examples:

  • valid: home
  • valid: connection
  • valid: tool.query-result
  • invalid: ToolCard
  • invalid: settings/panel

Canonical Contribution Keys

Examples:

data-lab-prod:routes/home
data-lab-prod:configuration-surfaces/connection
github-staging:tool-renderers/search-result
builtin-claude-chat:routes/chat

Rules:

  • duplicate canonical contribution keys are errors
  • same localId across different instanceId values is valid
  • import order must never resolve duplicate ownership
  • automatically generated random IDs are forbidden

Route Paths

Route paths are user-visible URL paths inside the workspace.

Grammar:

routePath = "/" | "/" path-segment *( "/" path-segment )
path-segment = lower-alnum *( lower-alnum | "-" | "_" )

Rules:

  • must start with /
  • must not end with /, except the root path /
  • must use lowercase ASCII letters, digits, hyphens, underscores, and slashes only
  • must not contain repeated slashes
  • must not contain dot segments, backslashes, percent encoding, protocol, or host
  • must not include query strings, hashes, URL parameters, or dynamic route syntax
  • host-owned routers may map params and search state outside the contribution key
  • module routes should not claim / in v0; root is reserved for product-kit built-ins unless explicit host policy allows it

Normalization:

  • v0 route declarations must already be canonical
  • the composer does not lowercase, trim, percent-decode, collapse repeated slashes, or add suffixes
  • pathAlias changes the effective path used for conflict checks, but it does not change the canonical contribution key
  • path comparison is exact after validation and policy application

Examples:

  • /data-lab
  • /data-lab/runs
  • /github-staging

Invalid examples:

  • data-lab
  • /DataLab
  • /data-lab/
  • /data-lab?tab=runs
  • /projects/:id
  • /data//lab
  • /data.lab
  • /data/%6cabs
  • https://example.com/data-lab

Renderer Claims

Renderer claims describe ownership of non-default rendering surfaces.

Claim grammar:

rendererClaim = `${rendererKind}:${claimValue}`

Allowed v0 renderer kinds:

  • message
  • tool
  • activity

Claim value grammar:

claimValue = lower-alnum *( lower-alnum | "-" | "_" | "." | "/" )

Rules:

  • ordinary default user and assistant text messages are not claimable in v0
  • custom module message types must use message:<type>
  • tool renderers must use tool:<toolName>
  • activity renderers must use activity:<activityKind>
  • duplicate claims are errors unless explicit rendererOverride policy resolves them
  • claim values are exact protocol strings and are not forced into localId grammar

Examples:

  • message:data-lab.result
  • tool:data_lab.query
  • activity:data-lab.query.started

Invalid examples:

  • message:assistant-text
  • message:user-text
  • tool:*
  • activity:

Message Appenders

Message appenders are contributions, not exclusive renderer claims.

Multiple appenders may target the same message type and position. They are ordered by explicit policy first and canonical contribution key second.

Appender contribution example:

data-lab-prod:message-appenders/related-artifacts

Appender target example:

targetMessageType = "assistant-text"
position = "after"

Message appenders still cannot replace default text rendering.

Module Author Example

Input:

const dataLabModule = {
packageId: '@maya/data-lab-module',
packageVersion: '0.1.0',
moduleApiVersion: '0.1',
instanceId: 'data-lab-prod',
contributions: {
routes: [
{
id: 'home',
path: '/data-lab',
renderHandle: {
renderHandleVersion: '0.1',
kind: 'route',
id: 'data-lab.home',
},
},
],
sidebarItems: [
{
id: 'home',
label: 'Data Lab',
routeKey: 'data-lab-prod:routes/home',
},
],
configurationSurfaces: [
{
id: 'connection',
purpose: 'connection',
renderHandle: {
renderHandleVersion: '0.1',
kind: 'configuration-surface',
id: 'data-lab.connection',
},
},
],
toolRenderers: [
{
id: 'query-card',
claim: 'tool:data_lab.query',
renderHandle: {
renderHandleVersion: '0.1',
kind: 'tool-renderer',
id: 'data-lab.query-card',
},
},
],
},
};

Generated keys and claims:

data-lab-prod:routes/home -> /data-lab
data-lab-prod:sidebar-items/home
data-lab-prod:configuration-surfaces/connection
data-lab-prod:tool-renderers/query-card
tool:data_lab.query

Version fields used by the platform:

moduleApiVersion = 0.1
compositionSchemaVersion = 0.1
renderHandleVersion = 0.1
diagnosticSchemaVersion = 0.1

Conflict Rules

The composer must produce deterministic diagnostics for conflicts.

Errors:

  • duplicate instanceId
  • invalid instanceId
  • duplicate canonical contribution key
  • invalid localId
  • duplicate effective route path
  • invalid route path
  • duplicate renderer claim
  • invalid renderer claim
  • default user or assistant text renderer override attempt
  • unsupported schema version

Policy may resolve only these v0 conflicts:

  • route path conflicts through explicit pathAlias
  • renderer claim conflicts through explicit rendererOverride
  • contribution ownership replacement through explicit descriptor-level replace

Policy must not resolve conflicts by:

  • import order
  • silent suffixing
  • wildcard ownership
  • DOM selectors
  • local built-in page patching

Structured Diagnostics

Diagnostics must be JSON-serializable, deterministic, and testable.

Tests should assert structured fields, not prose messages.

type CompositionJsonPrimitive = string | number | boolean | null;
type CompositionJsonValue = CompositionJsonPrimitive | readonly CompositionJsonValue[] | CompositionJsonObject;
type CompositionJsonObject = { readonly [key: string]: CompositionJsonValue };

type WorkspaceDiagnostic = {
diagnosticSchemaVersion: '0.1';
code: WorkspaceDiagnosticCode;
severity: 'error' | 'warning' | 'info';
origin:
| 'composer'
| 'render-runtime'
| 'host-helper'
| 'module-conformance';
category:
| 'structure'
| 'namespace'
| 'route'
| 'renderer'
| 'version'
| 'policy'
| 'handle';
subjects: DiagnosticSubject[];
details: CompositionJsonObject;
decisionIds: string[];
docsAnchor: string;
message: string;
};

message is for humans. It is not the compatibility contract.

Diagnostic Subjects

type DiagnosticSubject = {
ownerKind?: 'module' | 'builtin' | 'host';
ownerId?: string;
packageId?: string;
contributionKind?: string;
localId?: string;
canonicalKey?: string;
routePath?: string;
rendererClaim?: string;
};

Rules:

  • diagnostics about ownership conflicts must include all conflicting owners
  • diagnostics about route conflicts must include declared and effective route paths when policy changes them
  • diagnostics about version mismatches must include supported and received versions
  • diagnostics must include linked decision IDs when the failure protects an architectural lock

Diagnostic Detail Shapes

Registry Required Details names use these stable shapes:

  • owner: one DiagnosticSubject
  • owners: array of DiagnosticSubject, sorted by ownerKind, then ownerId, then canonicalKey
  • instanceId: module instance id string
  • selectedOwner: one DiagnosticSubject
  • overriddenOwners: array of DiagnosticSubject, sorted by ownerKind, then ownerId, then canonicalKey
  • field: version or input field name as a string
  • expected: expected type, enum, or schema version set as a string or sorted string array
  • received: received version or value as a string
  • supported: sorted string array of supported versions
  • value: invalid value as a string
  • reason: stable reason code string, not prose
  • canonicalKey: canonical contribution key string
  • routePath: declared route path string
  • effectivePath: path after explicit policy application
  • originalPath: route path before explicit policy application
  • aliasedPath: route path after explicit pathAlias policy application
  • rendererClaim: renderer claim key string
  • policyId: host-authored policy id string
  • target: canonical contribution key, renderer claim, or operation:<id> targeted by policy
  • use: canonical renderer contribution key requested by rendererOverride
  • renderHandle: opaque render handle id or serialized handle summary
  • kind: render handle kind string
  • provider: JSON-safe render provider summary with owner, packageId, optional packageVersion, handle, loadKind, optional moduleId, and optional trustTier; loadKind is eager or lazy for valid providers and unsupported only for invalid provider-shape summaries; it must not include component functions, controllers, loaders, preload functions, errors, stacks, or raw handle data values
  • providers: array of provider summaries in supplied pack/provider traversal order; diagnostics consumers must not treat this order as winner selection
  • admissionReason: stable render admission block reason string
  • unsupportedReason: stable unsupported render provider reason string, one of runtime-schema-version, render-handle-version, or provider-shape
  • failurePhase: stable render load failure phase string, one of provider-preload or lazy-load
  • defaultRenderer: protected default renderer id string

Fixture tests must sort owner arrays before assertion. They must not assert the human message as the primary compatibility contract.

Diagnostic Code Registry

This registry is the only prose source for v0 diagnostic codes. Codes are never reused.

Changing a code's severity, required details, or category is a public contract change after v0 publication.

The Fixture IDs column names the canonical fixture for each code. Additional matrix fixtures may assert the same code when they cover a related edge case.

CodeSeverityOriginCategoryRequired DetailsFixture IDsDecisions
WCP-STRUCT-001errorcomposerstructurefield, expected, received, reasonfixture-invalid-input-shapeWCP-ADR-001, WCP-ADR-015
WCP-NS-001errorcomposernamespaceinstanceId, ownersfixture-duplicate-instance-idWCP-ADR-006, WCP-ADR-015
WCP-NS-002errorcomposernamespacevalue, field, reasonfixture-invalid-instance-idWCP-ADR-006, WCP-ADR-015
WCP-NS-003errorcomposernamespacecanonicalKey, ownersfixture-duplicate-canonical-keyWCP-ADR-006, WCP-ADR-015
WCP-NS-004errorcomposernamespacevalue, field, reasonfixture-invalid-local-idWCP-ADR-006, WCP-ADR-015
WCP-ROUTE-001errorcomposerrouteeffectivePath, ownersfixture-duplicate-route-pathWCP-ADR-006, WCP-ADR-015
WCP-ROUTE-002errorcomposerrouteroutePath, reason, ownerfixture-invalid-route-pathWCP-ADR-006, WCP-ADR-015
WCP-ROUTE-003infocomposerrouteoriginalPath, aliasedPath, policyId, ownerfixture-route-path-aliasWCP-ADR-010, WCP-ADR-015
WCP-RENDERER-001errorcomposerrendererrendererClaim, ownersfixture-duplicate-tool-renderer-claimWCP-ADR-003, WCP-ADR-015
WCP-RENDERER-002errorcomposerrendererrendererClaim, reason, ownerfixture-invalid-renderer-claimWCP-ADR-003, WCP-ADR-015
WCP-RENDERER-003errorcomposerrendererrendererClaim, owner, defaultRendererfixture-default-text-renderer-rejectedWCP-ADR-012, WCP-ADR-015
WCP-RENDERER-004infocomposerrendererrendererClaim, selectedOwner, overriddenOwners, policyIdfixture-renderer-overrideWCP-ADR-010, WCP-ADR-015
WCP-VERSION-001errorcomposerversionfield, received, supportedfixture-unsupported-composition-schema-versionWCP-ADR-015
WCP-VERSION-002errorcomposerversionfield, received, supported, ownerfixture-unsupported-module-api-versionWCP-ADR-015
WCP-VERSION-003errorcomposerversionfield, received, supported, ownerfixture-unsupported-render-handle-versionWCP-ADR-003, WCP-ADR-015
WCP-VERSION-004errorhost-helperversionfield, received, supportedfixture-unsupported-diagnostic-schema-versionWCP-ADR-015
WCP-VERSION-005errorcomposerversionfield, received, supportedfixture-unsupported-policy-schema-versionWCP-ADR-010, WCP-ADR-015
WCP-POLICY-001errorcomposerpolicypolicyId, target, reasonfixture-invalid-policy-targetWCP-ADR-010, WCP-ADR-015
WCP-HANDLE-001errorrender-runtimehandlerenderHandle, owner, kindfixture-render-runtime-missing-handleWCP-ADR-003, WCP-ADR-004, WCP-ADR-015
WCP-HANDLE-002errorrender-runtimehandlerenderHandle, owner, kind, providersfixture-render-runtime-duplicate-providerWCP-ADR-003, WCP-ADR-004, WCP-ADR-015
WCP-HANDLE-003errorrender-runtimehandlerenderHandle, owner, kind, provider, admissionReasonfixture-render-runtime-blocked-handleWCP-ADR-003, WCP-ADR-004, WCP-ADR-015
WCP-HANDLE-004errorrender-runtimehandlerenderHandle, owner, kind, provider, unsupportedReasonfixture-render-runtime-unsupported-providerWCP-ADR-003, WCP-ADR-004, WCP-ADR-015
WCP-HANDLE-005errorrender-runtimehandlerenderHandle, owner, kind, provider, failurePhasefixture-render-runtime-load-failedWCP-ADR-003, WCP-ADR-004, WCP-ADR-015
WCP-HANDLE-006errorrender-runtimehandlerenderHandle, owner, kind, providerfixture-render-runtime-render-failedWCP-ADR-003, WCP-ADR-004, WCP-ADR-015
WCP-HANDLE-007errorrender-runtimehandlerenderHandle, owner, kindfixture-render-runtime-unknown-target-fallbackWCP-ADR-003, WCP-ADR-004, WCP-ADR-015

Diagnostic Examples

Duplicate route path:

{
"diagnosticSchemaVersion": "0.1",
"code": "WCP-ROUTE-001",
"severity": "error",
"origin": "composer",
"category": "route",
"subjects": [
{
"ownerKind": "module",
"ownerId": "data-lab-prod",
"packageId": "@maya/data-lab-module",
"contributionKind": "routes",
"localId": "home",
"canonicalKey": "data-lab-prod:routes/home",
"routePath": "/data-lab"
},
{
"ownerKind": "builtin",
"ownerId": "builtin-claude-chat",
"packageId": "@maya/claude-workspace",
"contributionKind": "routes",
"localId": "data-lab",
"canonicalKey": "builtin-claude-chat:routes/data-lab",
"routePath": "/data-lab"
}
],
"details": {
"effectivePath": "/data-lab",
"owners": [
{
"ownerKind": "builtin",
"ownerId": "builtin-claude-chat",
"canonicalKey": "builtin-claude-chat:routes/data-lab"
},
{
"ownerKind": "module",
"ownerId": "data-lab-prod",
"canonicalKey": "data-lab-prod:routes/home"
}
]
},
"decisionIds": ["WCP-ADR-006", "WCP-ADR-015"],
"docsAnchor": "diagnostic-code-registry",
"message": "Route path '/data-lab' is claimed by multiple active contributions."
}

Duplicate renderer claim:

{
"diagnosticSchemaVersion": "0.1",
"code": "WCP-RENDERER-001",
"severity": "error",
"origin": "composer",
"category": "renderer",
"subjects": [
{
"ownerKind": "module",
"ownerId": "data-lab-prod",
"packageId": "@maya/data-lab-module",
"contributionKind": "tool-renderers",
"localId": "query-card",
"canonicalKey": "data-lab-prod:tool-renderers/query-card",
"rendererClaim": "tool:data_lab.query"
},
{
"ownerKind": "module",
"ownerId": "warehouse-prod",
"packageId": "@maya/warehouse-module",
"contributionKind": "tool-renderers",
"localId": "query-card",
"canonicalKey": "warehouse-prod:tool-renderers/query-card",
"rendererClaim": "tool:data_lab.query"
}
],
"details": {
"rendererClaim": "tool:data_lab.query",
"owners": [
{
"ownerKind": "module",
"ownerId": "data-lab-prod",
"canonicalKey": "data-lab-prod:tool-renderers/query-card"
},
{
"ownerKind": "module",
"ownerId": "warehouse-prod",
"canonicalKey": "warehouse-prod:tool-renderers/query-card"
}
]
},
"decisionIds": ["WCP-ADR-003", "WCP-ADR-015"],
"docsAnchor": "diagnostic-code-registry",
"message": "Renderer claim 'tool:data_lab.query' is claimed by multiple active contributions."
}

Version Fields

The v0 platform uses explicit schema version fields instead of inferred package versions.

Required fields:

  • compositionSchemaVersion: version of WorkspaceComposition structure
  • moduleApiVersion: version of module declaration and contract compatibility
  • renderHandleVersion: version of opaque render handle grammar and semantics
  • diagnosticSchemaVersion: version of diagnostic object schema

Initial v0 value:

0.1

Rules:

  • version fields are strings
  • compatibility is decided by an explicit supported-version set, not npm semver inference
  • unsupported versions produce WCP-VERSION-* diagnostics
  • package semver does not replace schema version checks
  • schema versions do not authorize runtime or permission decisions
  • diagnosticSchemaVersion is emitted on diagnostics and validated by host helpers or persisted diagnostic readers

Ownership notes:

  • policySchemaVersion semantics belong to WCP-005 and WCP-010; its diagnostic code is registered here so every diagnostic code remains centrally owned
  • render runtime package version policy belongs to WCP-006 and release governance
  • full semver automation belongs to release work, not WCP-003

Golden Fixture Matrix

This matrix defines the cross-platform fixture inventory and expected diagnostic codes. It does not duplicate full expected JSON objects.

Package-specific specs may add fixture IDs for their own behavior, but they must not remove, rename, or redefine the fixture IDs in this table.

Fixture IDIntentExpected Diagnostic Codes
fixture-happy-single-moduleone valid module instancenone
fixture-happy-multi-instancesame package enabled twice with distinct instancesnone
fixture-same-local-id-across-instancessame local ID in different instances is validnone
fixture-invalid-input-shapemalformed top-level input, non-array contribution collection, missing required descriptor field, missing runtime, or invalid runtime statusWCP-STRUCT-001
fixture-duplicate-instance-idduplicate module instance IDWCP-NS-001
fixture-invalid-instance-idinvalid module instance IDWCP-NS-002
fixture-duplicate-canonical-keysame owner, kind, and local ID twiceWCP-NS-003
fixture-invalid-local-idinvalid local contribution IDWCP-NS-004
fixture-duplicate-route-pathtwo owners claim same effective route pathWCP-ROUTE-001
fixture-invalid-route-pathinvalid route path grammarWCP-ROUTE-002
fixture-route-path-trailing-slash-rejectednon-root trailing slash is rejected instead of normalizedWCP-ROUTE-002
fixture-route-path-aliasexplicit path alias resolves conflictWCP-ROUTE-003
fixture-route-path-alias-creates-conflictexplicit path alias creates a new effective path conflictWCP-ROUTE-001
fixture-duplicate-message-renderer-claimtwo owners claim same custom message typeWCP-RENDERER-001
fixture-duplicate-tool-renderer-claimtwo owners claim same tool nameWCP-RENDERER-001
fixture-duplicate-activity-renderer-claimtwo owners claim same activity kindWCP-RENDERER-001
fixture-message-appenders-do-not-conflictmultiple appenders target same message and positionnone
fixture-invalid-renderer-claiminvalid renderer claim grammarWCP-RENDERER-002
fixture-default-text-renderer-rejecteddefault text renderer override attemptWCP-RENDERER-003
fixture-renderer-overrideexplicit renderer override resolves conflictWCP-RENDERER-004
fixture-unsupported-composition-schema-versionunsupported composition schema versionWCP-VERSION-001
fixture-unsupported-module-api-versionunsupported module API versionWCP-VERSION-002
fixture-unsupported-render-handle-versionunsupported render handle versionWCP-VERSION-003
fixture-unsupported-diagnostic-schema-versionunsupported diagnostic schema versionWCP-VERSION-004
fixture-unsupported-policy-schema-versionunsupported composition policy schema versionWCP-VERSION-005
fixture-invalid-policy-targetpolicy points to missing or invalid targetWCP-POLICY-001
fixture-policy-conflictpolicy contains ambiguous duplicate or conflicting operationsWCP-POLICY-001
fixture-policy-reorder-cyclepolicy reorder constraints contain a cycleWCP-POLICY-001
fixture-render-runtime-missing-handlerender runtime lacks required handleWCP-HANDLE-001
fixture-render-runtime-duplicate-providerrender runtime receives duplicate providers for one owner plus handleWCP-HANDLE-002
fixture-render-runtime-blocked-handlerender runtime admission policy blocks provider executionWCP-HANDLE-003
fixture-render-runtime-unsupported-providerrender runtime rejects unsupported runtime or handle versionWCP-HANDLE-004
fixture-render-runtime-load-failedrender runtime lazy provider load failsWCP-HANDLE-005
fixture-render-runtime-render-failedrender runtime component execution fails within one surfaceWCP-HANDLE-006
fixture-render-runtime-unknown-target-fallbackrender runtime receives an unknown target shapeWCP-HANDLE-007
fixture-runtime-readyready module contributes normallynone
fixture-runtime-read-onlyread-only module contributes active entries with read-only runtime metadatanone
fixture-runtime-needs-configurationneeds-configuration module contributes configuration entry and fallbacknone
fixture-runtime-unauthorizedunauthorized module contributes fallback entry without default route or renderer UInone
fixture-runtime-disableddisabled module omits non-fallback contributions and contributes matching fallback if declarednone
fixture-runtime-errorerrored module contributes default integration surfaces and matching fallback if declarednone

Verification Rules

Now:

  • docs verifier checks this spec exists
  • docs verifier checks this spec is linked from the root docs indexes
  • docs verifier checks required version fields are named
  • docs verifier checks diagnostic registry codes are unique
  • docs verifier checks diagnostic codes do not appear in other architecture docs

Later:

  • WCP-009 implements namespace and conflict diagnostics
  • WCP-010 implements explicit policy validation/application diagnostics
  • WCP-011 implements composeWorkspace() and golden fixture tests
  • WCP-015 and WCP-016 implement render runtime handle diagnostics
  • release gates include public API snapshots for exported diagnostic and version types

Duplicate Truth Rule

This document is the only prose source for namespace, diagnostic code, and schema version semantics.

Other docs may say "structured diagnostics", "canonical namespace", or "golden fixture matrix", but they must not copy the diagnostic registry or redefine version field semantics.