Skip to content
Architecture Decision Records

Architecture Decision Records

An ADR records a decision about the SecLang specification: what was decided, which alternatives existed, and why. Write one whenever the engines disagree and the spec has to pick (Divergence), when behaviour is undocumented but agreed (Clarification), when a legacy feature is retired (Deprecation), or when an engine-specific feature is promoted into the spec (Extension).

Process

  1. Copy 0000-template.md to NNNN-short-slug.md with the next free number.
  2. Fill every header field. Status is proposed until maintainers of at least two implementing engines agree, then accepted. superseded and rejected are terminal.
  3. A Divergence ADR must list at least one test under ## Tests that encodes the outcome. The validator checks the paths exist.
  4. Add a row to the index below. uv run python tools/validate.py fails if a file and the index disagree.
  5. Update the affected section of spec/ in the same PR.

Index

ADRTitleCategoryStatus
0001Status labels and the meaning of CoreClarificationproposed
0002Directive, operator, action and transformation names match case-insensitivelyDivergenceproposed
0003Test formats: SecRules Test Set JSON for units, go-ftw-derived YAML for engine profilesClarificationproposed
0004Canonical names and required aliasesDivergenceproposed
0005Unknown versus unsupported directivesDivergenceproposed
0006Core ctl: optionsDivergenceproposed
0007Persistent collections are ExtendedDivergenceproposed
0008Collection keys match case-insensitivelyDivergenceproposed
0009Strict per-phase evaluation is normative; early evaluation must be invisibleClarificationproposed
0010Engine-specific names are reservedClarificationproposed
0011ModSecurity v2 legacy features are DeprecatedDeprecationproposed
0012uppercase is promoted to CoreExtensionproposed
0013Comment lines ending in a backslashDivergenceproposed
0014SecDefaultAction constraintsDivergenceproposed
0015Every rule carries an idDivergenceproposed
0016skipAfter scope ends with the phaseDivergenceproposed
0017The default phase is 2 and is never inheritedDivergenceproposed
0018Core regular-expression syntax is the RE2-compatible subsetDivergenceproposed
0019DURATION is Extended with unspecified unitsClarificationproposed
0020JSON argument names are unspecifiedClarificationproposed
0021The portable logging contract is rule ids and messagesClarificationproposed
0022REQUEST_BODY without a body processorDivergenceproposed
0023Reference adapters live in this repositoryClarificationproposed
0024Unparsable @ipMatch entries are configuration errorsDivergenceproposed
0025SecRequestBodyInMemoryLimit is Extended, not CoreDivergenceproposed
0026compressWhitespace treats the byte 0xA0 as whitespaceDivergenceproposed
0027@rx is compiled dot-all; line anchors need (?m)Divergenceproposed
0028skipAfter resolves to a SecMarker, never to a rule idDivergenceproposed
0029Tag and message rule exceptions select by exact stringDivergenceproposed
0030A negated operator applies per valueClarificationproposed