WDP Part 12: Component, Primary, and Sequence Metadata

Metadata schemas for developer documentation and organizational context

Abstract

This document defines metadata schemas for Components, Primaries, and Sequences in the Waddling Diagnostic Protocol (WDP). Metadata enriches the basic error code structure (Parts 1-4) with organizational context, documentation, ownership information, and role-based visibility. While optional, metadata is essential for developer documentation, code navigation, and maintaining large-scale diagnostic systems.

Key Concepts

  • Component metadata: Information about system modules and their organization
  • Primary metadata: Details about failure domains within components
  • Sequence metadata: Documentation for specific error instances
  • Role-based visibility: Public, developer, and internal information levels
  • Separation of concerns: Metadata lives separately from runtime catalogs

Note: This is an INFORMATIVE (Non-Normative) specification.

1. Introduction

1.1 What is Metadata?

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

Metadata provides context about each level:

E.Auth.Token.001
  │   │    │   │
  │   │    │   └── Sequence metadata: "What does 001 mean?"
  │   │    └────── Primary metadata: "What is Token domain?"
  │   └─────────── Component metadata: "What is Auth component?"
  └─────────────── Severity: Defined in Part 1

Metadata is NOT runtime data. It's documentation and organizational information used for:

  • Developer reference
  • Code navigation
  • Documentation generation
  • Team ownership
  • Architectural understanding

1.2 Metadata vs Catalog

AspectCatalog (Part 9a)Metadata (Part 12)
PurposeRuntime expansionDevelopment documentation
AudienceApplications, clientsDevelopers, tools
ContentError messages, hintsComponents, ownership, organization
DistributionCDN, cached by clientsInternal docs, git repo
SizeSmall, optimizedLarger, descriptive
SecurityCan be publicContains sensitive data
Catalog (runtime)
{
  "xY9Kp": {
    "code": "E.Auth.Token.001",
    "message": "Token expired at {{timestamp}}"
  }
}
Metadata (documentation)
{
  "components": {
    "Auth": {
      "description": "JWT-based authentication system",
      "owner": "security-team",
      "primaries": {
        "Token": {
          "description": "Token lifecycle management",
          "sequences": {
            "1": {
              "name": "TOKEN_EXPIRED",
              "description": "JWT token exceeded TTL"
            }
          }
        }
      }
    }
  }
}

1.3 When to Use Metadata

You SHOULD define metadata if:

  • Large team (multiple developers/teams)
  • Complex codebase (many components)
  • Need documentation generation
  • Want code navigation (IDE integration)
  • Multiple services/microservices
  • Need ownership tracking

You MAY skip metadata if:

  • Small project (1-2 developers)
  • Simple error structure (< 50 errors)
  • No documentation needs
  • Rapid prototyping/MVP

2. Why Metadata?

2.1 Developer Documentation

Problem: Understanding what E.Auth.Token.001 means

Without metadata
E.Auth.Token.001 - Token expired
- What is Auth?
- What is Token domain?
- Why 001?
- Who maintains this?
- Where's the code?
With metadata
# Component: Auth
**Description:** JWT-based authentication with RS256
**Owner:** security-team@company.com
**Location:** src/auth/

## Primary: Token
**Description:** Token lifecycle management (issue, validate, refresh)
**Related:** Session, Permission

### Sequence 001: TOKEN_EXPIRED
**Description:** JWT token exceeded its time-to-live (TTL)
**Introduced:** v1.0.0
**Hints:**
- Use /auth/refresh endpoint to get new token
- Tokens expire after 1 hour by default

2.2 Code Navigation

Use case: Developer wants to find where Auth.Token errors are defined

Json
{
  "components": {
    "Auth": {
      "locations": [
        {
          "file": "src/auth/mod.rs",
          "role": "internal"
        },
        {
          "file": "src/middleware/auth.rs",
          "role": "internal"
        }
      ]
    }
  }
}

IDE integration: "Jump to definition" takes you to the right file

2.3 Ownership Tracking

Use case: Error occurred, who should fix it?

Json
{
  "components": {
    "Auth": {
      "owner": "security-team",
      "maintainers": ["alice@company.com", "bob@company.com"],
      "slack": "#security-team",
      "oncall": "https://pagerduty.com/security-team"
    }
  }
}

