DocumentWDP-12
Version0.1.0-draft
StatusDraft
CategoryInformative (Non-Normative)
Updated2025-12-25

WDP Part 12: Metadata

Metadata schemas for WDP namespaces: Components, Primaries, Sequences, and Errors.

Abstract#

This document defines metadata schemas for WDP namespaces. Metadata provides documentation and organizational context for Components, Primaries, Sequences, and Errors as independent, combinatorial axes. While optional, metadata is essential for developer documentation, code navigation, and maintaining large-scale diagnostic systems.

Key concepts:

  • Flat structure: Components, Primaries, and Sequences are defined independently (not nested)
  • Per-namespace: Each namespace has its own metadata file
  • Combinatorial: The three axes combine freely; metadata documents each axis separately
  • Errors: Specific error instances keyed by full WDP code
  • Audience: Generic marker for implementer-defined filtering

Note: This is Part 12 of the WDP specification.

Conformance#

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

1. Introduction#

1.1 What is Metadata?#

WDP error codes have a combinatorial structure: SEVERITY.COMPONENT.PRIMARY.SEQUENCE

Each axis is independent:

E.Auth.Token.018
            
             Sequence: 018 (STALE) - defined in sequences section
        Primary: Token - defined in primaries section
  Component: Auth - defined in components section
Severity: E (Error) - defined in Part 1

Metadata documents each axis separately. The same Sequence (018/STALE) can appear with any Component and Primary. The same Primary (Token) can appear in multiple Components.

1.2 Combinatorial Design#

WDP is combinatorial—Components, Primaries, and Sequences are independent axes that combine freely:

AxisScopeExample
ComponentSystem moduleAuth, Database, Cache
PrimaryFailure domainToken, Connection, Data
SequenceSpecific condition018 (STALE), 003 (INVALID)

This means:

  • E.Auth.Token.018 - Auth component, Token domain, STALE condition
  • E.Cache.Data.018 - Cache component, Data domain, STALE condition
  • W.Database.Connection.027 - Database component, Connection domain, UNAVAILABLE condition

Metadata reflects this by defining each axis at the same level, not nested.

1.3 Per-Namespace#

Each namespace has its own metadata file. There is no aggregation across namespaces:

project/
  metadata/
    webapp-backend.metadata.json    # Namespace: webapp-backend
    webapp-frontend.metadata.json   # Namespace: webapp-frontend
    shared-lib.metadata.json        # Namespace: shared-lib

1.4 Metadata versus Catalog#

Catalog (Part 9a)Metadata (Part 12)
Runtime expansionDevelopment documentation
Maps compact IDs to messagesDocuments components/primaries/sequences
Used by clients/appsUsed by developers/tools
Per-namespacePer-namespace
Small, optimizedRich, descriptive

1.5 When to Use Metadata#

Implementations SHOULD define metadata if:

  • Multiple developers or teams
  • Complex codebase with many components
  • Documentation generation needed
  • IDE integration desired
  • Ownership tracking required

Implementations MAY skip metadata for small projects or rapid prototyping.

2. Metadata Structure#

2.1 Overview#

Metadata has four main sections at the same level:

Json
{
  "_format_version": "1.0",
  "namespace": "webapp-backend",
  "namespace_hash": "x7Kp2",
  
  "components": { },
  "primaries": { },
  "sequences": { },
  "errors": { }
}

2.2 Why Flat Structure?#

Nested (wrong for WDP):

Json
{
  "components": {
    "Auth": {
      "primaries": {
        "Token": {
          "sequences": {
            "018": { }
          }
        }
      }
    }
  }
}

Problems:

  • Implies Token only exists in Auth
  • Implies 018 only exists in Auth.Token
  • Duplicates sequence definitions

Flat (correct for WDP):

Json
{
  "components": {
    "Auth": { },
    "Cache": { }
  },
  "primaries": {
    "Token": { },
    "Data": { }
  },
  "sequences": {
    "018": { "name": "STALE" },
    "003": { "name": "INVALID" }
  },
  "errors": {
    "E.Auth.Token.018": { },
    "E.Cache.Data.018": { }
  }
}

Benefits:

  • Sequences defined once, used anywhere
  • Primaries are reusable across components
  • Errors are specific instances combining all axes

