Playbook: Adopt SicarioSpec in a Brownfield Repository
Scenario
You maintain a repository that already has governance: a project constitution,
Spec Kit templates, and agent-instruction files such as CLAUDE.md. You want
SicarioSpec's gate and evidence without losing a line of what you already
wrote. This playbook walks the overlay-not-clobber contract end to end:
preview with --dry-run, adopt for real, inspect what was merged and what was
preserved, confirm the backups can never be committed, and re-run init to
see that adoption converges to a no-op.
Intended reader: an engineer adopting SicarioSpec into an existing repository. No prior SicarioSpec experience is assumed beyond having the CLI installed.
Output conventions
Every quoted output block in this playbook carries a machine-readable marker
declaring it verified or illustrative:
- verified — captured from the reference run named in this page's front
matter and re-executable as-is. The only rewrites applied are the documented
normalizations listed in the marker:
paths(the reference-run directory is shown as~/refrun-rules/brownfield-app, and the SicarioSpec install location as<install-root>). - illustrative — representative of the shape you will see, visibly labeled
as such, used where output contains environment-dependent values (absolute
paths, backup timestamps, your
specifyversion).
Every step in this playbook is a terminal interaction, captured as text per the terminal-text capture class. No step surfaces a graphical view, so this playbook carries no screenshots (stated per the visual-asset policy).
Prerequisites and starting state
- Python 3.9+ and SicarioSpec 0.6.0. Commands below use the module form
python3 -m sicario_cli.cli, which works on every install; if thesicariocommand is on your PATH,sicario init/sicario verifyare equivalent. git, and a POSIX shell (bash or zsh) on macOS or Linux. On Windows, use WSL; native path separators and prompts will differ.
The starting state is a git repository with pre-existing governance. To
reconstruct it exactly, the reference run seeded a repository containing
README.md, src/app.py, a .gitignore (__pycache__/, *.pyc), and
these three governance files, all committed:
.specify/memory/constitution.md — the project's own constitution:
# payments-api Constitution
## Principle I — Boring Technology
We choose proven components over novel ones.
## Principle II — Reviewed Changes
Every change lands through a reviewed pull request.
.specify/templates/spec-template.md — the project's own minimal template:
# Feature Spec: [NAME]
## Problem
## Approach
## Rollout
and CLAUDE.md — agent instructions:
Prefer small, reviewable diffs. Never commit generated artifacts.
The remaining seed files (their content is not asserted by anything below):
printf '# payments-api\n' > README.md
mkdir -p src
printf 'def main():\n pass\n' > src/app.py
printf '__pycache__/\n*.pyc\n' > .gitignore
Steps
1. Preview the adoption with --dry-run
Always preview first. The dry run detects your existing governance, chooses a per-file plan, and writes nothing.
python3 -m sicario_cli.cli init . --profile public-core --dry-run
Illustrative output — excerpted; absolute paths and your specify version
vary by environment.
target ~/refrun-rules/brownfield-app
specify specify 0.11.8
integration claude
presets sicario-core, sicario-docs
detected existing governance: constitution=['.specify/memory/constitution.md']; templates=['.specify/templates/spec-template.md']; instructions=['CLAUDE.md']
mode: brownfield-safe (merge/overlay/preserve)
append ignore rule *.sicario-bak.* to ~/refrun-rules/brownfield-app/.gitignore
copy <install-root>/presets/sicario-core -> ~/refrun-rules/brownfield-app/.specify/presets/sicario-core
...
overlay ~/refrun-rules/brownfield-app/.specify/memory/constitution.md
SicarioSpec adoption report (dry-run preview — nothing written)
---------------------------------------------------------------
[merged-overlaid] ~/refrun-rules/brownfield-app/.gitignore — appended ignore rule *.sicario-bak.*
[created] ~/refrun-rules/brownfield-app/.specify/presets/sicario-core
[merged-overlaid] ~/refrun-rules/brownfield-app/.specify/templates/spec-template.md — appended overlay
[merged-overlaid] ~/refrun-rules/brownfield-app/.specify/memory/constitution.md — appended overlay
[merged-overlaid] ~/refrun-rules/brownfield-app/CLAUDE.md — appended overlay
...
summary: 33 created, 4 merged-overlaid
dry-run complete; no files written
Read the plan through the three per-file states:
- created — the file does not exist in your repository; SicarioSpec will write it new. Nothing of yours is involved.
- merged-overlaid — the file exists and SicarioSpec knows how to extend it additively: your content stays verbatim, a clearly delimited overlay block is appended, and a backup is taken first.
- preserved — the file exists and SicarioSpec cannot safely merge it, so
it is left untouched and reported. (You will see this state on re-runs in
step 5;
--forceis the explicit opt-in to full overwrite instead, and it still takes backups first.)
Note the detection line: your constitution, your template, and CLAUDE.md
were all found, and the mode switched to brownfield-safe (merge/overlay/preserve). In an empty directory the same command reports
mode: greenfield (no existing governance detected).
2. Adopt for real
python3 -m sicario_cli.cli init . --profile public-core
Illustrative output — final lines shown; the full report matches the dry-run plan.
summary: 33 created, 4 merged-overlaid
SicarioSpec initialized at ~/refrun-rules/brownfield-app
Next: cd into the project and run `sicario verify`.
3. Inspect the overlay: your content is untouched above the markers
sed -n '1,16p' .specify/memory/constitution.md
# payments-api Constitution
## Principle I — Boring Technology
We choose proven components over novel ones.
## Principle II — Reviewed Changes
Every change lands through a reviewed pull request.
<!-- BEGIN SICARIO-SPEC OVERLAY (additive; do not edit by hand) -->
## SicarioSpec Governance Overlay (Additive)
This section was appended by `sicario init`/`apply` as an ADDITIVE governance
overlay. Your existing constitution above is unchanged and remains authoritative.
This overlay is SUBORDINATE to the existing principles above and to `CLAUDE.md`. Where any conflict exists, the project's own principles and `mission.md` (or equivalent project-supremacy clause) WIN.
Your constitution is byte-for-byte intact above the
BEGIN SICARIO-SPEC OVERLAY marker, and the overlay itself states that it is
subordinate to your existing principles and to the instruction files it
detected (CLAUDE.md here). The overlay ends with an
<!-- END SICARIO-SPEC OVERLAY --> marker:
grep -n "SICARIO-SPEC OVERLAY" .specify/memory/constitution.md
9:<!-- BEGIN SICARIO-SPEC OVERLAY (additive; do not edit by hand) -->
39:<!-- END SICARIO-SPEC OVERLAY -->
The same marker pair delimits the overlays appended to CLAUDE.md and
.specify/templates/spec-template.md — run the same grep -n against each
to see them.
4. Backups exist — and cannot be committed
Every merged file was backed up first, as a timestamped sibling:
ls .specify/memory/
Illustrative output — the UTC timestamp in the backup name is taken at run time.
constitution.md
constitution.md.sicario-bak.20260728T204506Z
Backups are verbatim copies of your pre-existing files, which may contain
things that were never meant to be committed. So before the first backup was
taken, init appended an ignore rule to your .gitignore (your existing
entries untouched):
cat .gitignore
__pycache__/
*.pyc
# SicarioSpec timestamped backups (may contain pre-existing secrets)
*.sicario-bak.*
Confirm git actually ignores them — git check-ignore -v names the deciding
rule, and no backup appears in git status:
git check-ignore -v .specify/memory/constitution.md.sicario-bak.*
git status --short | grep sicario-bak
Illustrative output — timestamped file name varies; the second command prints nothing (and exits 1) because no backup is unignored.
.gitignore:5:*.sicario-bak.* .specify/memory/constitution.md.sicario-bak.20260728T204506Z
init is careful here: if your .gitignore already contains the rule it is
left alone, and if a later negation (!something.sicario-bak...) re-includes
backups, the rule is re-appended so the last matching pattern wins again.
5. Re-run to confirm adoption converges
Run the same init command again:
python3 -m sicario_cli.cli init . --profile public-core
Illustrative output — summary lines shown.
gitignore already ignores *.sicario-bak.*
overlay already present in ~/refrun-rules/brownfield-app/.specify/templates/spec-template.md
...
summary: 2 merged-overlaid, 35 preserved
Nothing you own is touched again: files with the overlay marker report
overlay already present, directories report skip existing, and generated
files report preserve existing. One wrinkle, reported honestly because the
reference run observed it: the second run appends the overlay marker block to
plan-template.md and tasks-template.md — the two templates the first
run created without markers — which is why this run still shows
2 merged-overlaid. From the second run onward the state is stable; a third
run is a pure no-op:
Illustrative output — third run's summary line.
summary: 37 preserved
No new backups are taken on a converged re-run.
6. Run the gate
python3 -m sicario_cli.cli verify .
sicario verify passed
Exit code 0. The adopted repository passes because init created every
document the shipped rules require (threat model, risk registers, data
classification, control maps, and the rest) while preserving yours.
Success check
You are done when all of the following hold:
python3 -m sicario_cli.cli verify .printssicario verify passedand exits0.git diffon.specify/memory/constitution.md,CLAUDE.md, and.specify/templates/spec-template.mdshows only appendedSICARIO-SPEC OVERLAYblocks (plus the.gitignorerule) — none of your original lines changed.git status --short | grep sicario-bakprints nothing: every backup exists on disk but is uncommittable.- Re-running
initreportspreserved/overlay already presentrather than taking new backups.
Further reading
- Playbook: add a custom project rule — your first project-owned gate in the adopted repository.
- Playbook: override a shipped rule — narrowing shipped rules to fit a brownfield layout, with the evidence that records it.
- Declarative rule engine — reference for everything the gate enforces.