2.4 Documentation Generation

Use case: Generate developer documentation automatically

Bash
$ wdp-doc-gen --metadata component-metadata.json --output docs/

Generated:
  docs/components/Auth.md
  docs/components/Database.md
  docs/primaries/Auth/Token.md
  docs/sequences/Auth/Token/001-TOKEN_EXPIRED.md

3. Component Metadata

3.1 Component Metadata Schema

Typescript
interface ComponentMetadata {
  // Identity (REQUIRED)
  name: string;  // "Auth", "Database", "Payment", etc.
  
  // Description (OPTIONAL)
  description?: string | MultiLevelDescription;
  
  // Ownership (OPTIONAL)
  owner?: string;              // Team or person
  maintainers?: string[];      // List of maintainers
  contact?: {
    email?: string;
    slack?: string;
    oncall?: string;
  };
  
  // Organization (OPTIONAL)
  primaries?: Record<string, PrimaryMetadata>;
  related_components?: string[];  // Components this depends on
  tags?: string[];                // Categorization tags
  
  // Status (OPTIONAL)
  status?: "draft" | "stable" | "deprecated";
  version?: string;
  introduced?: string;  // Version when introduced
  deprecated?: string;  // Version when deprecated
  
  // Code Locations (OPTIONAL - Internal Only!)
  locations?: Array<{
    file: string;          // File path
    module_path?: string;  // Module path
    role: "internal";      // Always internal!
  }>;
  
  // Documentation (OPTIONAL)
  docs_url?: string;      // Link to detailed docs
  examples?: string[];    // Example usage
}

interface MultiLevelDescription {
  public?: string;      // User-facing description
  developer?: string;   // Developer documentation
  internal?: string;    // Internal notes
}

3.2 Component Metadata Fields

FieldTypeRequiredDescription
namestringYesComponent name as it appears in error codes
descriptionstring | objectNoHuman-readable description (can be multi-level)
ownerstringNoTeam or person responsible
maintainersstring[]NoList of individual maintainers
contactobjectNoContact information (email, slack, oncall)
locationsarrayNoCode locations (INTERNAL only)
primariesobjectNoNested primary metadata
statusstringNodraft | stable | deprecated

name (REQUIRED)

The component name as it appears in error codes.

Json
{
  "name": "Auth"  // Must match: E.Auth.Token.001
}

Rules:

  • MUST match the Component field in error codes (case-sensitive)
  • SHOULD be PascalCase
  • MUST be unique within the system

description (OPTIONAL)

Human-readable description of what the component does.

Simple string
{
  "description": "JWT-based authentication and authorization system"
}
Multi-level (role-based)
{
  "description": {
    "public": "User authentication system",
    "developer": "JWT-based authentication with RS256 signing and 1-hour token TTL",
    "internal": "Auth service deployed to k8s cluster auth-prod, uses PostgreSQL auth_db"
  }
}

locations (OPTIONAL - Internal Only!)

IMPORTANT: File paths are INTERNAL information and should NEVER be exposed in public documentation.

Json
{
  "locations": [
    {
      "file": "src/auth/mod.rs",
      "module_path": "myapp::auth",
      "role": "internal"
    }
  ]
}

3.3 Component Metadata Example

Json
{
  "components": {
    "Auth": {
      "name": "Auth",
      "description": {
        "public": "User authentication system",
        "developer": "JWT-based authentication with RS256, 1-hour token TTL",
        "internal": "Deployed to k8s auth-prod, PostgreSQL auth_db, Redis cache"
      },
      "owner": "security-team",
      "maintainers": ["alice@company.com", "bob@company.com"],
      "contact": {
        "email": "security-team@company.com",
        "slack": "#security-team",
        "oncall": "https://pagerduty.com/security-oncall"
      },
      "locations": [
        {
          "file": "src/auth/mod.rs",
          "module_path": "myapp::auth",
          "role": "internal"
        }
      ],
      "primaries": {
        "Token": { /* ... */ },
        "Session": { /* ... */ }
      },
      "related_components": ["User", "Database"],
      "tags": ["authentication", "security", "jwt"],
      "status": "stable",
      "version": "1.2.0",
      "introduced": "1.0.0",
      "error_count": 15,
      "docs_url": "https://docs.company.com/auth"
    }
  }
}

