NAEOS provides comprehensive validation at multiple levels to catch errors early and enforce consistency across your project.

Validation Levels

┌─────────────────────────────────────────────┐
│              Validation System               │
├──────────┬──────────┬──────────┬────────────┤
│   Spec   │  Module  │ Service  │  Policy    │
│  Valid.  │  Valid.  │  Valid.  │  Valid.   │
└──────────┴──────────┴──────────┴────────────┘

Spec Validation

CLI Usage

# Validate a specification
naeos validate --input-file spec.yaml

# Lint a specification (additional style checks)
naeos lint --input-file spec.yaml

# Output as JSON
naeos validate --input-file spec.yaml --output json

Go API

import "github.com/NAEOS-foundation/naeos/internal/lint"

result, err := lint.ValidateSpec(specContent)
if err != nil {
    log.Fatal(err)
}

if !result.Valid {
    for _, issue := range result.Issues {
        fmt.Printf("[%s] %s\n", issue.Severity, issue.Message)
    }
}

Module Validation

Duplicate Detection

Detects modules with the same name:

validator := parser.NewSpecValidator()
issues := validator.ValidateModules(modules)

// Issues will include "module-duplicate" if duplicates exist

Circular Dependency Detection

Detects circular dependencies between modules:

modules := []parser.Module{
    {Name: "a", Dependencies: []string{"b"}},
    {Name: "b", Dependencies: []string{"a"}},
}

issues := validator.ValidateModules(modules)
// Issues will include "circular-dependency"

Dangling Dependency Detection

Detects references to non-existent modules:

modules := []parser.Module{
    {Name: "auth", Dependencies: []string{"nonexistent"}},
}

issues := validator.ValidateModules(modules)
// Issues will include "dependency-not-found"

Service Validation

Port Conflict Detection

Detects multiple services using the same port:

services := []parser.Service{
    {Name: "api", Port: 8080},
    {Name: "web", Port: 8080},
}

issues := validator.ValidateServices(services)
// Issues will include "service-port-conflict"

Port Range Validation

Ensures ports are within valid range (1–65535):

services := []parser.Service{
    {Name: "bad", Port: 99999},
}

issues := validator.ValidateServices(services)
// Issues will include "service-port-range"

Schema Version Validation

Automatic Check on Parse

The parser automatically validates the schema version:

# This spec will be checked against minimum version 0.1.0
version: 0.3.0

Manual Check

result := parser.CheckSpecVersion("0.3.0")
if !result.Valid {
    fmt.Println(result.Message)
    // "Schema version 0.3.0 is not supported. Minimum: 0.1.0"
}

Policy Validation

Default Rules

import "github.com/NAEOS-foundation/naeos/internal/governance/policy"

evaluator := policy.NewEvaluator()
rules := policy.DefaultRules()

ctx := map[string]any{
    "project":  "my-app",
    "modules":  3,
    "services": 2,
}

results, err := evaluator.EvaluateRules(rules, ctx)
for _, r := range results {
    fmt.Printf("[%s] %s: %s\n", r.RuleID, r.Action, r.Message)
}

Custom Rules

rules := []policy.Rule{
    {
        RuleID:    "require-architecture",
        Condition: "exists:architecture",
        Priority:  1,
        Action:    "block",
        Scope:     "spec",
        Enabled:   true,
    },
    {
        RuleID:    "max-modules",
        Condition: "lt:module_count,50",
        Priority:  2,
        Action:    "warn",
        Scope:     "spec",
        Enabled:   true,
    },
}

Validation Result

type ValidationResult struct {
    Valid        bool
    Issues       []ValidationIssue
    Warnings     []ValidationIssue
    ModuleCount  int
    ServiceCount int
}

type ValidationIssue struct {
    Severity string  // "error", "warning", "info"
    Rule     string
    Message  string
    Line     int
}

Pipeline Integration

Validation runs automatically as part of the pipeline:

# Full pipeline includes validation
naeos run --input spec.yaml

# Validation-only mode
naeos validate --input-file spec.yaml

Skip Specific Validation

# Skip module validation
naeos run --input spec.yaml --skip-validation

# Skip specific checks
naeos validate --input-file spec.yaml --skip circular-deps

See also: Governance, Pipeline Engine, Spec Language