Custom Query DSL & Semantic Linter
symtrace v0.5.0 includes a custom Tree-Sitter Query DSL engine and a dedicated declarative semantic linter (symtrace lint). Developers and security teams can define domain-specific architectural invariants and security checks using standard Tree-Sitter .scm query files placed in .symtrace/queries/.
Declarative AST Semantic Linter (symtrace lint)
Section titled “Declarative AST Semantic Linter (symtrace lint)”In v0.5.0, you can run semantic lint rules across your entire codebase as a standalone CI step:
# Scan current repository with default rules in .symtrace/queriessymtrace lint .
# Enforce zero warnings in automated CI pipelines (non-zero exit code on violations)symtrace lint . --max-warnings 0
# Specify custom queries directorysymtrace lint src/ --queries-dir /path/to/my-rules
# Format output as SARIF for GitHub Code Scanningsymtrace lint . --format sarifLinter CLI Options
Section titled “Linter CLI Options”| Flag | Default | Description |
|---|---|---|
PATH | . | Target file or directory to scan |
--queries-dir <DIR> | .symtrace/queries | Directory path containing .scm rule files |
--max-warnings <N> | 0 | Maximum allowed warnings before non-zero CI exit code |
--format <FMT> | cli | Linter output format (cli, json, sarif) |
How Rule Evaluation Works
Section titled “How Rule Evaluation Works”During AST diff analysis or symtrace lint scans, symtrace compiles .scm queries against parsed Concrete Syntax Trees (CSTs). When an AST node matches a query pattern, symtrace extracts severity metadata and surfaces annotated findings.
.symtrace/queries/*.scm │ ▼ Query DSL Compiler │ ┌─────────┴─────────┐ ▼ ▼ AST Diff Engine symtrace lint (CI) │ │ ▼ ▼ Diff Annotations SARIF / CLI FindingsRule File Structure & Directives
Section titled “Rule File Structure & Directives”Rule files are placed under .symtrace/queries/<rule_name>.scm. Each rule can declare optional metadata headers:
;; @severity ERROR|WARN|INFO(default:WARN);; @message <custom message template>(supports$fileand$lineinterpolation)
;; .symtrace/queries/no_unwrap.scm;; @severity ERROR;; @message Unhandled unwrap() detected in $file:$line: use proper error handling or Result matching(call_expression function: (field_expression field: (field_identifier) @method (#eq? @method "unwrap") )) @no_unwrap_violationQuery Syntax Examples
Section titled “Query Syntax Examples”1. Flag Security-Sensitive Public API Changes (Rust)
Section titled “1. Flag Security-Sensitive Public API Changes (Rust)”;; .symtrace/queries/security_api.scm;; @severity ERROR;; @message Public security-sensitive API modified in $file:$line(function_item visibility_modifier: (visibility_modifier) @vis (#eq? @vis "pub") name: (identifier) @name (#match? @name "^(auth|crypto|verify|token)")) @security_api_change2. Track Modifications to Database Models (Python)
Section titled “2. Track Modifications to Database Models (Python)”;; .symtrace/queries/orm_models.scm;; @severity WARN;; @message Django / SQLAlchemy ORM model altered in $file:$line(class_definition superclasses: (argument_list (identifier) @base (#match? @base "^(Model|BaseModel)$") ) body: (block) @model_body) @orm_model_change3. Flag Exported API Route Changes (TypeScript)
Section titled “3. Flag Exported API Route Changes (TypeScript)”;; .symtrace/queries/api_routes.scm;; @severity WARN;; @message Exported HTTP route handler modified in $file:$line(export_statement declaration: (function_declaration name: (identifier) @fn_name (#match? @fn_name "^(GET|POST|PUT|DELETE|handler)$") )) @api_route_change4. Detect Sensitive Config Alterations (C#)
Section titled “4. Detect Sensitive Config Alterations (C#)”;; .symtrace/queries/config_classes.scm;; @severity INFO(class_declaration name: (identifier) @class_name (#match? @class_name "Config$")) @config_class_changeOutput Representation
Section titled “Output Representation”Terminal Linter Output (symtrace lint)
Section titled “Terminal Linter Output (symtrace lint)”[ERROR] src/auth.rs:L42: Unhandled unwrap() detected in src/auth.rs:42: use proper error handling (Rule: no_unwrap)[WARN] src/server.rs:L18: Security-sensitive API modified (Rule: security_api)
━━━ Summary ━━━Files Scanned: 18 | Errors: 1 | Warnings: 1 | Passed: falseIn Diff Mode (symtrace)
Section titled “In Diff Mode (symtrace)”When .scm rules match modified functions in a diff, operations are annotated inline:
━━━ src/auth.rs ~ [MODIFY] function_item 'authenticate_user' modified (L42 -> L45) [80% similarity, medium] ── Custom Rule Alerts ── ⚠️ [ERROR] [security_api] Security-sensitive public API signature modifiedMachine-Readable SARIF Output (--format sarif)
Section titled “Machine-Readable SARIF Output (--format sarif)”{ "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "version": "2.1.0", "runs": [ { "tool": { "driver": { "name": "symtrace-lint", "semanticVersion": "0.5.0" } }, "results": [ { "ruleId": "no_unwrap", "level": "error", "message": { "text": "Unhandled unwrap() detected in src/auth.rs:42" }, "locations": [ { "physicalLocation": { "artifactLocation": { "uri": "src/auth.rs" }, "region": { "startLine": 42 } } } ] } ] } ]}Configuration
Section titled “Configuration”Configure default query directories and evaluation flags in .symtracerc / symtrace.toml:
[queries]enabled = truedir = ".symtrace/queries"fail_on_security_match = false # If true, --check exits with code 1 on security rule match