4. Primary Metadata

4.1 Primary Metadata Schema

Typescript
interface PrimaryMetadata {
  // Identity (REQUIRED)
  name: string;  // "Token", "Session", "Permission", etc.
  
  // Description (OPTIONAL)
  description?: string | MultiLevelDescription;
  
  // Organization (OPTIONAL)
  sequences?: Record<number, SequenceMetadata>;
  related_primaries?: string[];  // Other primaries in same component
  
  // Documentation (OPTIONAL)
  docs_url?: string;
  examples?: string[];
  
  // Statistics (OPTIONAL)
  error_count?: number;
  errors?: string[];  // List of full error codes
}

4.2 Primary Metadata Fields

name (REQUIRED)

The primary name as it appears in error codes.

Json
{
  "name": "Token"  // Must match: E.Auth.Token.001
}

sequences (OPTIONAL)

Metadata for specific sequences within this primary.

Json
{
  "sequences": {
    "1": {
      "name": "TOKEN_EXPIRED",
      "description": "JWT token exceeded TTL"
    },
    "2": {
      "name": "TOKEN_INVALID",
      "description": "Token signature verification failed"
    }
  }
}

4.3 Primary Metadata Example

Json
{
  "primaries": {
    "Token": {
      "name": "Token",
      "description": "JWT token lifecycle management (issue, validate, refresh, revoke)",
      "sequences": {
        "1": { /* SequenceMetadata */ },
        "2": { /* SequenceMetadata */ }
      },
      "related_primaries": ["Session"],
      "error_count": 8,
      "errors": [
        "E.Auth.Token.001",
        "E.Auth.Token.002",
        "W.Auth.Token.005"
      ],
      "docs_url": "https://docs.company.com/auth/tokens"
    }
  }
}

5. Sequence Metadata

5.1 Sequence Metadata Schema

Typescript
interface SequenceMetadata {
  // Identity (REQUIRED for numeric sequences)
  number?: number;  // 1, 2, 3, etc.
  
  // Named Sequence (OPTIONAL)
  name?: string;  // "TOKEN_EXPIRED", "INVALID_INPUT", etc.
  
  // Description (OPTIONAL)
  description?: string | MultiLevelDescription;
  
  // Hints (OPTIONAL - Role-based)
  hints?: Array<{
    text: string;
    role: "public" | "developer" | "internal";
  }>;
  
  // Lifecycle (OPTIONAL)
  introduced?: string;   // Version when introduced
  deprecated?: string;   // Version when deprecated
  replacement?: string;  // Replacement error code if deprecated
  
  // Relationships (OPTIONAL)
  related_codes?: string[];  // Related error codes
  
  // Documentation (OPTIONAL)
  docs_url?: string;
  examples?: string[];
}

5.2 Sequence Metadata Fields

name (OPTIONAL)

Named sequence for better readability.

Json
{
  "number": 1,
  "name": "TOKEN_EXPIRED"
}

Note: Numeric sequences (001, 002) are canonical. Names are aliases for documentation.

hints (OPTIONAL - Role-based)

Actionable suggestions for resolving the error.

Json
{
  "hints": [
    {
      "text": "Refresh your session by logging in again",
      "role": "public"
    },
    {
      "text": "Use the /auth/refresh endpoint with your refresh token",
      "role": "developer"
    },
    {
      "text": "Check token TTL in config: auth.token_ttl_seconds",
      "role": "internal"
    }
  ]
}

Lifecycle Fields

Json
{
  "introduced": "1.0.0",
  "deprecated": "2.0.0",
  "replacement": "E.Auth.Session.001"
}

5.3 Sequence Metadata Example

