Skip to main content

Scapius DSL (.ea) Linter & Formatter

The Scapius EA linter analyzes .ea architecture model files for formatting issues, code style inconsistencies, missing documentation/metadata, and architectural anti-patterns.

It runs automatically in the VS Code Extension and can be run in CI/CD pipelines via the Scapius CLI (scapius lint).


1. CLI Usage

Run the linter on any directory of .ea files:

scapius lint <workspace-directory-path> [options]

Common Flags

OptionDescription
-f, --format <text|json|sarif>Output format. text (default) for terminal output; json for machine consumption; sarif (SARIF v2.1.0) for GitHub Code Scanning.
--fixAutomatically apply fixes for fixable formatting and style rules in-place.
--dry-runPreview what fixes would be applied without modifying files on disk.
--strictTreat warnings as errors (exits with code 1 if any warning is reported).
--max-warnings <N>Fail (exit with code 1) if the total warning count exceeds N.
--rule <id>=<severity>Ad-hoc override for rule severity on the CLI (e.g. --rule naming-convention=error or --rule missing-owner=off).

Examples

# Lint a workspace with human-readable output
scapius lint ./architecture

# Automatically reformat and fix style violations in-place
scapius lint ./architecture --fix

# Run in CI with strict failure on any warning
scapius lint ./architecture --strict

# Output SARIF for GitHub Code Scanning
scapius lint ./architecture --format sarif > results.sarif

2. Configuration (manifest.yaml)

Linter rules, options, and severities can be configured centrally in your workspace's manifest.yaml under the lint: block:

workspace:
name: "Corporate Enterprise Architecture"
currency: "USD"

lint:
enabled: true
rules:
# Formatting rules
one-property-per-line:
severity: warning

consistent-brace-style:
severity: warning

# Style rules
naming-convention:
severity: warning
options:
convention: snake_case # snake_case | kebab-case | PascalCase

# Completeness rules
missing-description:
severity: warning
options:
require_for: ["system", "app", "capability", "process"]

missing-owner:
severity: warning
options:
require_for: ["system", "app"]

# Architectural rules
orphan-entity:
severity: warning
options:
ignore_types: ["standard", "trust_boundary", "policy"]

excessive-nesting-depth:
severity: warning
options:
max_depth: 3

# Governance rules
missing-data-classification:
severity: warning

missing-criticality:
severity: info

Supported Severity Levels

  • error: Blocks CI and reports as a fatal lint failure.
  • warning / warn: Reported as a warning.
  • info / suggestion: Reported as an informational suggestion.
  • off / disabled: Disables the rule completely.

3. Inline Comment Suppressions

To suppress lint warnings in specific files or lines, use # or // comments:

Disable a single line

system legacy_crm "Legacy CRM" {
owner "Sales" cost 100000 year # ea-lint-disable-line NEA5101
}

Disable the next line

# ea-lint-ignore-next-line NEA5004
system unassigned_service "Service Without Description" {
owner "Platform Team"
}

Disable a block of code

# ea-lint-disable naming-convention, missing-owner
system OldLegacySystem "Old Legacy System" {}
system AnotherOldSystem "Another Old System" {}
# ea-lint-enable naming-convention, missing-owner

4. Rule Catalog

Formatting & Layout Rules (NEA51xx)

NEA5101: one-property-per-line (Auto-fixable)

  • Default Severity: Warning
  • Rationale: Keeps git diffs clean and ensures readability across large enterprise architecture models.
  • Violation:
    system core_banking "Core Banking" {
    owner "Payments Team" cost 50000 month
    }
  • Compliant:
    system core_banking "Core Banking" {
    owner "Payments Team"
    cost 50000 month
    }

NEA5102: consistent-brace-style (Auto-fixable)

  • Default Severity: Warning
  • Rationale: Enforces Egyptian opening brace style ({ on declaration line).

NEA5103: no-consecutive-blank-lines (Auto-fixable)

  • Default Severity: Information
  • Rationale: Prevents accidental excessive vertical whitespace gaps (more than 1 blank line in a row).

NEA5104: blank-line-between-entities (Auto-fixable)

  • Default Severity: Information
  • Rationale: Encourages clean visual separation between distinct top-level entities or containers.

Style & Naming Rules (NEA50xx)

NEA5001: naming-convention (Auto-fixable)

  • Default Severity: Warning
  • Rationale: Ensures uniform casing across all entity IDs and view IDs.
  • Default Convention: snake_case (configurable: kebab-case, PascalCase).

NEA5002: empty-container

  • Default Severity: Warning
  • Rationale: Flags empty workspace, layer, group, or views blocks that define zero entities or statements.

Completeness & Documentation Rules (NEA50xx)

NEA5004: missing-description (Auto-fixable)

  • Default Severity: Warning
  • Rationale: Ensures that core architecture elements (system, app, capability, process, data_object) provide documentation describing their purpose.

NEA5005: missing-owner (Auto-fixable)

  • Default Severity: Warning
  • Rationale: Establishes organizational accountability for systems, applications, and capabilities.

NEA5006: missing-tags

  • Default Severity: Information
  • Rationale: Encourages tagging entities to enable rich, dynamic view filtering and slicing.

Architecture & Graph Quality Rules (NEA50xx)

NEA5003: excessive-nesting-depth

  • Default Severity: Warning
  • Rationale: Avoids overly deep containment hierarchies (e.g. system > app > component > subcomponent > ...) that impair readability and diagramming. Default max depth is 3.

NEA5007: orphan-entity

  • Default Severity: Warning
  • Rationale: Identifies "island" entities that have no relationships to any other entity in the workspace and are not referenced in any view.

NEA5008: dead-view

  • Default Severity: Warning
  • Rationale: Flags empty views that define no include or query statements.

NEA5009: redundant-relationship

  • Default Severity: Warning
  • Rationale: Flags duplicate relationships between the exact same pair of entities with the same verb.

Governance & Security Rules (NEA50xx)

NEA5010: missing-data-classification

  • Default Severity: Warning
  • Rationale: Requires all data_object entities to declare a data_classification (e.g. Public, Internal, Confidential, Restricted).

NEA5011: missing-criticality

  • Default Severity: Information
  • Rationale: Suggests setting a criticality rating on operational systems, applications, and infrastructure.

5. GitHub Actions CI Example

Upload SARIF diagnostics directly to GitHub Code Scanning to display inline PR annotations:

name: Scapius Architecture Lint

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'

- name: Run Scapius Linter
run: dotnet run --project backend/NexusEA.Cli -- lint ./models --format sarif > scapius-results.sarif
continue-on-error: true

- name: Upload SARIF to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: scapius-results.sarif