3. Top-Level Fields#

3.1 Schema#

Typescript
interface MetadataFile {
  // Format (REQUIRED)
  _format_version: string;  // "1.0"
  
  // Namespace Identity (REQUIRED)
  namespace: string;       // "webapp-backend"
  namespace_hash: string;  // "x7Kp2" (5-char hash from Part 7)
  
  // Project Info (OPTIONAL)
  project?: string;        // "WebApp Backend"
  version?: string;        // "1.2.0"
  generated?: string;      // ISO 8601 timestamp
  
  // The Four Axes (all OPTIONAL)
  components?: Record<string, ComponentMetadata>;
  primaries?: Record<string, PrimaryMetadata>;
  sequences?: Record<string, SequenceMetadata>;
  errors?: Record<string, ErrorMetadata>;
  
  // Statistics (OPTIONAL)
  total_errors?: number;
}

3.2 Field Descriptions#

_format_version (REQUIRED)

Version of the metadata format.

Json
{ "_format_version": "1.0" }

namespace (REQUIRED)

The namespace identifier as defined in Part 7.

Json
{ "namespace": "webapp-backend" }

namespace_hash (REQUIRED)

The 5-character namespace hash as computed in Part 7.

Json
{ "namespace_hash": "x7Kp2" }

project (OPTIONAL)

Human-readable project name.

version (OPTIONAL)

Project or metadata version.

generated (OPTIONAL)

ISO 8601 timestamp when metadata was generated.

4. Components#

4.1 Schema#

Typescript
interface ComponentMetadata {
  // Identity (REQUIRED)
  name: string;
  
  // Description (OPTIONAL)
  description?: string | Record<string, string>;
  
  // Organization (OPTIONAL)
  tags?: string[];
  related_components?: string[];
  
  // Ownership (OPTIONAL)
  owner?: string;
  maintainers?: string[];
  contact?: {
    email?: string;
    slack?: string;
    oncall?: string;
  };
  
  // Code Locations (OPTIONAL)
  locations?: Location[];
  
  // Lifecycle (OPTIONAL)
  status?: "draft" | "stable" | "deprecated";
  introduced?: string;
  deprecated?: string;
  
  // Statistics (OPTIONAL)
  error_count?: number;
  errors?: string[];  // List of error codes in this component
  
  // Documentation (OPTIONAL)
  examples?: string[];
  docs_url?: string;
}

interface Location {
  file: string;
  module_path?: string;
  audience?: string | string[];
}

4.2 Example#

Json
{
  "components": {
    "Auth": {
      "name": "Auth",
      "description": {
        "user": "Authentication system",
        "developer": "JWT-based authentication with RS256 signing",
        "ops": "Deployed to k8s auth-prod, uses PostgreSQL and Redis"
      },
      "tags": ["security", "authentication", "jwt"],
      "owner": "security-team",
      "maintainers": ["alice@company.com", "bob@company.com"],
      "contact": {
        "email": "security-team@company.com",
        "slack": "#security-team"
      },
      "locations": [
        { "file": "src/auth/mod.rs", "audience": "engineering" }
      ],
      "status": "stable",
      "introduced": "1.0.0",
      "error_count": 6,
      "errors": [
        "E.Auth.Token.001",
        "E.Auth.Token.003",
        "E.Auth.Token.031",
        "E.Auth.Permission.008",
        "W.Auth.Permission.033"
      ],
      "docs_url": "https://docs.company.com/auth"
    },
    "Cache": {
      "name": "Cache",
      "description": "Redis caching layer",
      "tags": ["performance", "redis"],
      "owner": "backend-team",
      "error_count": 4,
      "errors": [
        "E.Cache.Connection.027",
        "W.Cache.Data.018",
        "I.Cache.Data.034",
        "S.Cache.Data.035"
      ]
    }
  }
}

4.3 Field Notes#

  • name: MUST match the key and the Component in error codes
  • description: MAY be string or audience-keyed object (see Section 8)
  • errors: Lists all error codes where this component appears
  • locations: File paths; use audience to control visibility

5. Primaries#

5.1 Schema#

Typescript
interface PrimaryMetadata {
  // Identity (REQUIRED)
  name: string;
  