Json
{
  "sequences": {
    "1": {
      "number": 1,
      "name": "TOKEN_EXPIRED",
      "description": {
        "public": "Your authentication token has expired",
        "developer": "JWT token exceeded TTL (default: 1 hour)",
        "internal": "Token exp claim < current timestamp in validator.rs:42"
      },
      "hints": [
        {
          "text": "Please log in again to continue",
          "role": "public"
        },
        {
          "text": "Use POST /auth/refresh with refresh_token to get new access token",
          "role": "developer"
        },
        {
          "text": "Token TTL configured in config/auth.yaml: token_ttl_seconds",
          "role": "internal"
        }
      ],
      "introduced": "1.0.0",
      "related_codes": ["E.Auth.Token.002", "W.Auth.Token.005"],
      "docs_url": "https://docs.company.com/auth/tokens#expiration"
    }
  }
}

6. Metadata File Format

6.1 File Structure

Metadata is stored in JSON files separate from runtime catalogs.

Recommended structure
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

6.2 Complete Metadata File

Json
{
  "wdp_version": "1.0.0",
  "project": "myapp",
  "version": "1.2.0",
  "generated": "2024-01-16T10:00:00Z",
  
  "components": {
    "ComponentName": {
      "name": "ComponentName",
      "description": "...",
      "owner": "...",
      "primaries": {
        "PrimaryName": {
          "name": "PrimaryName",
          "description": "...",
          "sequences": {
            "1": {
              "number": 1,
              "name": "SEQUENCE_NAME",
              "description": "..."
            }
          }
        }
      }
    }
  }
}

6.3 Separate vs Embedded

Option A: Separate files (RECOMMENDED)

component-metadata.json  # All metadata
catalog.json             # Runtime catalog only

Pros:

  • 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 */ }
  }
}

Pros: Single file, easier distribution

Cons: Larger file, harder to filter sensitive data

Recommendation: Use separate files.

7. Role-Based Visibility

7.1 Three Visibility Levels

Metadata can be filtered based on audience:

LevelAudienceCan See
publicEnd users, external docsGeneric descriptions, public hints
developerInternal developers, API docsTechnical details, implementation hints
internalOps team, security teamFile paths, infrastructure details, internal notes

7.2 Filtering Rules

Hierarchy: internal > developer > public

  • Internal role can see: internal + developer + public
  • Developer role can see: developer + public
  • Public role can see: public only

7.3 What to Hide from Public

CategoryExamplesVisibility
File pathslocations, module pathsMUST hide from public
InfrastructureInternal URLs, deployment detailsMUST hide from public
Contact infoOwner emails, oncall linksMUST hide from public
Team namesOwner team namesMAY hide from public
Component namesAuth, Database, etc.Safe for public
Generic descriptionsUser authentication systemSafe for public
Statusstable, deprecatedSafe for public

7.4 Filtering Implementation

Typescript
function filterMetadataForRole(
  metadata: ComponentMetadata,
  role: "public" | "developer" | "internal"
): ComponentMetadata {
  const filtered = { ...metadata };
  
  // Select appropriate description
  if (typeof filtered.description === 'object') {
    if (role === "public") {
      filtered.description = filtered.description.public || null;
    } else if (role === "developer") {
      filtered.description = filtered.description.developer 
        || filtered.description.public 
        || null;
    } else {
      filtered.description = filtered.description.internal 
        || filtered.description.developer 
        || filtered.description.public 
        || null;
    }
  }
  
  // Hide locations for non-internal
  if (role !== "internal") {
    delete filtered.locations;
    delete filtered.contact?.oncall;
  }
  
  // Filter hints by role
  if (filtered.primaries) {
    for (const primary of Object.values(filtered.primaries)) {
      if (primary.sequences) {
        for (const seq of Object.values(primary.sequences)) {
          if (seq.hints) {
            seq.hints = seq.hints.filter(hint => {
              const levels = { public: 0, developer: 1, internal: 2 };
              return levels[hint.role] <= levels[role];
            });
          }
        }
      }
    }
  }
  
  return filtered;
}

7.5 Filtered Output Examples

