/agnosticv:validator

โœ“ Catalog Validation

Validate AgnosticV catalog configurations and best practices before creating pull request.


What Youโ€™ll Need Before Starting

validator workflow diagram

Click to view full workflow diagram

Prerequisites

๐Ÿ“

AgnosticV Repository

cd ~/work/code/agnosticv
๐Ÿ“„

Catalog Files Created

agd_v2/your-catalog-name/
โ”œโ”€โ”€ common.yaml
โ”œโ”€โ”€ dev.yaml
โ””โ”€โ”€ description.adoc
๐Ÿ”„

Repository Up to Date

git checkout main
git pull origin main

What Youโ€™ll Need


Quick Start

  1. Navigate to Repo

    AgnosticV repository

  2. Run Validator

    /agnosticv:validator

  3. Review Results

    Check validation report

  4. Fix Issues

    Address errors and warnings

  5. Create PR

    When validation is clean


What It Validates

โ„น๏ธ

Comprehensive Validation Checks

The validator performs extensive checks across your catalog configuration, including new checks aligned to the v2.6.0 catalog-builder standards:

Check 1: File Structure
  • Required files: common.yaml must exist
  • Recommended files: dev.yaml, description.adoc, info-message-template.adoc
  • File paths: Correct directory structure
  • Naming: Follows catalog naming convention
Check 2: UUID Compliance
  • Format: RFC 4122 compliant UUID
  • Case: Lowercase only (no uppercase)
  • Uniqueness: Not used by other catalogs
  • Structure: Proper hyphenation (8-4-4-4-12)
Check 3: Category Validation

Valid values (must be exactly one):

  • Workshops - Multi-user hands-on learning
  • Demos - Single-user presenter-led (MUST NOT be multi-user)
  • Labs - General learning environments
  • Sandboxes - Self-service playgrounds
  • Brand_Events - Events like Red Hat Summit, Red Hat One

Important Rules:

  • Case-sensitive: Must match exactly (plural)
  • Required: Cannot be empty
  • Demo rules:
    • Demos MUST be single-user (ERROR if multiuser: true)
    • Demos MUST NOT have workshopLabUiRedirect enabled (ERROR)
Checks 4-5: Workloads and YAML
  • Check 4: Workloads - Collection format, existence, dependencies, naming (full namespace.collection.role format required)
  • Check 5: YAML Syntax - Valid YAML, required fields, data types
Check 6: Infrastructure (UPDATED)

Check 6 detects config: type and routes to the appropriate check file. Four paths:

cloud-vms-base โ†’ cloud-vms-base-validator-checks.md:

  • Instances block defined with bastion VM and correct tags
  • Bastion image is supported RHEL version (9.4+)
  • CNV: services:/routes: present; AWS: security_groups: present
  • Multi-user isolation warning (no per-user namespace on VMs)

config: namespace (Sandbox API Tenant CI) โ†’ sandbox-validator-checks.md:

  • Check 6C: ERROR if __meta__.sandboxes missing, kind โ‰  OcpSandbox, cloud_selector.cloud not valid, or cloud_selector.lab missing
  • Check 6D: ERROR if sandbox_api.actions.destroy.catch_all not explicitly false
  • Check 6E: ERROR if namespaced_workloads collection missing, or tenant workloads (tenant_keycloak_user, tenant_namespace) absent
  • Check 6F: WARNING if remove_workloads missing or incomplete
  • Check 6G: WARNING if deployer.actions.status or update not disabled

config: openshift-workloads + cloud_provider: none + num_users: 0 (Sandbox API Cluster CI) โ†’ sandbox-validator-checks.md:

  • Check 6H: ERROR if #include /includes/sandbox-api.yaml or access-restriction-admins-only.yaml missing
  • Check 6I: WARNING if propagate_provision_data missing or incomplete (must pass api_url, token, sandbox vars to tenants)
  • Check 6J: WARNING if deployer.actions.status or update not disabled

config: openshift-workloads (standard OCP lab) โ†’ ocp-validator-checks.md:

  • Pool suffix: ERROR if pool does not end in /prod
  • OCP version: Must be 4.18, 4.20, or 4.21 (known pool versions)
  • AWS OCP: WARNING โ€” confirm RHDP team approval
  • SNO + multiuser: ERROR โ€” SNO cannot support concurrent users