  // Description (OPTIONAL)
  description?: string | Record<string, string>;
  
  // Organization (OPTIONAL)
  related?: string[];  // Related primaries
  
  // Statistics (OPTIONAL)
  error_count?: number;
  errors?: string[];  // List of error codes with this primary
  
  // Documentation (OPTIONAL)
  examples?: string[];
  docs_url?: string;
}

5.2 Example#

Json
{
  "primaries": {
    "Token": {
      "name": "Token",
      "description": "Authentication token errors. JWT parsing, validation, expiry, and signature verification.",
      "related": ["Permission", "Session"],
      "error_count": 4,
      "errors": [
        "E.Auth.Token.001",
        "E.Auth.Token.003",
        "E.Auth.Token.031",
        "E.Auth.Token.032"
      ],
      "examples": [
        "Missing Authorization header",
        "Invalid JWT signature",
        "Token expired"
      ]
    },
    "Connection": {
      "name": "Connection",
      "description": "Connection and network errors. TCP failures, DNS resolution, connection pooling.",
      "related": ["Timeout"],
      "error_count": 6,
      "errors": [
        "E.Cache.Connection.027",
        "E.Db.Connection.021",
        "E.Api.Connection.027",
        "E.Api.Connection.028",
        "E.Queue.Connection.021",
        "C.Db.Connection.026"
      ],
      "examples": [
        "Connection pool exhausted",
        "Connection refused",
        "DNS resolution failure"
      ]
    },
    "Data": {
      "name": "Data",
      "description": "Data integrity errors. Corruption detection, constraint violations, referential integrity.",
      "related": ["Validation"],
      "error_count": 11,
      "errors": [
        "C.Db.Data.025",
        "C.Storage.Data.025",
        "E.Db.Data.023",
        "E.Storage.Data.021",
        "E.Storage.Data.022",
        "W.Cache.Data.018",
        "I.Cache.Data.034",
        "S.Cache.Data.035",
        "K.Queue.Data.036",
        "K.Storage.Data.037",
        "T.Storage.Data.038"
      ]
    }
  }
}

5.3 Field Notes#

  • name: MUST match the key and the Primary in error codes
  • Primaries are reusable across components (Token appears in Auth, Session, etc.)
  • related: Other primaries that often co-occur or are related conceptually

6. Sequences#

6.1 Schema#

Sequences are defined per Part 6 (Sequence Conventions). Each sequence number has a semantic meaning that applies regardless of Component or Primary.

Typescript
interface SequenceMetadata {
  // Identity (REQUIRED)
  name: string;  // "STALE", "INVALID", "UNAVAILABLE"
  
  // Semantics (OPTIONAL)
  description?: string;
  typical_severity?: string;  // "Error", "Warning", "Critical"
  
  // Resolution (OPTIONAL)
  hints?: string[];
  
  // Statistics (OPTIONAL)
  error_count?: number;
  errors?: string[];  // All errors using this sequence
}

6.2 Example#

Json
{
  "sequences": {
    "001": {
      "name": "MISSING",
      "description": "Required parameter, field, or argument is absent",
      "typical_severity": "Error",
      "hints": [
        "Check if parameter was provided",
        "Verify required fields are set"
      ],
      "error_count": 1,
      "errors": ["E.Auth.Token.001"]
    },
    "003": {
      "name": "INVALID",
      "description": "Validation failed - data doesn't meet constraints",
      "typical_severity": "Error",
      "hints": [
        "Review validation rules",
        "Check input format"
      ],
      "error_count": 5,
      "errors": [
        "E.Auth.Token.003",
        "E.Db.Validation.003",
        "E.Navigation.Route.003",
        "W.Api.Validation.003",
        "W.Queue.Validation.003"
      ]
    },
    "018": {
      "name": "STALE",
      "description": "Data is outdated and needs refresh",
      "typical_severity": "Warning",
      "hints": [
        "Refresh from source",
        "Adjust TTL settings"
      ],
      "error_count": 1,
      "errors": ["W.Cache.Data.018"]
    },
    "021": {
      "name": "NOT_FOUND",
      "description": "Requested resource does not exist",
      "typical_severity": "Error",
      "hints": [
        "Verify resource identifier",
        "Check if resource was deleted"
      ],
      "error_count": 4,
      "errors": [
        "E.Db.Connection.021",
        "E.Storage.Data.021",
        "E.Navigation.Page.021",
        "E.Queue.Connection.021"
      ]
    },
    "027": {
      "name": "UNAVAILABLE",
      "description": "Service temporarily unavailable",
      "typical_severity": "Error",
      "hints": [
        "Retry after delay",
        "Check service status",
        "Enable fallback"
      ],
      "error_count": 2,
      "errors": [
        "E.Cache.Connection.027",
        "E.Api.Connection.027"
      ]
    }
  }
}