Internal metadata
{
  "Auth": {
    "description": "Auth service at k8s auth-prod, PostgreSQL auth_db",
    "owner": "security-team",
    "contact": {
      "email": "security@company.com",
      "oncall": "https://pagerduty.com/security"
    },
    "locations": [
      {"file": "src/auth/mod.rs", "role": "internal"}
    ]
  }
}
Developer metadata (filtered)
{
  "Auth": {
    "description": "JWT-based authentication with RS256",
    "owner": "security-team",
    "contact": {
      "email": "security@company.com"
    }
  }
}
Public metadata (filtered)
{
  "Auth": {
    "description": "User authentication system"
  }
}

8. Usage Patterns

8.1 Developer Documentation

Generate Markdown docs from metadata:

Bash
$ wdp-doc-gen \
    --metadata component-metadata.json \
    --catalog catalog.json \
    --output docs/ \
    --role developer
Output
# Auth Component

**Owner:** security-team  
**Status:** Stable  
**Version:** 1.2.0

JWT-based authentication with RS256, 1-hour token TTL.

## Primaries

### Token
Token lifecycle management (issue, validate, refresh).

#### Errors
- `E.Auth.Token.001` [xY9Kp] - TOKEN_EXPIRED
- `E.Auth.Token.002` [mN3Yr] - TOKEN_INVALID

8.2 IDE Integration

Typescript
// Developer types: E.Auth.Token.001
// IDE shows tooltip:
//   Component: Auth (JWT-based authentication)
//   Primary: Token (Token lifecycle)
//   Sequence: 001 - TOKEN_EXPIRED
//   Location: src/auth/token.rs:42

// "Go to definition" → Opens src/auth/token.rs

8.3 Error Search

Bash
$ wdp-search --component Auth
Found 15 errors in Auth component:
  E.Auth.Token.001 - TOKEN_EXPIRED
  E.Auth.Token.002 - TOKEN_INVALID
  E.Auth.Session.001 - SESSION_EXPIRED
  ...

8.4 Ownership Lookup

Bash
$ wdp-owner E.Auth.Token.001
Component: Auth
Owner: security-team
Contact: security-team@company.com
Slack: #security-team

9. Integration with Catalogs

9.1 Relationship

Metadata (build time) → Documentation generation
                       Developer reference
                     
Catalog (runtime) → Client expansion
                    User-facing errors

9.2 Merging for Tools

Tools may merge both for rich UI:

Typescript
interface EnrichedError {
  // From catalog
  code: string;
  compact_id: string;
  message: string;
  severity: string;
  
  // From metadata
  component_description: string;
  component_owner: string;
  primary_description: string;
  sequence_name: string;
  hints: string[];
}

9.3 Separate Distribution

Public distribution
https://cdn.example.com/wdp/
  catalog-v1.0.0.json              # Runtime catalog (public)
  catalog-v1.0.0-en.json           # Localized (public)
  component-metadata-v1.0.0-public.json  # Filtered metadata (public)
Internal distribution
https://internal.example.com/wdp/
  component-metadata-v1.0.0-internal.json  # Full metadata (internal)
  component-metadata-v1.0.0-dev.json       # Developer metadata

10. Implementation Guidelines

10.1 When to Generate Metadata

Bash
# During build
$ cargo build
  → Generates catalog.json
  → Generates component-metadata.json

# Or explicitly
$ wdp-gen metadata --output metadata/component-metadata.json

10.2 Metadata Collection

From code annotations:

Rust
#[in_component(Auth, role = internal)]
mod token {
    /// Component: Auth
    /// Primary: Token
    /// Description: JWT token validation and lifecycle
    #[error("E.Auth.Token.001", "TOKEN_EXPIRED")]
    pub struct TokenExpired;
}
Collected into
{
  "components": {
    "Auth": {
      "locations": [{"file": "src/token.rs", "role": "internal"}],
      "primaries": {
        "Token": {
          "description": "JWT token validation and lifecycle",
          "sequences": {
            "1": {"name": "TOKEN_EXPIRED"}
          }
        }
      }
    }
  }
}

10.3 Versioning

component-metadata-v1.0.0.json
component-metadata-v1.1.0.json
component-metadata-v2.0.0.json
Include version in file
{
  "wdp_version": "1.0.0",
  "project_version": "1.2.0",
  "generated": "2024-01-16T10:00:00Z"
}

10.4 Best Practices

