Playbook: Select Compliance Frameworks
Scenario and intended reader
You maintain a repository that already has SicarioSpec initialized, and you need to change or understand which compliance frameworks the gate enforces: read the current selection, add a framework, handle the finding that fires when a selected framework has no control map, and enforce an experimental-tier map deliberately.
This playbook is for the engineer or compliance owner making that change in
an existing repository. If you are choosing frameworks at initial setup
(sicario init), that decision belongs to the selection guide — the
"Choose profiles, presets, and frameworks" playbook in this section — which
covers per-profile defaults and composition. The
profiles reference and the
control maps reference remain the reference material;
this playbook is the workflow.
Starting state
- A repository initialized with
sicario initat SicarioSpec 0.6.0, using--profile appsec(any profile works; quoted output below was captured withappsec). sicario verify .currently passes.- A shell with Python 3.9+ and the SicarioSpec CLI installed. If
sicariois not on your PATH, every command below also works aspython3 -m sicario_cli.cli— for examplepython3 -m sicario_cli.cli verify ..
Assumed platform: macOS or Linux with a POSIX shell. On Windows, use
forward-slash paths in commands and adjust cat/cp to your shell.
Reconstructed exactly (this is also what the docs verification runner does —
see FR-051): init, then prune docs/compliance/control-maps/ down to the two
enforced maps (ssdf, iso27001) — a common hygiene move, and the starting
state step 4 assumes.
sicario init . --profile appsec
python3 - <<'PY'
from pathlib import Path
keep = {"ssdf-800-218-sicario.json", "iso-27001-2022-sicario.json"}
maps_dir = Path("docs/compliance/control-maps")
for f in maps_dir.glob("*.json"):
if f.name not in keep:
f.unlink()
PY
How framework selection works (one paragraph)
The selection lives in one plain-text file, .sicario/frameworks.txt, one
framework key per line. When the file exists, sicario verify requires a
control map for each listed key and emits a
SICARIO-MISSING-FRAMEWORK-MAP finding for each one whose map is absent —
you enforce exactly the frameworks you chose, not all 14 and not none. When
the file does not exist, no framework is selected and that finding cannot
fire (the coarse SICARIO-MISSING-CONTROL-MAPS check, which only requires
that some control map exists, runs regardless). The 14 shipped maps are
split into two tiers: supported (11 maps) and experimental
(ai-rmf, owasp-asvs, pci-dss). Experimental maps are never selected
implicitly — a profile default excludes them even when the profile's
framework table lists them — and are enforced only when you name them
explicitly.
Steps
1. Read the current selection
cat .sicario/frameworks.txt
# SicarioSpec framework selector (#18).
# One framework key per line. `sicario verify` requires a control map
# for each key listed here (SICARIO-MISSING-FRAMEWORK-MAP if absent).
# Remove this file to fall back to the default coarse control-map check.
# Supported keys: bsi-c5, ccm, eu-ai-act, fedramp, gdpr, hipaa, iso27001, nist-800-53, soc2, sox, ssdf
# Experimental keys: ai-rmf, owasp-asvs, pci-dss
# Experimental maps are thinner than the supported set. They are
# enforced exactly like any other key when listed here, but are never
# selected by a profile default -- only by explicit --frameworks.
ssdf
iso27001
Note what the appsec profile wrote here. Its framework table lists
ssdf, iso27001, and owasp-asvs — but owasp-asvs is
experimental-tier, so the implicit default filtered it out and only the two
supported keys landed. That is the tier rule working: an experimental map
never enters your enforced set unless you name it yourself (step 6).
2. See what is enforced, with tier labels
The init report states the effective selection and labels experimental
keys. A --dry-run re-run prints that report without writing anything:
sicario init . --profile appsec --dry-run | grep '^frameworks'
frameworks ssdf, iso27001
Later in this playbook, after gdpr and owasp-asvs are added, the same command reports the experimental key with an explicit label (step 6 shows that output). The label is the visible consequence of the tier: experimental enforcement is always something someone chose on purpose, and the report says so.
3. Add a framework to the selection
The selection file is the interface: add one key per line. Suppose the project now owes GDPR evidence:
printf 'gdpr\n' >> .sicario/frameworks.txt
tail -3 .sicario/frameworks.txt
ssdf
iso27001
gdpr
Editing the file directly is the supported path for an existing repository.
Re-running sicario init will not change an existing selection — it
preserves .sicario/frameworks.txt (brownfield-safe) and prints a notice
that the file differs from the profile defaults.
4. Run the gate and read the missing-map finding
This reference run's repository had pruned docs/compliance/control-maps/
down to the two enforced maps — a common hygiene move. Selecting gdpr
without its map present makes the gate fail:
sicario verify .
MEDIUM SICARIO-MISSING-FRAMEWORK-MAP docs/compliance/control-maps/gdpr-cpra-sicario.json: Selected framework 'gdpr' has no control map (gdpr-cpra-sicario.json)
sicario verify failed with 1 finding(s)
The command exits 1. Read the finding precisely:
- It fires once per selected key whose map is absent, at severity
medium. - The gate accepts the map at either
docs/compliance/control-maps/gdpr-cpra-sicario.json(wheresicario initinstalls maps) orcontrol_maps/gdpr-cpra-sicario.json. - Deselecting the key (removing the line) also clears the finding — but that changes what your project claims to enforce, so treat it as a compliance decision, not a fix.
One sharp edge, observed on this exact run: re-running sicario init .
does not restore a deleted map, because an existing
docs/compliance/control-maps/ directory is preserved as-is rather than
merged file-by-file. Restore the map explicitly, as in step 5.
5. Restore the missing map and re-run to green
The shipped maps live with your SicarioSpec installation. Ask the CLI where that is, then copy the map in:
MAPS="$(python3 -c "from sicario_cli.cli import CONTROL_MAPS_ROOT; print(CONTROL_MAPS_ROOT)")"
cp "$MAPS/gdpr-cpra-sicario.json" docs/compliance/control-maps/
sicario verify .
sicario verify passed
Exit code is 0. (If the map was previously committed, git checkout -- docs/compliance/control-maps/ is an equivalent fix.)
6. Enforce an experimental-tier map — explicitly
Experimental maps (ai-rmf, owasp-asvs, pci-dss) are fully
installable and, once listed, enforced exactly like any other key. The
only behavioral difference is that no profile default will ever add them
for you. To enforce OWASP ASVS:
printf 'owasp-asvs\n' >> .sicario/frameworks.txt
MAPS="$(python3 -c "from sicario_cli.cli import CONTROL_MAPS_ROOT; print(CONTROL_MAPS_ROOT)")"
cp "$MAPS/owasp-asvs-sicario.json" docs/compliance/control-maps/
sicario verify .
sicario verify passed
Now re-check the effective selection report from step 2:
sicario init . --profile appsec --dry-run | grep '^frameworks'
frameworks ssdf, iso27001, gdpr, owasp-asvs (experimental)
frameworks: existing .sicario/frameworks.txt preserved; it differs from this profile's defaults. Re-run with --force or edit the file to adopt them.
The (experimental) label follows the key everywhere the selection is
reported. Before enforcing an experimental map, read its tier rationale in
the control maps reference: experimental maps are
measurably thinner than the supported set (fewer controls resolved, coarser
evidence references), which is exactly why they require an explicit
opt-in.
7. State what this selection does — and does not — claim
Record, in the same change that edits .sicario/frameworks.txt (for
example in your docs/compliance/control-applicability.md), what the
selection means. This is a step, not a footnote, because the claim is easy
to overstate:
- Control maps are coarse traceability aids: they connect SicarioSpec evidence artifacts to framework control areas so an auditor can navigate from one to the other. They are not certification claims, and selecting a framework does not make the repository "compliant" with it.
- The gate checks completeness, not quality:
sicario verifyconfirms the selected map files are present (and the evidence artifacts exist); it does not judge whether your evidence would satisfy an assessor. - Experimental-tier maps carry both caveats more strongly — name them as experimental wherever you cite them.
Success check
You are done when all of the following hold:
cat .sicario/frameworks.txtlists exactly the framework keys your project owes evidence for — including any experimental keys you chose deliberately.sicario verify .exits0with noSICARIO-MISSING-FRAMEWORK-MAPfindings.sicario init . --profile <your-profile> --dry-run | grep '^frameworks'reports your selection, with(experimental)labels only on keys you named on purpose.- Your compliance docs state the traceability-not-certification boundary from step 7.
About the output quoted in this playbook
Every quoted block above is labeled verified (re-executable and compared
against a real run) or illustrative (representative). All output was
captured from a reference run on a net-new repository (refrun-frameworks,
run date 2026-07-28, SicarioSpec 0.6.0, module form
python3 -m sicario_cli.cli from the source checkout). Absolute paths in
captured output were normalized: the working directory to ~/work/<repo>
and the SicarioSpec installation to ~/tools/sicario-spec.