Check 7: Authentication (UPDATED)
  • cloud-vms-base: Auth check skipped โ€” VM catalogs use OS-level auth, no OCP cluster. Warns if ocp4_workload_authentication accidentally added.
  • OCP: ERROR if deprecated ocp4_workload_authentication_htpasswd or ocp4_workload_authentication_keycloak roles found
  • OCP: ERROR if RHSSO detected (use Keycloak/RHBK instead)
  • OCP: PASS requires unified ocp4_workload_authentication with valid ocp4_workload_authentication_provider value (htpasswd or keycloak)
Check 8: Showroom (UPDATED)
  • OCP: Both ocp4_workload_ocp_console_embed AND ocp4_workload_showroom required together. ERROR if ocp_console_embed missing.
  • OCP: ocp4_workload_showroom_antora_enable_dev_mode: "false" in common.yaml; "true" in dev.yaml
  • cloud-vms-base: Uses vm_workload_showroom with showroom_git_repo and showroom_git_ref. ERROR if ocp_console_embed present (requires OCP cluster).
  • cloud-vms-base: No dev mode variable โ€” vm_workload_showroom does not have Antora dev mode.
Check 9: Best Practices
  • Naming conventions followed
  • Documentation completeness
  • dev.yaml has purpose: development
Check 10: Stage Files Validation
  • dev.yaml: Must have purpose: development
  • event.yaml: Should have purpose: events (if exists)
  • prod.yaml: Should have purpose: production (if exists)
  • scm_ref: Validates deployment repository references
Check 11: Multi-User Configuration (CRITICAL)
  • num_users parameter: Required for multi-user catalogs
  • worker_instance_count: Must scale with num_users
  • workshopLabUiRedirect:
    • WARNING if not enabled for multi-user workshops
    • Multi-user workshops SHOULD enable this for per-user lab UI routing
  • Category compliance: Workshops/Brand_Events must be multi-user
Check 12: Bastion Configuration
  • Image version: RHEL 9.4-10.0 recommended
  • Resources: Minimum 2 cores, 4Gi memory
  • Configuration: Proper bastion setup for CNV pools
Check 13: Collection Versions (UPDATED)
  • tag: defined: ERROR if tag: variable is not set in common.yaml
  • Standard collections: Should use โ€” WARNING if hardcoded version found on standard collections
  • Showroom collection: Must use a fixed version (not ) pinned to โ‰ฅ v1.6.6 โ€” ERROR if version is older or missing
  • Galaxy collections: Version validation
  • Format: Proper requirements_content structure
Check 14: Deployer Configuration
  • scm_url: Must point to agnosticd-v2 repository
  • scm_ref: Deployment reference (main, tag, branch)
  • execution_environment: Container image for deployment
Check 14a: Reporting Labels (CRITICAL - ERROR if missing)
โš ๏ธ

primaryBU: REQUIRED for business unit tracking

Examples: Hybrid_Platforms, Application_Services, Ansible, RHEL

Used for tracking and reporting across RHDP

ERROR severity if missing

Check 15: Component Propagation
  • Multi-stage catalogs: Validates data flow between stages
  • propagate_provision_data: Ensures proper variable passing
  • Component structure: Validates __meta__.components configuration
Check 15a: Anarchy Namespace
  • ERROR if anarchy.namespace is defined anywhere in the catalog item
  • The anarchy.namespace field is managed by the platform and must never be set by catalog items
Check 16: AsciiDoc Templates
  • description.adoc: Required catalog description
  • info-message-template.adoc: Required user notification template
  • Variable substitutions: Validates {variable} syntax usage
  • Content quality: Checks for proper structure
Check 16a: Event Catalog Validation
  • Category: Event catalogs must use Brand_Events category
  • Keywords: Event-specific keywords required (e.g. summit-2026)
  • Directory naming: Must follow summit-2026/lb####-short-name-cloud_provider convention. WARNING if directory doesn't start with the lab ID. WARNING if directory doesn't end with -aws (AWS pools) or -cnv (CNV/OpenStack pools)
  • Showroom naming: Showroom repo name must match lab ID pattern
  • Console embed: ocp_console_embed workload presence validated for OCP-based event labs
