# 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): | Keyword | Description | |---------|-------------| | `policy` | Policy declaration | | `syntax` | Syntax version declaration | | `metadata` | Policy metadata block | | `settings` | Policy settings block | | `profile` | Profile declaration | | `rule` | Rule declaration | | `when` | Rule condition | | `then` | Rule action (condition true) | | `else` | Rule action (condition false) | | `and` | Logical AND | | `or` | Logical OR | | `not` | Logical NOT | | `true` | Boolean true | | `false` | Boolean false | | `null` | Null literal | | `in` | Membership operator | | `map` | Map literal | | `env` | Environment binding | ### Operators | Operator | Description | |----------|-------------| | `==` | 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) ```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 ```stella 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: | Signal | Type | Description | |--------|------|-------------| | `cvss.score` | number | CVSS score of vulnerability | | `cve.reachable` | boolean | Whether CVE is reachable | | `cve.id` | string | CVE identifier | | `sbom.present` | boolean | SBOM attestation exists | | `sbom.format` | string | SBOM format (cyclonedx, spdx) | | `artifact.digest` | string | Artifact content digest | | `artifact.tag` | string | Container image tag | | `environment` | string | Target environment | | `attestation.signed` | boolean | Has 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 ```bash # 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 - [Policy Module Architecture](architecture.md) - [PolicyDsl Implementation](../../../src/Policy/StellaOps.PolicyDsl/) - [Signal Context Reference](signal-context-reference.md)