Threat Modeler (/mantis-threat-model)
System Goal
Security Architect. Synthesizes trust boundaries, attack surfaces, and attacker
profiles into THREAT_MODEL.md based exclusively on the entities and
architecture defined in the Knowledge Base (KB).
Command Definition
- Command:
/mantis-threat-model
- Description: Evaluates architectural perimeters, entry points, and trust
boundaries to construct the threat model.
- Arguments (all optional; absent → today's behavior):
--state_root <dir>: parent of workspace/. If absent, use
./workspace/... relative to the current directory. Locates
.mantis_state.json, the KB, and the archive directory.
--snapshot_id <id>: the SNAPSHOT_ID this pass is pinned to. Used ONLY as
the provenance value stamped into THREAT_MODEL.md (the KB_SNAPSHOT:
line). If absent, fall back to active_snapshot.snapshot_id from state; if
that is also absent or snapshot_pinned is false, the stamp is the literal
UNPINNED.
--snapshot_root <dir>: accepted for interface uniformity but NOT used —
this stage never reads target source (Block A step 0, findings-only role).
Input/Output Contract
- Reads:
workspace/.mantis_state.json — pass_number (to archive per pass) and,
for provenance only, active_snapshot
({root, snapshot_id, snapshot_pinned}). Both optional; absent → degraded
(see Backward-compat).
workspace/kb/architecture.md.
workspace/kb/entities/*.md.
- The EXISTING
workspace/kb/THREAT_MODEL.md from the previous pass, if
present — only its first KB_SNAPSHOT: line, for the freshness check in
step 0.
- Writes:
workspace/kb/THREAT_MODEL.md (first line is a KB_SNAPSHOT: provenance
header).
- Archives the previous
workspace/kb/THREAT_MODEL.md (if any) to
workspace/archive/kb/THREAT_MODEL_pass_${N}.md BEFORE overwriting.
- Preconditions:
- Knowledge Base files must exist and be populated.
- Idempotency Guarantee:
- Copies the prior
THREAT_MODEL.md (if any) to the pass archive, then
deterministically overwrites workspace/kb/THREAT_MODEL.md in-place.
Re-running a pass with an unchanged snapshot reproduces an equivalent model
plus a STALE banner (see step 0 and the final save step).
Instructions
LOCATOR RESOLUTION (before reading ANY target code or artifact):
0. ROLE: If this skill NEVER reads target source (report, calibrate, reflect),
you are a FINDINGS-ONLY stage: skip steps 2-6; still read active_snapshot from
state for provenance/annotation; NEVER stop merely because a code root is unset.
1. Determine CODE_ROOT, in this priority order:
a. If --target_root is passed on THIS invocation, CODE_ROOT = --target_root.
It is AUTHORITATIVE and OVERRIDES SNAPSHOT_ROOT and the state fallback
(used when a caller hands you a prepared tree, e.g. a patched shadow).
b. Else if --snapshot_root (or SNAPSHOT_ROOT) is passed, use it.
c. Else read state_root/workspace/.mantis_state.json (state_root from
--state_root if passed, else ./workspace/... relative to the current dir)
-> active_snapshot.root / .snapshot_id / .snapshot_pinned.
d. Else (no arg AND no readable active_snapshot): CODE_ROOT = current directory,
treat snapshot_pinned = false (MODE-OFF). Do NOT stop.
2. SENTINEL CHECK (only if snapshot_pinned is true AND you did NOT take path 1a):
verify CODE_ROOT/.mantis_snapshot_id exists and equals SNAPSHOT_ID. If missing
or different -> STOP "snapshot sentinel mismatch". (A --target_root tree (1a) is
deliberately mutated and is sentinel-EXEMPT.)
3. PATH FIELDS:
- SNAPSHOT-RELATIVE (read under CODE_ROOT): code_paths entries; plan target_files
that are file paths. Strip ONLY a trailing ":<digits>". A code_paths entry
containing "://" is a URL/endpoint, NOT a file read. A code_paths entry that is
NOT of the form <existing-path>:<integer> is a non-source LOCATOR
(symbol/offset/endpoint): only check that the artifact/symbol exists; skip ALL
line-range and line-existence logic.
- STATE-RELATIVE (read/write under state_root/workspace, NEVER prefix CODE_ROOT):
kb_references, repro_file_path, reattack_file_path, helper scripts, report
files, and all state/findings JSON.
4. Never WRITE under CODE_ROOT when snapshot_pinned is true. Any command that
compiles, generates, or writes artifacts MUST run in a PRIVATE SHADOW copy
(mktemp -d from CODE_ROOT), never with cwd=CODE_ROOT. Read-only inspection may
cd into CODE_ROOT.
5. VCS-METADATA CARVE-OUT: history-log extraction and any VCS diff/blame command
run in the LIVE repository root (which still has .git/.hg/.repo), NOT CODE_ROOT
(the snapshot copy strips VCS metadata). Do NOT stop merely because CODE_ROOT
lacks .git/.hg/.repo.
6. Every shell command uses ABSOLUTE paths and sets its own working directory on
that call. Do NOT assume the working directory persists between calls.
Role for this stage (findings-only / KB-only). /mantis-threat-model NEVER
reads target source. Every input it uses — architecture.md, entities/*.md,
the prior THREAT_MODEL.md, and .mantis_state.json — is STATE-RELATIVE (read
under state_root/workspace, NEVER under CODE_ROOT). This stage therefore
takes Block A step 0's FINDINGS-ONLY path: SKIP Block A steps 2–6, but STILL
read active_snapshot from state for provenance, and NEVER stop merely because
a code root is unset or unpinned.
Maintain a high-level Threat Model that explicitly defines who the attackers
are and where they can interact with the system, relying on the pre-processed
entities in the KB.
Execute the threat modeling process as follows:
Resolve Snapshot Provenance, Freshness, and Archive the Prior Model:
a. Compute CUR (the snapshot this threat model is stamped against):
- If
--snapshot_id was passed → CUR = that value.
- Else if state
active_snapshot.snapshot_pinned is true → CUR =
active_snapshot.snapshot_id.
- Else →
CUR = the literal UNPINNED (degraded / today's behavior).
b. Compute PREV_TM (what the last model was stamped against): read the
FIRST line matching ^KB_SNAPSHOT: in the existing
workspace/kb/THREAT_MODEL.md; its value (trimmed) is PREV_TM. If the file
is absent, has no such line, or the value is empty → PREV_TM = the empty
string "".
c. SYNC-DELTA DECISION (mechanical; exact string equality, no fuzzy
compare):
CUR == "UNPINNED" → SYNC_OCCURRED = true (degraded: always re-derive).
- else
PREV_TM == "" → SYNC_OCCURRED = true (first run / legacy KB).
- else
PREV_TM != CUR → SYNC_OCCURRED = true (a sync or dirty edit
advanced the snapshot).
- else (
PREV_TM == CUR) → SYNC_OCCURRED = false (snapshot unchanged since
the last model).
d. Archive the prior model (per pass), so overwrite is non-destructive:
- Resolve
N: read "pass_number" from workspace/.mantis_state.json. If
missing or invalid, scan workspace/archive/ for folders matching
findings_pass_N or loopN_findings and set N = max_found + 1,
defaulting to 1 if no archives exist. (Same rule the architecture stage
uses.)
- If
workspace/kb/THREAT_MODEL.md exists: ensure workspace/archive/kb/
exists (mkdir -p workspace/archive/kb/) and COPY (do NOT move) the file
to workspace/archive/kb/THREAT_MODEL_pass_${N}.md. You will overwrite the
live file in step 3. If the file does not exist, skip the copy.
- All paths in this step are STATE-RELATIVE (under
state_root/workspace);
NEVER prefix CODE_ROOT.
Carry CUR, SYNC_OCCURRED, and N forward into steps 1–3 and the final
save.
Read the Synthesized KB:
- Read
workspace/kb/architecture.md to understand the system's data flows
and high-level design.
- Read the files inside
workspace/kb/entities/ to understand the individual
components and any historical constraints or vulnerability patterns mapped
to them by the /mantis-architecture stage.
Analyze Trust Boundaries:
- Evaluate the entities to determine where trust boundaries lie. Where does
untrusted data cross into a trusted context? Which components are exposed
to external input?
Synthesize the Threat Model:
- Write a comprehensive, structured Markdown file and save it directly to
workspace/kb/THREAT_MODEL.md (overwriting the old one).
- Token Optimization: Use your file-writing tools to write the file
directly to disk; do not output the threat model text in your chat
response.
Include the following sections to ensure downstream planning agents have
sufficient context:
System Overview Summary: A concise summary derived from
architecture.md.
Deployment Intent: State exactly one of Intent: PRODUCTION or
Intent: SAMPLE_OR_TEST_ONLY. This verdict has a large blast radius:
/mantis-critic marks EVERY finding SAMPLE_OR_TEST (dismissing the whole
pass) the instant it reads Intent: SAMPLE_OR_TEST_ONLY. So
SAMPLE_OR_TEST_ONLY is FAIL-CLOSED behind a mechanical checklist:
PRODUCTION-SIGNAL CHECKLIST — you may write Intent: SAMPLE_OR_TEST_ONLY
ONLY IF ALL five checks are TRUE. If ANY is FALSE, or the KB is silent on /
you are unsure about any one of them, you MUST write
Intent: PRODUCTION.
- NO entity in
workspace/kb/entities/*.md is classified CRITICAL or
STANDARD availability (either implies an operated/production service).
architecture.md names NO externally-reachable service, daemon, server,
API, or network endpoint, AND NO deployment/packaging descriptor
(systemd, Dockerfile/docker, kubernetes/k8s/helm, load balancer,
cloud/VPC/IaC, CI/CD publish or release).
- The KB describes NO installable/publishable package or runtime
entrypoint (e.g.,
console_scripts/entry_points, a main()/service
binary, a published library or package manifest).
- EVERY component/path referenced in the KB lies exclusively under
test/sample directories — its path contains one of
test, tests,
example, examples, sample, samples, tutorial, demo, docs,
fixtures — and NONE lie under production source roots such as src,
lib, pkg, internal, cmd, app, server, or core.
- NO entity documents a real (non-mock, non-test) untrusted external input
crossing a trust boundary into privileged/production logic.
After a sync (SYNC_OCCURRED == true from step 0) you MUST re-run this
checklist from scratch against the CURRENT KB and MUST NOT inherit a prior
Intent: verdict — a sync can add production code to a tree that was
previously sample-only, which would otherwise silently dismiss every new
finding.
Trust Boundaries: Clear, rigorous definitions of where untrusted inputs
meet internal trusted states. Reference the specific entities (e.g.,
[Auth Module](entities/auth_module.md)).
Threat Actors & Vectors: Define the profiles of potential attackers
(e.g., Unauthenticated Network Attacker, Malicious Local User) and the
specific boundaries they can reach.
High-Risk Assets: The data, execution privileges, or availability
targets an attacker wants to compromise. For availability targets,
classify them into one of these Availability Tiers based on the KB:
CRITICAL: 24/7 immediate operational impact if disrupted.
STANDARD: Important operations; short downtime is tolerable.
LOW_CRITICALITY: Non-blocking utilities; disruption is a mild
annoyance.
Stamp and save the model:
- The FIRST line of
workspace/kb/THREAT_MODEL.md MUST be the provenance stamp
KB_SNAPSHOT: followed by CUR (from step 0) — e.g. KB_SNAPSHOT: <CUR>,
or KB_SNAPSHOT: UNPINNED in degraded mode. The next pass reads this back as
PREV_TM, and mantis-critic reads it as a KB freshness check.
- If
SYNC_OCCURRED == false (snapshot unchanged since the last model): you MAY
reuse the prior model's substance, but you MUST insert this STALE banner as
the line immediately AFTER the KB_SNAPSHOT: line:
> STALE: Threat model NOT re-evaluated this pass; carried unchanged from snapshot <CUR>.
If SYNC_OCCURRED == true: do NOT emit the STALE banner — you re-derived
every section fresh this pass, including the Deployment-Intent checklist.
- Save directly to
workspace/kb/THREAT_MODEL.md (STATE-RELATIVE; the prior
file was already copied to the pass archive in step 0d). Use your file-writing
tools; do not print the model to chat. When complete, notify the user.
1---2name: mantis-threat-model3description: Synthesizes trust boundaries, attack surfaces, and attacker profiles into a living threat model. Use as Stage B of the Knowledge Base generation process, reading architecture and entity definitions from the KB. Don't use for analyzing source code or extracting raw learnings from JSONL files.4---5
6# Threat Modeler (/mantis-threat-model)
7
8## System Goal
9
10Security Architect. Synthesizes trust boundaries, attack surfaces, and attacker
11profiles into `THREAT_MODEL.md` based exclusively on the entities and
12architecture defined in the Knowledge Base (KB).
13
14## Command Definition
15
16- **Command:** `/mantis-threat-model`
17- **Description:** Evaluates architectural perimeters, entry points, and trust
18 boundaries to construct the threat model.
19- **Arguments (all optional; absent → today's behavior):**
20 - `--state_root <dir>`: parent of `workspace/`. If absent, use
21 `./workspace/...` relative to the current directory. Locates
22 `.mantis_state.json`, the KB, and the archive directory.
23 - `--snapshot_id <id>`: the `SNAPSHOT_ID` this pass is pinned to. Used ONLY as
24 the provenance value stamped into `THREAT_MODEL.md` (the `KB_SNAPSHOT:`
25 line). If absent, fall back to `active_snapshot.snapshot_id` from state; if
26 that is also absent or `snapshot_pinned` is false, the stamp is the literal
27 `UNPINNED`.
28 - `--snapshot_root <dir>`: accepted for interface uniformity but NOT used —
29 this stage never reads target source (Block A step 0, findings-only role).
30
31## Input/Output Contract
32
33- **Reads**:
34 - `workspace/.mantis_state.json` — `pass_number` (to archive per pass) and,
35 for provenance only, `active_snapshot`
36 (`{root, snapshot_id, snapshot_pinned}`). Both optional; absent → degraded
37 (see Backward-compat).
38 - `workspace/kb/architecture.md`.
39 - `workspace/kb/entities/*.md`.
40 - The EXISTING `workspace/kb/THREAT_MODEL.md` from the previous pass, if
41 present — only its first `KB_SNAPSHOT:` line, for the freshness check in
42 step 0.
43- **Writes**:
44 - `workspace/kb/THREAT_MODEL.md` (first line is a `KB_SNAPSHOT:` provenance
45 header).
46 - Archives the previous `workspace/kb/THREAT_MODEL.md` (if any) to
47 `workspace/archive/kb/THREAT_MODEL_pass_${N}.md` BEFORE overwriting.
48- **Preconditions**:
49 - Knowledge Base files must exist and be populated.
50- **Idempotency Guarantee**:
51 - Copies the prior `THREAT_MODEL.md` (if any) to the pass archive, then
52 deterministically overwrites `workspace/kb/THREAT_MODEL.md` in-place.
53 Re-running a pass with an unchanged snapshot reproduces an equivalent model
54 plus a `STALE` banner (see step 0 and the final save step).
55
56## Instructions
57
58```
59LOCATOR RESOLUTION (before reading ANY target code or artifact):
600. ROLE: If this skill NEVER reads target source (report, calibrate, reflect),
61 you are a FINDINGS-ONLY stage: skip steps 2-6; still read active_snapshot from
62 state for provenance/annotation; NEVER stop merely because a code root is unset.
631. Determine CODE_ROOT, in this priority order:
64 a. If --target_root is passed on THIS invocation, CODE_ROOT = --target_root.
65 It is AUTHORITATIVE and OVERRIDES SNAPSHOT_ROOT and the state fallback
66 (used when a caller hands you a prepared tree, e.g. a patched shadow).
67 b. Else if --snapshot_root (or SNAPSHOT_ROOT) is passed, use it.
68 c. Else read state_root/workspace/.mantis_state.json (state_root from
69 --state_root if passed, else ./workspace/... relative to the current dir)
70 -> active_snapshot.root / .snapshot_id / .snapshot_pinned.
71 d. Else (no arg AND no readable active_snapshot): CODE_ROOT = current directory,
72 treat snapshot_pinned = false (MODE-OFF). Do NOT stop.
732. SENTINEL CHECK (only if snapshot_pinned is true AND you did NOT take path 1a):
74 verify CODE_ROOT/.mantis_snapshot_id exists and equals SNAPSHOT_ID. If missing
75 or different -> STOP "snapshot sentinel mismatch". (A --target_root tree (1a) is
76 deliberately mutated and is sentinel-EXEMPT.)
773. PATH FIELDS:
78 - SNAPSHOT-RELATIVE (read under CODE_ROOT): code_paths entries; plan target_files
79 that are file paths. Strip ONLY a trailing ":<digits>". A code_paths entry
80 containing "://" is a URL/endpoint, NOT a file read. A code_paths entry that is
81 NOT of the form <existing-path>:<integer> is a non-source LOCATOR
82 (symbol/offset/endpoint): only check that the artifact/symbol exists; skip ALL
83 line-range and line-existence logic.
84 - STATE-RELATIVE (read/write under state_root/workspace, NEVER prefix CODE_ROOT):
85 kb_references, repro_file_path, reattack_file_path, helper scripts, report
86 files, and all state/findings JSON.
874. Never WRITE under CODE_ROOT when snapshot_pinned is true. Any command that
88 compiles, generates, or writes artifacts MUST run in a PRIVATE SHADOW copy
89 (mktemp -d from CODE_ROOT), never with cwd=CODE_ROOT. Read-only inspection may
90 cd into CODE_ROOT.
915. VCS-METADATA CARVE-OUT: history-log extraction and any VCS diff/blame command
92 run in the LIVE repository root (which still has .git/.hg/.repo), NOT CODE_ROOT
93 (the snapshot copy strips VCS metadata). Do NOT stop merely because CODE_ROOT
94 lacks .git/.hg/.repo.
956. Every shell command uses ABSOLUTE paths and sets its own working directory on
96 that call. Do NOT assume the working directory persists between calls.
97```
98
99**Role for this stage (findings-only / KB-only).** `/mantis-threat-model` NEVER
100reads target source. Every input it uses — `architecture.md`, `entities/*.md`,
101the prior `THREAT_MODEL.md`, and `.mantis_state.json` — is STATE-RELATIVE (read
102under `state_root/workspace`, NEVER under `CODE_ROOT`). This stage therefore
103takes Block A step 0's FINDINGS-ONLY path: SKIP Block A steps 2–6, but STILL
104read `active_snapshot` from state for provenance, and NEVER stop merely because
105a code root is unset or unpinned.
106
107Maintain a high-level Threat Model that explicitly defines *who* the attackers
108are and *where* they can interact with the system, relying on the pre-processed
109entities in the KB.
110
111Execute the threat modeling process as follows:
112
1130. **Resolve Snapshot Provenance, Freshness, and Archive the Prior Model:**
114
115 a. **Compute `CUR` (the snapshot this threat model is stamped against):**
116
117 - If `--snapshot_id` was passed → `CUR` = that value.
118 - Else if state `active_snapshot.snapshot_pinned` is true → `CUR` =
119 `active_snapshot.snapshot_id`.
120 - Else → `CUR` = the literal `UNPINNED` (degraded / today's behavior).
121
122 b. **Compute `PREV_TM` (what the last model was stamped against):** read the
123 FIRST line matching `^KB_SNAPSHOT:` in the existing
124 `workspace/kb/THREAT_MODEL.md`; its value (trimmed) is `PREV_TM`. If the file
125 is absent, has no such line, or the value is empty → `PREV_TM` = the empty
126 string `""`.
127
128 c. **SYNC-DELTA DECISION (mechanical; exact string equality, no fuzzy
129 compare):**
130
131 - `CUR == "UNPINNED"` → `SYNC_OCCURRED = true` (degraded: always re-derive).
132 - else `PREV_TM == ""` → `SYNC_OCCURRED = true` (first run / legacy KB).
133 - else `PREV_TM != CUR` → `SYNC_OCCURRED = true` (a sync or dirty edit
134 advanced the snapshot).
135 - else (`PREV_TM == CUR`) → `SYNC_OCCURRED = false` (snapshot unchanged since
136 the last model).
137
138 d. **Archive the prior model (per pass), so overwrite is non-destructive:**
139
140 - Resolve `N`: read `"pass_number"` from `workspace/.mantis_state.json`. If
141 missing or invalid, scan `workspace/archive/` for folders matching
142 `findings_pass_N` or `loopN_findings` and set `N = max_found + 1`,
143 defaulting to `1` if no archives exist. (Same rule the architecture stage
144 uses.)
145 - If `workspace/kb/THREAT_MODEL.md` exists: ensure `workspace/archive/kb/`
146 exists (`mkdir -p workspace/archive/kb/`) and COPY (do NOT move) the file
147 to `workspace/archive/kb/THREAT_MODEL_pass_${N}.md`. You will overwrite the
148 live file in step 3. If the file does not exist, skip the copy.
149 - All paths in this step are STATE-RELATIVE (under `state_root/workspace`);
150 NEVER prefix `CODE_ROOT`.
151
152 Carry `CUR`, `SYNC_OCCURRED`, and `N` forward into steps 1–3 and the final
153 save.
154
1551. **Read the Synthesized KB:**
156
157 - Read `workspace/kb/architecture.md` to understand the system's data flows
158 and high-level design.
159 - Read the files inside `workspace/kb/entities/` to understand the individual
160 components and any historical constraints or vulnerability patterns mapped
161 to them by the `/mantis-architecture` stage.
162
1632. **Analyze Trust Boundaries:**
164
165 - Evaluate the entities to determine where trust boundaries lie. Where does
166 untrusted data cross into a trusted context? Which components are exposed
167 to external input?
168
1693. **Synthesize the Threat Model:**
170
171 - Write a comprehensive, structured Markdown file and save it directly to
172 `workspace/kb/THREAT_MODEL.md` (overwriting the old one).
173 - **Token Optimization:** Use your file-writing tools to write the file
174 directly to disk; do not output the threat model text in your chat
175 response.
176
177 Include the following sections to ensure downstream planning agents have
178 sufficient context:
179
180 - **System Overview Summary:** A concise summary derived from
181 `architecture.md`.
182
183 - **Deployment Intent:** State exactly one of `Intent: PRODUCTION` or
184 `Intent: SAMPLE_OR_TEST_ONLY`. This verdict has a large blast radius:
185 `/mantis-critic` marks EVERY finding `SAMPLE_OR_TEST` (dismissing the whole
186 pass) the instant it reads `Intent: SAMPLE_OR_TEST_ONLY`. So
187 `SAMPLE_OR_TEST_ONLY` is FAIL-CLOSED behind a mechanical checklist:
188
189 **PRODUCTION-SIGNAL CHECKLIST — you may write `Intent: SAMPLE_OR_TEST_ONLY`
190 ONLY IF ALL five checks are TRUE. If ANY is FALSE, or the KB is silent on /
191 you are unsure about any one of them, you MUST write
192 `Intent: PRODUCTION`.**
193
194 1. NO entity in `workspace/kb/entities/*.md` is classified `CRITICAL` or
195 `STANDARD` availability (either implies an operated/production service).
196 2. `architecture.md` names NO externally-reachable service, daemon, server,
197 API, or network endpoint, AND NO deployment/packaging descriptor
198 (systemd, Dockerfile/`docker`, kubernetes/`k8s`/helm, load balancer,
199 cloud/VPC/IaC, CI/CD publish or release).
200 3. The KB describes NO installable/publishable package or runtime
201 entrypoint (e.g., `console_scripts`/`entry_points`, a `main()`/service
202 binary, a published library or package manifest).
203 4. EVERY component/path referenced in the KB lies exclusively under
204 test/sample directories — its path contains one of `test`, `tests`,
205 `example`, `examples`, `sample`, `samples`, `tutorial`, `demo`, `docs`,
206 `fixtures` — and NONE lie under production source roots such as `src`,
207 `lib`, `pkg`, `internal`, `cmd`, `app`, `server`, or `core`.
208 5. NO entity documents a real (non-mock, non-test) untrusted external input
209 crossing a trust boundary into privileged/production logic.
210
211 **After a sync (`SYNC_OCCURRED == true` from step 0) you MUST re-run this
212 checklist from scratch against the CURRENT KB and MUST NOT inherit a prior
213 `Intent:` verdict** — a sync can add production code to a tree that was
214 previously sample-only, which would otherwise silently dismiss every new
215 finding.
216
217 - **Trust Boundaries:** Clear, rigorous definitions of where untrusted inputs
218 meet internal trusted states. Reference the specific entities (e.g.,
219 `[Auth Module](entities/auth_module.md)`).
220
221 - **Threat Actors & Vectors:** Define the profiles of potential attackers
222 (e.g., Unauthenticated Network Attacker, Malicious Local User) and the
223 specific boundaries they can reach.
224
225 - **High-Risk Assets:** The data, execution privileges, or availability
226 targets an attacker wants to compromise. **For availability targets,
227 classify them into one of these Availability Tiers based on the KB:**
228
229 - `CRITICAL`: 24/7 immediate operational impact if disrupted.
230 - `STANDARD`: Important operations; short downtime is tolerable.
231 - `LOW_CRITICALITY`: Non-blocking utilities; disruption is a mild
232 annoyance.
233
234Stamp and save the model:
235
236- The FIRST line of `workspace/kb/THREAT_MODEL.md` MUST be the provenance stamp
237 `KB_SNAPSHOT: ` followed by `CUR` (from step 0) — e.g. `KB_SNAPSHOT: <CUR>`,
238 or `KB_SNAPSHOT: UNPINNED` in degraded mode. The next pass reads this back as
239 `PREV_TM`, and `mantis-critic` reads it as a KB freshness check.
240- If `SYNC_OCCURRED == false` (snapshot unchanged since the last model): you MAY
241 reuse the prior model's substance, but you MUST insert this STALE banner as
242 the line immediately AFTER the `KB_SNAPSHOT:` line:
243 `> STALE: Threat model NOT re-evaluated this pass; carried unchanged from snapshot <CUR>.`
244 If `SYNC_OCCURRED == true`: do NOT emit the STALE banner — you re-derived
245 every section fresh this pass, including the Deployment-Intent checklist.
246- Save directly to `workspace/kb/THREAT_MODEL.md` (STATE-RELATIVE; the prior
247 file was already copied to the pass archive in step 0d). Use your file-writing
248 tools; do not print the model to chat. When complete, notify the user.