Check 17: LiteMaaS Validation
  • Triggered when ocp4_workload_litellm_virtual_keys workload is present, OR any litellm/litemaas variable is set, OR either include is already present
  • Models list (OCP only): ERROR if ocp4_workload_litellm_virtual_keys_models is empty
  • Duration (OCP only): WARNING if ocp4_workload_litellm_virtual_keys_duration is not set
  • Includes (OCP and cloud-vms-base): ERROR if #include /includes/secrets/litemaas-master_api.yaml is missing
  • Includes (OCP and cloud-vms-base): ERROR if #include /includes/parameters/litellm_metadata.yaml is missing
Check 17a: Event Restriction Include
  • Triggered when catalog is in an event directory (e.g. summit-2026/ or rh1-2026/)
  • WARNING if event restriction include is missing from common.yaml
  • Expected includes: summit-devs.yaml (for Summit) or rh1-2026-devs.yaml (for RH1)
  • These restrict catalog access to event participants until the event event.yaml file is created
Check 18: Duplicate Includes
  • ERROR if the same #include line appears in multiple files loaded together (account.yaml, common.yaml, dev.yaml)
  • Prevents "included more than once / include loop" errors at deploy time
  • Common case: event directory account.yaml already includes the restriction file, and common.yaml adds it again
Check 19: Credential Pattern (UPDATED v2.10.8)

Applies to all credential-like variables โ€” any key containing password, passwd, secret, token, access_key, api_key, or credential (excluding benign suffixes like _length, _policy, _type, _format, _expires).

  • Rule 1 โ€” No hash/GUID generation: ERROR if any credential variable uses hash(), sha, md5, or GUID-derived values
  • Rule 2 โ€” No plain static strings: ERROR if a credential is a hardcoded string โ€” must use lookup('password'), reference , or be empty ("" for workload auto-generation)
  • Rule 3 โ€” Unique lookup paths: ERROR if two credential variables use the same output_dir ~ path (generates identical values)
  • Rule 4 โ€” No clear text in dev.yaml / test.yaml: ERROR if plain-text credentials appear in dev.yaml or test.yaml โ€” these files are committed to git

Correct pattern: lookup('password', output_dir ~ '/common_password', length=12, chars=['ascii_letters', 'digits'])

Check 20: Showroom Namespace in Tenant Catalogs
  • Applies to Sandbox API Tenant CI catalogs only (config: namespace)
  • WARNING if ocp4_workload_showroom_namespace is set โ€” Showroom manages its own namespace
  • WARNING if a showroom suffix entry exists in ocp4_workload_tenant_namespace_namespaces
Check 21: EE Image Date
  • WARNING if execution_environment.image uses a chained-YYYY-MM-DD tag that is more than 90 days old
  • Recommended current image: quay.io/agnosticd/ee-multicloud:chained-2026-02-23
Check 22: requirements_content Position
  • WARNING if requirements_content: appears after line 200 in common.yaml
  • Collections must be visible near the top for fast troubleshooting โ€” reviewers look there first
  • Per Nate Stencell's review standard
Check 23: Untagged Images
  • Applies to prod and event stage catalogs only
  • ERROR if any container image reference uses :latest, :main, :master, or has no tag at all
  • Mutable tags cause non-reproducible deployments โ€” all images must be pinned
  • Per Nate Stencell's review standard
Check 24: Catalog Directory Name Length
  • ERROR if the catalog directory name exceeds 50 characters
  • Platform limit is 52 chars (babylon_checks.py); skill enforces 50 to catch violations before CI
  • Per JK's request
Check 25: E2E Runtime Automation

All checks in this group are WARNING severity โ€” E2E failures are student-retryable and do not block provisioning.

  • Missing runtime automation workload: WARNING if ocp4_workload_runtime_automation_k8s is absent from an OCP tenant or dedicated catalog item that is expected to run E2E tests
  • Missing zt-runner image: WARNING if the zt-runner container image reference is not present in the catalog when runtime automation is otherwise configured
โ„น๏ธ

E2E checks are all WARNING (not ERROR) because failures affect individual student sessions and can be retried โ€” they are not provisioning blockers.

