Engine CLI

Reference for attacktree.sh, the deterministic AttackTree engine: global options, feature resolution, every subcommand with its flags, and exit codes.

The engine is scripts/python/attacktree.py. Call it through the wrappers scripts/bash/attacktree.sh or scripts/powershell/attacktree.ps1, which find a Python with PyYAML or fall back to uv. In an installed project the path is .specify/extensions/attacktree/scripts/bash/attacktree.sh.

attacktree.sh [--repo PATH] [--feature-dir PATH] <subcommand> [options]

# Global options

OptionDefault
--repo PATHThe nearest parent directory containing .specify/ or .git.
--feature-dir PATHSPECIFY_FEATURE, then the directory under specs/ named like the current git branch, then the newest specs/*/spec.md.

Global options come before the subcommand.

# Subcommands

# paths

Prints the resolved repository, feature, and artifact paths, whether each artifact exists, and how the feature was found. --json for machine-readable output. Exit code 1 if no feature is found.

# init

Creates an empty attack-tree.yaml with source hashes and the configured baseline. --project-id, --name, and --force to overwrite an existing tree.

# seed

Derives assets and candidate goals from an Open Threat Model file. --otm FILE (default: model.otm from the configuration) and --output FILE.

# validate FILE

Validates a tree against the JSON Schema, the reference rules, and the tree structure. --json for machine-readable output. Exit code 1 on errors.

# merge --incoming FILE

Merges an agent-written tree into attack-tree.yaml: it keeps ids and human-owned fields, retires what disappeared, records source hashes, sorts deterministically, and validates. --dry-run prints the result without writing. --allow-invalid writes despite errors; avoid it.

# render

Writes attack-tree.md and the CR-### block in spec.md. --no-markdown and --no-spec skip either for one run.

# check

Runs checks A1 to A16. --format md|json|sarif, --output FILE, --persist (writes security/attacktree-check-report.md), --strict, --enforcement warn|strict. Exit code 0 when nothing is above MEDIUM, 1 for HIGH (or MEDIUM in strict mode), 2 for CRITICAL.

# simulate

Evaluates the tree. --format md|json, --output FILE, --persist (writes security/attacktree-simulation.{md,json}), --scenario none|current|verified|planned|all, --apply IDS and --remove IDS (comma-separated control ids, what-if only), --iterations N, --seed N, --no-monte-carlo. Refuses to run on an invalid tree. Exit code 1 while a goal is at risk.block_on residual risk without a decision.

# converge-scan

Collects evidence facts per requirement as JSON: tasks, test files, touchpoints, validation steps, residual risk with verified controls, and check findings. --output FILE.

# converge-apply --verdicts FILE

Records verdicts, rolls statuses up, writes the convergence report, and appends remediation tasks. --only CR-001,CR-002 judges only those requirements; the others keep their last verdict. --commit SHA overrides the detected commit. --no-render skips re-rendering attack-tree.md. Exit code 0 when converged, 1 otherwise.

# Environment

VariableEffect
SPECIFY_FEATUREFeature directory name under specs/.
SPECKIT_ATTACKTREE_ENFORCEMENTOverrides enforcement.
SPECKIT_ATTACKTREE_PROFILESOverrides profiles (comma-separated).
SPECKIT_ATTACKTREE_SCENARIOOverrides risk.scenario.