6.3 Field Notes#

  • Keys are zero-padded 3-digit strings ("001", "018", "027")
  • name: UPPER_SNAKE_CASE, matches Part 6 conventions
  • Sequences are global—defined once, used across all Component.Primary combinations
  • typical_severity: What severity this sequence usually has (actual may vary)

7. Errors#

7.1 Schema#

Errors are specific instances combining Severity, Component, Primary, and Sequence. Keyed by full WDP code.

Typescript
interface ErrorMetadata {
  // Identity (REQUIRED)
  code: string;  // "E.Auth.Token.018"
  
  // Parsed Components (OPTIONAL - can be derived)
  severity?: string;    // "E"
  component?: string;   // "Auth"
  primary?: string;     // "Token"
  sequence?: number;    // 18
  
  // Compact ID (OPTIONAL)
  hash?: string;  // "xY9Kp"
  
  // Content (OPTIONAL)
  message?: string;
  description?: string | Record<string, string>;
  hints?: Hint[];
  
  // Classification (OPTIONAL)
  tags?: string[];
  audience?: string | string[];  // Visibility marker
  
  // Relationships (OPTIONAL)
  related_codes?: string[];
  see_also?: string[];
  
  // Lifecycle (OPTIONAL)
  introduced?: string;
  deprecated?: string;
  
  // Code Context (OPTIONAL)
  code_snippets?: CodeSnippet[];
  locations?: Location[];
  
  // Documentation (OPTIONAL)
  docs_url?: string;
  fields?: string[];  // Template fields like ["timestamp", "user_id"]
}

interface Hint {
  text: string;
  audience?: string | string[];
}

interface CodeSnippet {
  language: string;
  code: string;
  label?: string;
  audience?: string | string[];
}

7.2 Example#

Json
{
  "errors": {
    "E.Auth.Token.001": {
      "code": "E.Auth.Token.001",
      "severity": "E",
      "component": "Auth",
      "primary": "Token",
      "sequence": 1,
      "hash": "V6a0B",
      "message": "JWT token missing from Authorization header",
      "description": {
        "user": "Authentication required",
        "developer": "The client did not provide a JWT token in the Authorization header"
      },
      "hints": [
        { "text": "Please log in to continue", "audience": "user" },
        { "text": "Include Authorization: Bearer <token> header", "audience": "developer" }
      ],
      "tags": ["authentication", "security"],
      "related_codes": ["E.Auth.Token.003", "E.Auth.Token.031"],
      "introduced": "1.0.0",
      "code_snippets": [
        {
          "language": "javascript",
          "label": "Correct usage",
          "code": "fetch('/api/data', {\n  headers: { 'Authorization': 'Bearer <token>' }\n})",
          "audience": "developer"
        }
      ]
    },
    "E.Auth.Token.003": {
      "code": "E.Auth.Token.003",
      "severity": "E",
      "component": "Auth",
      "primary": "Token",
      "sequence": 3,
      "hash": "AcAGP",
      "message": "JWT token signature validation failed",
      "description": "The JWT token signature could not be verified",
      "hints": [
        { "text": "Verify JWT_SECRET configuration" },
        { "text": "Check token hasn't been modified" }
      ],
      "tags": ["authentication", "security", "cryptography"],
      "related_codes": ["E.Auth.Token.001", "E.Auth.Token.031"]
    },
    "W.Cache.Data.018": {
      "code": "W.Cache.Data.018",
      "severity": "W",
      "component": "Cache",
      "primary": "Data",
      "sequence": 18,
      "hash": "0yRgf",
      "message": "Cache entry stale - refreshing from database",
      "description": "The cached entry has exceeded its TTL and is considered stale",
      "hints": [
        { "text": "Refresh from source" },
        { "text": "Adjust TTL settings" },
        { "text": "Consider implementing cache warming" }
      ],
      "tags": ["cache", "ttl", "refresh"]
    },
    "E.Cache.Connection.027": {
      "code": "E.Cache.Connection.027",
      "severity": "E",
      "component": "Cache",
      "primary": "Connection",
      "sequence": 27,
      "hash": "F3Z7a",
      "message": "Redis cache server unavailable",
      "description": {
        "user": "Service temporarily unavailable",
        "developer": "The Redis cache server is temporarily unavailable",
        "ops": "Check Redis server status, verify network connectivity"
      },
      "hints": [
        { "text": "Check Redis server status", "audience": "ops" },
        { "text": "Verify network connectivity", "audience": "ops" },
        { "text": "Review Redis logs for errors", "audience": "ops" }
      ],
      "tags": ["cache", "redis", "connectivity"]
    }
  }
}

