Heuristic Annotations
The heuristic property associates a CRADLE element with a supported security
framework and identifier. On an instance, it can also add provisioning tasks to
backend-generated output when matching heuristic content is available.
Only instance-level heuristics currently reach the deployment IR and generated provisioning playbook. Heuristics on metadata, events and objects are parsed, but they do not change backend output.
Syntax
heuristic("<framework>", "<identifier>")
For identifier-based frameworks, the compiler consumes two string values:
| Argument | Description | Example |
|---|---|---|
| Framework | Name or key identifying the external classification system | cve |
| Identifier | Identifier or framework-specific value | CVE-2024-1086 |
Use one framework-identifier pair per declaration. Repeat heuristic when an
instance needs multiple annotations.
heuristic("cve", "CVE-2024-1086"),
heuristic("cwe", "CWE-89")
Do not combine several identifiers into one comma-separated value. Separate declarations remain easier to validate, search and transform.
Framework keys are parsed case-insensitively and normalized to lowercase. The current compiler recognizes exactly these keys:
cvettpmbccwed3fendcapeckillchainfair
An unknown key, such as cvee, is an error. Earlier compiler behavior silently
treated an unknown key as cve; it no longer does so.
Where heuristics take effect
The current compiler recognizes heuristic annotations on:
| Context | Current behavior |
|---|---|
| Instance | Validated, lowered into the deployment IR and rendered into provisioning output. |
| Metadata | Parsed as an annotation; not included in deployment output. |
| Event | Parsed as an annotation; not included in deployment output. |
| Object | Parsed as an annotation; not included in deployment output. |
Place a heuristic on an instance when it is expected to affect a build. Other placements should be treated as descriptive annotations only.
Framework and identifier checks
The compiler checks instance heuristic identifiers against these shapes:
| Framework key | Expected value | Example |
|---|---|---|
cve | CVE-<four-digit year>-<four or more digits> | CVE-2024-1086 |
ttp | T plus four digits, optionally followed by a three-digit sub-technique | T1566.001 |
mbc | OB, B, C, E or F plus four digits, optionally followed by three digits | C0046 |
cwe | CWE- plus one to four digits | CWE-79 |
d3fend | D3- plus an alphanumeric abbreviation | D3-IPA |
capec | CAPEC- plus one to four digits | CAPEC-160 |
killchain | One of the seven Cyber Kill Chain phases | command-and-control |
fair | No identifier-shape check | See FAIR values. |
An unfamiliar identifier shape produces a warning rather than an error because external frameworks can evolve independently of CRADLE. The compiler does not look up the identifier in an external framework registry.
Except for fair, an instance heuristic value must also be a safe single path
segment: letters, digits, ., _ and - are allowed, while path separators,
an empty value, . and .. are rejected.
Examples by context
Instance annotation
instance("TargetServer") >
os("ubuntu", "20.04"),
heuristic("cve", "CVE-2024-1086"),
heuristic("cwe", "CWE-89").
Event annotation
event("initialize_client") >
instance("TargetServer"),
needRoot(false),
subject("bash", ""),
runObject("ValidationScript", ""),
heuristic("ttp", "T1190"),
description("Illustrative validation event").
Object annotation
object("ValidationScript") >
location("${uriRemote}/scripts/validate.sh"),
heuristic("mbc", "F0002").
FAIR values
Existing documentation uses the fair key with semicolon-separated key=value data:
heuristic("fair", "controlStrengthMostLikely=75;primaryLossResponseMostLikely=50000")
The parser also accepts a structured form:
heuristic("fair", { threat_event_frequency = 2 })
FAIR values are exempt from the normal identifier and content checks. The compiler does not validate the fields, preserve the structured block in deployment output, apply distributions, run simulations or calculate risk.
Do not use either FAIR form as an instance provisioning reference. Structured fields are not carried into the deployment IR, and FAIR data is not a valid setup-template identifier for a backend to resolve.
FAIR remains annotation syntax rather than a supported provisioning or analytical feature.
Provisioning content
An instance heuristic resolves against heuristics_dir using this layout:
heuristics/
└── <framework>/
└── <identifier>/
└── ansible/
└── <identifier>.j2
For example, heuristic("cve", "CVE-2024-1086") resolves to:
<heuristics_dir>/cve/CVE-2024-1086/ansible/CVE-2024-1086.j2
The template is rendered into the instance's generated provisioning playbook.
Assets can live beside the heuristic folder and can be referenced by the
template through config_asset_dir.
heuristics_dir may be a local directory or a Git repository configured for
CradleXC. When it is a repository, cxc build, cxc rebuild and the
development deployment commands fetch referenced heuristic subtrees on demand.
List locally available heuristic content with:
cxc heuristics list
or inspect another directory with:
cxc heuristics list --heuristics-dir <path>
Heuristic provisioning is setup-only. Replacing or removing a heuristic can mark an instance for reprovisioning, but CradleXC does not render teardown tasks for the removed heuristic.
Validation behavior
Current instance-level diagnostics include:
- unknown framework: error
- empty non-FAIR value: error
- unsafe path value: error
- unexpected identifier shape: warning
- no matching content in a resolved
heuristics_dir: warning
cxc validate performs syntax and identifier checks without loading
heuristics_dir. Commands that prepare backend output also resolve heuristic
content; if an instance heuristic has no setup template, rendering can fail even
though the content diagnostic itself is a warning.
Maintenance guidance
When introducing a framework convention:
- Define a stable lowercase framework key.
- Identify the authoritative external source.
- Document valid target contexts and identifier forms.
- Decide whether identifiers are validated locally or externally.
- Add positive and negative test cases.
- Record the supported framework version or retrieval date.
Heuristic annotations must not be treated as authorization, proof that a vulnerability exists or evidence that an event occurred.