Skip to content

Code Quality Rules — authoring guide

Documentation home · Previous: Features · Next: Configuration

This guide is for contributors adding or reviewing code-quality rules. Synapse's code-quality engine (see the Features guide) turns parsed source into Kind=quality / Kind=reliability findings and the A–E ratings. Each language ships a built-in "Synapse way" quality profile — generated automatically from the catalog rules for that language (every rule whose Language matches, at its default severity). This page defines how those rules are modelled, how they are authored, and the authoritative sources each language draws on.

Tracking epic: Code Quality as a product · language rule-pack tracker: #185.

Clean-room policy (non-negotiable)

We author 100% of our rule content ourselves. We survey prior art — the public rule taxonomies of mature analyzers, and each language's own linters — to understand structure and coverage, never to copy. Specifically:

  • Do derive rules from a language's authoritative, openly-published sources: official style guides, the language team's own tooling (go vet, Clippy, Roslyn analyzers, …), CWE, OWASP, SEI CERT secure-coding standards, and ISO/IEC 25010 software-quality attributes.
  • Do write our own rule title, description, rationale, remediation, and code examples, and our own detection (AST query, structured parser check, token/line pattern, or metric threshold).
  • Do not copy any third-party rule's text, description, examples, or detection code, and do not attribute our rules to a specific commercial product. Cite the concept's origin (a CWE id, a style-guide section, a linter category) — not another tool's rule prose.

When a rule maps to a well-known weakness, cite the CWE (e.g. CWE-89 for SQL injection). When it maps to a language idiom, cite the style-guide section or the linter category it belongs to.

Taxonomy

Every rule carries a type, an impacted software quality, and a severity.

Type (what kind of problem):

Type Meaning
bug Code that is or will be wrong at runtime (a defect).
vulnerability A security weakness that is exploitable as written.
code_smell Maintainability issue — correct today, costly to change.
security_hotspot Security-sensitive code that needs human review (not asserted exploitable).

Software quality (which rating it moves — from ISO/IEC 25010; a rule may touch more than one): Security, Reliability, Maintainability. This is how a rule feeds the A–E ratings — every new rule declares the quality it impacts so the rating engine stays honest.