7.3 Field Notes#

  • Keys are full WDP codes: "E.Auth.Token.018"
  • hash: Compact ID from Part 5
  • description: MAY be string or audience-keyed (see Section 8)
  • hints: Array with optional audience filtering
  • audience on error: Controls overall visibility of this error's details

8. Audience#

8.1 Overview#

WDP provides audience as a generic marker. WDP does not define:

  • What audience values mean
  • How filtering works
  • Access control policies
  • RBAC rules

Implementations define their own audience semantics.

8.2 Usage#

The audience field MAY appear on:

  • Descriptions (as object keys)
  • Hints
  • Code snippets
  • Locations
  • Entire errors
Json
{
  "description": {
    "user": "Your session expired",
    "developer": "JWT exceeded TTL",
    "ops": "Check auth-service metrics"
  }
}

8.3 Audience Values#

Implementations MAY define any audience identifiers:

SchemeValues
Rolesuser, developer, internal, ops, admin
Tierspublic, private, confidential
Teamsfrontend, backend, security

9. File Format#

9.1 File Structure#

Metadata is stored in JSON files separate from runtime catalogs.

project/
  catalogs/
    catalog.json           # Runtime catalog (Part 9a)
    catalog-en.json        # Localized catalog (Part 8)
  metadata/
    component-metadata.json    # Component/Primary/Sequence metadata
    component-metadata-public.json  # Filtered for public

9.2 Separate vs Embedded#

Option A: Separate files (RECOMMENDED)

component-metadata.json  # All metadata
catalog.json             # Runtime catalog only
  • Clear separation of concerns
  • Can filter metadata without touching catalog
  • Smaller catalog for runtime

Option B: Embedded in catalog

Json
{
  "version": "1.0.0",
  "diags": { /* catalog entries */ },
  "metadata": {
    "components": { /* component metadata */ }
  }
}
  • Single file, easier distribution
  • Larger file, harder to filter sensitive data

10. Integration with Catalogs#

10.1 Mapping#

Metadata files can be linked to catalogs via the namespace_hash or explicit configuration.

Tools typically read both files:

  1. Read catalog.json for runtime messages
  2. Read metadata.json for context and validation
  3. Merge data for documentation generation

11. Examples#

See Section 2.2, 4.2, 5.2, 6.2, and 7.2 for specific examples of each section.

A full example metadata file is available in Part 9c (Implementation Guide).

Appendix A: JSON Schema#

Download JSON Schema

Json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["_format_version", "namespace", "namespace_hash"],
  "properties": {
    "_format_version": { "type": "string" },
    "namespace": { "type": "string" },
    "namespace_hash": { "type": "string", "pattern": "^[0-9a-zA-Z]{5}$" },
    "components": { "type": "object" },
    "primaries": { "type": "object" },
    "sequences": { "type": "object" },
    "errors": { "type": "object" }
  }
}

Appendix B: Metadata versus Catalog#

FeatureCatalog (Runtime)Metadata (Dev)
Optimized forSpeed, SizeReadability, Completeness
Required?Yes (for clients)No (optional)
AudienceSoftwareHumans
FormatCompact JSONRich JSON
StructureFlat list of IDsStructured Graph