Stella Policy DSL Grammar Specification

Version: stella-dsl@1.0
Status: Implemented
Last Updated: 2026-02-15

Overview

The Stella Policy DSL is a domain-specific language for defining release policies that control software deployment decisions. Policies are evaluated against signal contexts to produce deterministic verdicts.

File Extension

Policy files use the .stella extension.

Lexical Structure

Comments

// Single-line comment

/*
 * Multi-line comment
 */

Keywords

Reserved keywords (case-sensitive):

KeywordDescription
policyPolicy declaration
syntaxSyntax version declaration
metadataPolicy metadata block
settingsPolicy settings block
profileProfile declaration
ruleRule declaration
whenRule condition
thenRule action (condition true)
elseRule action (condition false)
andLogical AND
orLogical OR
notLogical NOT
trueBoolean true
falseBoolean false
nullNull literal
inMembership operator
mapMap literal
envEnvironment binding

Operators

OperatorDescription
==Equality
!=Inequality
<Less than
<=Less than or equal
>Greater than
>=Greater than or equal
:=Definition
=>Arrow (lambda/map)
.Member access
,Separator
:Key-value separator
=Assignment

Literals

Strings

"hello world"
"escaped \"quotes\""

Numbers

42
3.14
-1
0.5

Booleans

true
false

Arrays

[1, 2, 3]
["a", "b", "c"]

Identifiers

Identifiers start with a letter or underscore, followed by letters, digits, or underscores:

identifier
_private
signal_name
cvss_score

Grammar (EBNF)

document        = policy-header "{" body "}" ;

policy-header   = "policy" string-literal "syntax" string-literal ;

body            = { metadata-block | settings-block | profile | rule } ;

metadata-block  = "metadata" "{" { key-value } "}" ;

settings-block  = "settings" "{" { key-value } "}" ;

key-value       = identifier ":" literal ;

profile         = "profile" identifier "{" { profile-item } "}" ;

profile-item    = map-item | env-item | scalar-item ;

map-item        = "map" identifier "=>" expression ;

env-item        = "env" identifier "=>" string-literal ;

scalar-item     = identifier ":=" expression ;

rule            = "rule" identifier [ "(" priority ")" ] "{" rule-body "}" ;

priority        = number-literal ;

rule-body       = when-clause then-clause [ else-clause ] ;

when-clause     = "when" expression ;

then-clause     = "then" "{" { action } "}" ;

else-clause     = "else" "{" { action } "}" ;

action          = action-name [ "(" { argument } ")" ] ;

action-name     = identifier ;

argument        = expression | key-value ;

expression      = or-expression ;

or-expression   = and-expression { "or" and-expression } ;

and-expression  = unary-expression { "and" unary-expression } ;

unary-expression = [ "not" ] primary-expression ;

primary-expression = literal
                   | identifier
                   | member-access
                   | "(" expression ")"
                   | comparison ;

comparison      = primary-expression comparison-op primary-expression ;

comparison-op   = "==" | "!=" | "<" | "<=" | ">" | ">=" | "in" ;

member-access   = identifier { "." identifier } ;

literal         = string-literal
                | number-literal
                | boolean-literal
                | array-literal
                | null-literal ;

string-literal  = '"' { character } '"' ;

number-literal  = [ "-" | "+" ] digit { digit } [ "." digit { digit } ] ;

boolean-literal = "true" | "false" ;

array-literal   = "[" [ expression { "," expression } ] "]" ;

null-literal    = "null" ;

Example Policy

policy "Production Release Policy" syntax "stella-dsl@1" {
    metadata {
        author: "security-team@example.com"
        version: "1.2.0"
        description: "Governs production releases"
    }
    
    settings {
        default_action: "block"
        audit_mode: false
    }
    
    profile production {
        env target => "prod"
        map severity_threshold := 7.0
    }
    
    rule critical_cve_block (100) {
        when cvss.score >= 9.0 and cve.reachable == true
        then {
            block("Critical CVE is reachable")
            notify("security-oncall")
        }
    }
    
    rule high_cve_warn (50) {
        when cvss.score >= 7.0 and cvss.score < 9.0
        then {
            warn("High severity CVE detected")
        }
        else {
            allow()
        }
    }
    
    rule sbom_required (80) {
        when not sbom.present
        then {
            block("SBOM attestation required")
        }
    }
}

Signal Context

Policies are evaluated against a signal context containing runtime values:

SignalTypeDescription
cvss.scorenumberCVSS score of vulnerability
cve.reachablebooleanWhether CVE is reachable
cve.idstringCVE identifier
sbom.presentbooleanSBOM attestation exists
sbom.formatstringSBOM format (cyclonedx, spdx)
artifact.digeststringArtifact content digest
artifact.tagstringContainer image tag
environmentstringTarget environment
attestation.signedbooleanHas signed attestation

Compilation

The DSL compiles to a content-addressed IR (Intermediate Representation):

  1. Tokenize: Source → Token stream
  2. Parse: Tokens → AST
  3. Compile: AST → PolicyIrDocument
  4. Serialize: IR → Canonical JSON
  5. Hash: JSON → SHA-256 checksum

The checksum provides deterministic policy identity for audit and replay.

CLI Commands

# Lint a policy file
stella policy lint policy.stella

# Compile to IR JSON
stella policy compile policy.stella --output policy.ir.json

# Get deterministic checksum
stella policy compile policy.stella --checksum-only

# Simulate with signals
stella policy simulate policy.stella --signals context.json

See Also