Recommended practices:

  • Generate metadata automatically from code
  • Version metadata files
  • Filter sensitive data for public distribution
  • Keep metadata separate from catalog
  • Validate metadata structure
  • Document ownership and contacts

Practices to avoid:

  • Include file paths in public metadata
  • Hardcode metadata (generate from code)
  • Mix runtime catalog with documentation metadata
  • Expose internal infrastructure details publicly
  • Let metadata drift from actual code

11. Complete Examples

11.1 Full Component Metadata

Json
{
  "wdp_version": "1.0.0",
  "project": "myapp",
  "version": "1.2.0",
  "generated": "2024-01-16T10:00:00Z",
  "role_filter": "internal",
  
  "components": {
    "Auth": {
      "name": "Auth",
      "description": {
        "public": "User authentication system",
        "developer": "JWT-based authentication with RS256, 1-hour access tokens",
        "internal": "Deployed to k8s cluster auth-prod (3 replicas)"
      },
      "owner": "security-team",
      "maintainers": ["alice@company.com", "bob@company.com"],
      "contact": {
        "email": "security-team@company.com",
        "slack": "#security-team",
        "oncall": "https://pagerduty.com/security-oncall"
      },
      "locations": [
        {
          "file": "src/auth/mod.rs",
          "module_path": "myapp::auth",
          "role": "internal"
        }
      ],
      "primaries": {
        "Token": {
          "name": "Token",
          "description": "JWT token lifecycle management",
          "sequences": {
            "1": {
              "number": 1,
              "name": "TOKEN_EXPIRED",
              "description": {
                "public": "Your session has expired",
                "developer": "JWT access token exceeded 1-hour TTL",
                "internal": "Token exp claim validation at src/auth/token.rs:42"
              },
              "hints": [
                {"text": "Please log in again", "role": "public"},
                {"text": "Use POST /auth/refresh", "role": "developer"},
                {"text": "Check config: token_ttl_seconds", "role": "internal"}
              ],
              "introduced": "1.0.0",
              "related_codes": ["E.Auth.Token.002"]
            }
          }
        }
      },
      "status": "stable",
      "error_count": 15,
      "docs_url": "https://docs.company.com/components/auth"
    }
  }
}

11.2 Filtered Public Metadata

Json
{
  "wdp_version": "1.0.0",
  "project": "myapp",
  "version": "1.2.0",
  "role_filter": "public",
  
  "components": {
    "Auth": {
      "name": "Auth",
      "description": "User authentication system",
      "status": "stable",
      "primaries": {
        "Token": {
          "name": "Token",
          "description": "JWT token lifecycle management",
          "sequences": {
            "1": {
              "number": 1,
              "name": "TOKEN_EXPIRED",
              "description": "Your session has expired",
              "hints": [
                {"text": "Please log in again", "role": "public"}
              ],
              "docs_url": "https://docs.company.com/auth/tokens#expiration"
            }
          }
        }
      },
      "docs_url": "https://docs.company.com/components/auth"
    }
  }
}

11.3 Integration with Catalog

Component metadata
{
  "components": {
    "Auth": {
      "primaries": {
        "Token": {
          "sequences": {
            "1": {
              "name": "TOKEN_EXPIRED",
              "description": "JWT token exceeded TTL"
            }
          }
        }
      }
    }
  }
}
Runtime catalog
{
  "version": "1.0.0",
  "diags": {
    "xY9Kp": {
      "code": "E.Auth.Token.001",
      "severity": "E",
      "message": "Token expired at {{timestamp}}",
      "fields": ["timestamp"]
    }
  }
}
Merged view (for tools)
{
  "code": "E.Auth.Token.001",
  "compact_id": "xY9Kp",
  "severity": "E",
  "message": "Token expired at {{timestamp}}",
  "component": "Auth",
  "component_description": "User authentication system",
  "primary": "Token",
  "primary_description": "JWT token lifecycle management",
  "sequence": 1,
  "sequence_name": "TOKEN_EXPIRED",
  "sequence_description": "JWT token exceeded TTL"
}

End of Part 12: Component, Primary, and Sequence Metadata

Copyright © 2025 Ashutosh Mahala. This specification is licensed under CC BY 4.0.

View on GitLab