Severity (Synapse's own scale — do not fork it): critical · high · medium · low · info.

security_hotspot findings flow through the review workflow (To review → Acknowledged / Fixed / Safe), not the exploitability gate — see the hotspots issue #179.

Depth: parity targets + rule categories

A serious code-quality profile carries hundreds of rules per major language, not a dozen. Our built-in profiles target real parity with mature analyzers. A flat list of 300+ rules is unmaintainable, so every language pack is planned as a set of rule categories (families), each with a target count that sums to the language's parity target. Contributors claim a category within a language and fill it out; reviewers check the family is complete, not just that "some rules exist".

Standard rule families (apply across languages; a language issue distributes its target across these):

Family Covers Typical types
bugs logic/correctness defects (wrong comparisons, off-by-one, always-true conditions, unreachable code) bug
err exception & error handling (swallowed errors, over-broad catch, error in finally) bug, code_smell
res resource & memory management (unclosed handles, leaks, use-after-free, double-free) bug
conc concurrency / async (races, deadlock shapes, unawaited promises, goroutine leaks) bug
inj injection & untrusted input (SQLi, command, path traversal, XXE, deserialization, SSRF, XSS) vulnerability
crypto cryptography & secrets (weak hash/cipher, hardcoded keys, bad randomness, TLS misconfig) vulnerability, security_hotspot
authz authentication / session / access control vulnerability, security_hotspot
hotspot security-sensitive code to review (not asserted exploitable) security_hotspot
api library/contract misuse (deprecated/dangerous API, wrong arguments, misused stdlib) bug, code_smell
types type & null safety (null deref, unchecked casts, narrowing, any) bug, code_smell
perf performance anti-patterns (allocation in loops, needless copies) code_smell
maint maintainability: cyclomatic/cognitive complexity, size, duplication, dead/redundant code, naming, comments, docs, modernization, test smells code_smell

Each language issue carries a category-count table (family → target) whose total is the language's parity target. Ship a family at a time; each rule still needs metadata + a compliant/non-compliant golden test (see the workflow below).

Rule schema

Rules are catalogued as first-class entities (see #182):

Rule {
  Key            // stable, opaque. Namespace by analyzer domain. Existing IDs never renamed.
  Name           // short human title
  Language       // explicit user-facing language ("Go", "Python", etc.). Never parsed from Key.
  Type           // bug | vulnerability | code_smell | security_hotspot
  Qualities[]    // security | reliability | maintainability
  DefaultSeverity// critical | high | medium | low | info
  Tags[]         // free-form discovery tags
  CWE[] / OWASP[]// when security-relevant
  Description    // what it flags (our own words)
  Rationale      // why it matters (cite the concept origin + a source link)
  Remediation    // how to fix
  CompliantExample    // compliant code example
  NoncompliantExample // non-compliant code example
  RemediationEffort // minutes, for the tech-debt measure
  Detection      // ast | parse | pattern | metric
}

Detection & the parser

Detection is one of: an AST query (via the sandboxed synapse-ast sidecar, tree-sitter), a structured parser check, a token/line pattern, or a metric threshold (complexity, size, duplication). Prefer AST rules where a grammar exists.

The sidecar parses, via bundled tree-sitter grammars, Python, JavaScript, Java, Go, C, C++, C#, Rust, Ruby, PHP, Scala, Swift, Kotlin, CSS, and HTML (registered in internal/infrastructure/tools/astwalk; each grammar's function/complexity node types are verified by parse_langs_cgo_test.go). go-enry supplies line counts for many more. A language whose grammar is registered is ready for AST rule authoring. VB.NET ships 140 deterministic pattern rules for .vb files but has no bundled grammar; where relevant, C#/.NET concepts are re-authored for VB syntax. Structured-config languages (Docker, CloudFormation, Terraform, Kubernetes, Azure Resource Manager) use the misconfig analyzer, and XML/Secrets/Text use token/parse — none needs a grammar. The matrix below records each language's parser status.

Authoring workflow

  1. Pick the language's authoritative sources (matrix below) and enumerate rule ideas by category: correctness/bugs, security, maintainability/smells, and style-with-substance.
  2. For each rule, write the schema fields from scratch, with a concrete source link in the rationale, and a compliant + non-compliant example.
  3. Implement detection (AST query preferred) and add a golden test per rule: a fixture that must flag and one that must not.
  4. Catalogue the rule (#182) with its Language set. That is all that is required to ship it: the built-in "Synapse way ()" profile is generated from the catalog, so a correctly-Language-tagged rule is automatically active in that language's default profile (#183), browsable in the Rules explorer, and gate-eligible (#184).

Built-in profiles, custom profiles & the gate

How a rule flows from the catalogue to an enforced gate result (the shipped #182/#183/#184 plumbing):

  • Built-in profile (generated, immutable). For each language, qualityprofile.BuiltIn activates every catalog rule for that Language at its default severity, under the key synapse-way-<slug>. It is never stored and never edited — it always reflects the current catalogue.
  • Custom profile (copy, editable). A user copies a built-in into a tenant-scoped custom profile, then deactivates rules or overrides severities. Deactivating/overriding is PermOperate-gated and audited; it never touches SCA advisory findings (a profile can only affect first-party catalog rules, so it can't suppress a dependency vulnerability).
  • Assignment. A profile is assigned per language per project. At analysis time the assigned profiles are resolved into one overlay that drops deactivated rules and applies severity overrides before the findings are classified, rated, and gated — so analyses honor the assigned profile.
  • Gate. Metrics feed the Quality Gate (#184): the whole-codebase and Clean-as-You-Code (new_*) counts, ratings, hotspots-reviewed, and the coverage/duplication metrics (coverage, new_coverage, duplication_density, new_duplication).

The acceptance invariant — every shipped language has a non-empty built-in profile — is enforced by a test over the real catalogue (internal/infrastructure/rulecatalogqualityprofile.BuiltIn per language), so adding the first rule for a new language automatically gives it a "Synapse way" profile.

Language source matrix

Parity targets. These are our own built-in-profile targets, set to match the depth of a mature analyzer's default profile (not a token seed). Each language issue decomposes its target across the rule families above. Ship families incrementally toward the target; every rule is clean-room + golden-tested.

Language Parity target (rules) Notes
Java ~450 broadest surface; concurrency + API misuse heavy
JavaScript/TypeScript ~400 one pack; shared JS rules + TS-only type rules
C# ~300 + VB.NET later shares much of the catalog
Python ~300 dynamic-language bug + API-misuse heavy
C++ ~180 memory/resource + object-lifetime heavy
C ~120 memory safety + CERT C core
Rust ~80 Clippy-category coverage + unsafe/security
Node.js ~50 server-side security subset (complements JS/TS)
Go ~40 correctness + concurrency + gosec-class security
PHP ~180 web-app security + typing
VB.NET ~140 shares most of the C# catalog
Kotlin ~130 JVM + Android; nullability + coroutines
Swift ~120 iOS/macOS; optionals + memory
Terraform ~60 multi-cloud (AWS/Azure/GCP) misconfig
HTML ~50 correctness + accessibility (WCAG)
Secrets ~40 credential detectors (extends the existing scanner)
Ruby ~40 Rails security (Brakeman-class) + style
Scala ~40 JVM + functional idioms
ARM ~35 cloud misconfig
CSS ~30 correctness + maintainability
Docker ~30 image hardening + hygiene
Kubernetes ~30 manifest hardening (Pod Security Standards)
CloudFormation ~30 cloud misconfig
XML ~30 XXE + schema/well-formedness
IPython Notebooks +~15 notebook-specific (reuses the Python pack over cells)
Text ~8 any-file: bidi-unicode, BOM, generic secrets
Flex deferred legacy ActionScript — low priority

Every source below is openly published; cite the concept origin per rule.

Language Detection Parser status Authoritative sources
Go AST + pattern ready (tree-sitter) Effective Go, Go Code Review Comments, go vet, Staticcheck checks, gosec, CWE
Python AST (today) ready PEP 8, Ruff rules, Pylint checks, Bandit plugins, CWE
JavaScript/TypeScript AST (JS today) needs TS grammar ESLint rules, typescript-eslint rules, MDN JS, CWE
Node.js AST (JS) + pattern needs TS grammar for TS OWASP Node.js Security Cheat Sheet, Prototype Pollution Prevention, Node.js security best practices, NPM Security, CWE
Java AST (today) ready Google Java Style, Error Prone bug patterns, SpotBugs descriptions, SEI CERT Oracle (Java), CWE
C# AST ready (tree-sitter) .NET code-quality rules, StyleCop Analyzers, .NET secure coding, CWE
Rust AST ready (tree-sitter) Clippy lints (book), Rust API Guidelines, RustSec advisories, CWE
C AST ready (tree-sitter) SEI CERT C, clang-tidy checks, Cppcheck, CWE
C++ AST ready (tree-sitter) SEI CERT C++, C++ Core Guidelines, clang-tidy checks, CWE
CSS AST/token ready (tree-sitter) W3C CSS specs, MDN CSS, Stylelint rules
Docker config analyzer ready (misconfig) Dockerfile best practices, Hadolint rules, CIS Docker Benchmark, CWE
CloudFormation config analyzer ready (misconfig) AWS Well-Architected, cfn-lint rules, CIS AWS Benchmark, CWE
Azure Resource Manager config analyzer ready (misconfig) ARM template best practices, arm-ttk, Azure Security Baseline, CWE
Kotlin AST ready (tree-sitter) Kotlin coding conventions, detekt rules, ktlint standard rules, CWE
PHP AST ready (tree-sitter) PSR standards, PHPStan, Psalm, OWASP PHP, CWE
Ruby AST ready (tree-sitter) Ruby Style Guide, RuboCop cops, Brakeman warnings, CWE
Scala AST ready (tree-sitter) Scala Style Guide, Scalafix rules, Scalastyle, CWE
Swift AST ready (tree-sitter) Swift API Design Guidelines, SwiftLint rule directory, CWE
VB.NET token/pattern no bundled grammar (pattern rules) .NET code-quality rules (shared with C#), CWE
Kubernetes config analyzer ready (misconfig) Pod Security Standards, KubeLinter checks, CIS Kubernetes Benchmark, kubesec, CWE
Terraform config analyzer ready (misconfig) Terraform style, Trivy IaC (ex-tfsec), Checkov Terraform policies, tflint, AWS/Azure/GCP Well-Architected, CWE
HTML AST/token ready (tree-sitter) HTMLHint rules, WCAG, MDN HTML, W3C validator
XML token/parse ready W3C XML, OWASP XXE Prevention, CWE-611
IPython Notebooks reuses Python ready (Python) reuses the Python pack over notebook cells + notebook-specific (nbqa, Bandit)
Secrets token/entropy ready (secretscan) extends the existing secret scanner; gitleaks rules, detect-secrets, CWE-798
Text token ready any-file checks: bidi-unicode (Trojan Source), BOM, oversized files, generic secrets

Kubernetes and Terraform give Synapse its AWS / Azure / GCP cloud-misconfig coverage alongside CloudFormation + ARM. Secrets and IPython Notebooks extend existing engines (the secret scanner and the Python pack) rather than adding a new parser. Deferred / low-priority: Flex (legacy ActionScript). Further candidates: Shell, Dart, YAML-generic.

Reviewing an existing pack

When reviewing a language pack, check each rule:

  • Correct — does the detection actually match the described defect, with acceptable false-positive rate? Prefer AST over regex where precision matters.
  • Sourced — does the rationale cite a concrete, openly-published source link?
  • Typed + rated — right type, impacted software quality, and severity on Synapse's scale?
  • Tested — a compliant + non-compliant golden fixture?
  • Original — our own wording and detection (clean-room)?