Check 26: LiteLLM Virtual Keys Placement
  • Rule: ocp4_workload_litellm_k8s must NOT appear in a cluster CI catalog item
  • Cluster CI detection: __meta__.components includes sandbox_api, OR the catalog display name contains cluster
  • ERROR if ocp4_workload_litellm_k8s is found in a cluster CI โ€” same placement rule as Showroom (per-student workloads belong on the tenant/user deployer, not the shared cluster provisioner)
โš ๏ธ

LiteLLM virtual-key provisioning is per-student. It must live on the tenant/user deployer catalog item, not on the shared cluster CI. Placing it on the cluster CI results in a single shared key for all students.

Check 27: Showroom in Cluster CI
  • Rule: ocp4_workload_showroom must NOT appear in a cluster CI catalog item
  • Cluster CI detection: __meta__.components includes sandbox_api, OR the catalog display name contains cluster
  • ERROR if ocp4_workload_showroom is found in a cluster CI
โš ๏ธ

Showroom is per-student. It must only appear on the tenant/user deployer catalog item. Adding it to a cluster CI causes a single shared Showroom instance for all students instead of individual per-user lab UIs.

CNV Pool CI โ€” false-positive suppression
  • Catalogs with config: openshift-cluster + cloud_provider: openshift_cnv are pool CIs โ€” they provision shared OCP clusters for sandbox allocation, not user-facing labs
  • Check 7 (authentication workload) is skipped โ€” pool clusters handle auth at the sandbox level
  • Check 11 (worker scaling) is skipped โ€” worker_instance_count: 0 is correct for SNO/compact pools

Common Workflow

  1. Generate Catalog

    /agnosticv:catalog-builder
    โ†’ Create catalog files
  2. Validate Configuration

    /agnosticv:validator
    โ†’ Check for issues
    โ†’ Get validation report
  3. Fix Issues

    Fix reported issues in:

    • common.yaml
    • dev.yaml
    • description.adoc
  4. Re-validate

    /agnosticv:validator
    โ†’ Confirm all issues resolved
  5. Create Pull Request

    git checkout -b add-your-catalog
    git add agd_v2/your-catalog-name/
    git commit -m "Add your-catalog catalog"
    git push origin add-your-catalog
    gh pr create --fill

Example Validation Report

Sample Validation Output

โœ…
UUID: Valid and unique (a1b2c3d4-e5f6-7890-abcd-ef1234567890)
โœ…
Category: Valid value (Workshops)
โœ…
Workloads: All collections found
โš ๏ธ
Description: Missing estimated time
โŒ
common.yaml: Invalid cloud_provider value

Common Issues and Fixes

UUID Issues

Wrong:

asset_uuid: A1B2C3D4-E5F6-7890-ABCD-EF1234567890

UUID contains uppercase letters

Correct:

asset_uuid: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Convert to lowercase

Category Issues

Wrong:

category: Workshop  # Singular or wrong case

Wrong category name

Correct:

category: Workshops  # Must be: Workshops, Demos, or Sandboxes

Use exact plural form

Workload Issues

Wrong:

workloads:
  - showroom  # Missing collection namespace

Incorrect workload format

Correct:

workloads:
  - rhpds.showroom.ocp4_workload_showroom

Use full collection path


Tips & Best Practices

โœ“ Always Validate

Before creating PR

Fix Critical First

Errors before warnings

๐Ÿ”„ Run Multiple Times

As you fix issues

๐Ÿ“‹ Check Examples

Similar catalogs for patterns

Keep in Sync

common.yaml and dev.yaml


Troubleshooting

Skill not found?
  • Restart Claude Code or VS Code
  • Verify installation: ls ~/.claude/skills/agnosticv-validator (Claude Code) or ls ~/.cursor/skills/agnosticv-validator (Cursor)
  • Check the Troubleshooting Guide
Validation fails but looks correct?
  • Check for hidden characters or extra spaces
  • Verify YAML indentation (use spaces, not tabs)
  • Compare with working catalog examples
Workload not found error?
  • Check ~/.claude/docs/workload-mappings.md
  • Verify collection is published
  • Ensure namespace.collection.role format