| name | tm7-modeling |
| description | Create, import, preservation-edit, convert, and validate Microsoft Threat Modeling Tool .tm7 files through a constrained JSON interchange format and bundled PowerShell scripts. Use when an agent must author or change a TM7 threat-model diagram, trust boundaries, processes, external interactors, data stores, data flows, or explicit threats; safely parse an existing TM7 to editable JSON and produce a new TM7 without discarding opaque source metadata; inspect a TM7 file; or prove that a file loads through Microsoft's installed serializer and ObjectModel. Supports one-diagram models and fails rather than silently degrading unsupported native shapes. |
TM7 Modeling
Treat the JSON specification as the editable source and .tm7 as compiled output. Never hand-author or patch TM7 XML when the bundled converter can express the change. For a necessary one-off edit to an unmodeled field, read references/direct-xml-editing.md before touching XML and follow its decision gate, preservation rules, and required Microsoft validation.
Set up the workflow
Run the scripts on Windows with PowerShell 7.x (pwsh.exe). Resolve the directory containing this SKILL.md and keep it in a task-specific variable such as $tm7SkillRoot.
Before authoring or editing JSON, read references/json-contract.md. Open references/tm7-spec.schema.json when exact fields or enum values are needed. Read references/format-notes.md only for compatibility, reverse-engineering, or failure diagnosis.
Use assets/example.tm7.json as a contract example, not as content to leave in a new model. Create the destination JSON early and replace the example identity, components, flows, and threats in the first authoring pass. Do not modify assets/EmptyDiagram.tm7; it is the compiler template for new models.
Choose the workflow
Create a new model
- Inspect the target system or repository before drawing. Identify entry points, trust transitions, privileged operations, durable data, dependency/update paths, external inputs and outputs, and the evidence that supports each modeled component.
- Create a task-specific
.tm7.json from the contract example. Immediately replace all example identity and content; never deliver a lightly edited sample model.
- Model the security-relevant components and threats. Use
layout_mode: "auto", omit tm7_guid, bounds, and route, and use stable semantic IDs.
- Validate with
Test-Tm7.ps1 -Kind Spec. Read the returned Layout object. Fix element overlaps and long labels; investigate label and route warnings instead of treating Valid: true as a visual pass.
- Convert with
ConvertTo-Tm7.ps1. Use -MicrosoftCompatibility Required when Microsoft Threat Modeling Tool is installed; use Auto only when absence of the application is acceptable and report when that check was unavailable.
- Validate the resulting
.tm7 with Test-Tm7.ps1 -Kind Model -MicrosoftCompatibility Required before delivery.
- When the Microsoft application and UI control are available, open the TM7, maximize the application, inspect the whole diagram and the busiest region, and iterate on the JSON if labels obscure nodes or the main interactions cannot be traced. State explicitly if no GUI visual review was possible.
- Keep the JSON beside the TM7 as its maintainable source unless the user requests otherwise.
Edit an existing model
- Preserve the original
.tm7; write edits to a new output path unless replacement was explicitly requested.
- Import it with
ConvertFrom-Tm7.ps1. The result uses manual geometry, retains native GUIDs, and records source_model.sha256 so the converter can reject the wrong or stale base file.
- If import reports an unsupported or lossy feature, stop the JSON workflow. Prefer extending and retesting the converter. Use the guarded direct-XML fallback only for an explicitly required, unambiguous existing leaf-value edit whose representation is proven by the source or a Microsoft-generated exemplar; first read references/direct-xml-editing.md. Do not use XML to bypass validation or guess a missing contract.
- Edit the exported JSON while preserving
source_model, the diagram tm7_guid, and every tm7_guid for an object that remains the same native object. See references/json-contract.md for replacement, addition, deletion, and field-clearing rules.
- Keep
layout_mode: "manual" to preserve existing geometry. Give new elements non-overlapping bounds; omit a new flow's route to let the converter route that connector. To relayout everything, switch to auto and remove every imported bounds and route field.
- Validate the edited JSON as a spec.
- Convert with the exact original TM7 passed explicitly as
-TemplatePath. Confirm the result reports ConversionMode: PreservingEdit and SourceHashVerification: Passed. Existing matched XML objects are patched by GUID, preserving opaque stencil properties, display attributes, knowledge-base content, and threat-instance metadata that JSON does not expose.
- Run required Microsoft compatibility validation on the new TM7. Re-import the result and verify the requested names, endpoints, geometry, threats, and counts before delivery.
Never use -AllowKnowledgeBaseReplacement during an edit unless the user explicitly accepts replacing unmodeled source knowledge-base content with the bundled base template.
Use direct XML only as a fallback
Read references/direct-xml-editing.md in full before any direct XML patch. Use it only when the JSON contract cannot represent the requested field or cannot import a surrounding feature that must remain intact. Restrict direct work to verified existing nodes whenever possible, write a new TM7, run structural plus required Microsoft ObjectModel validation, and re-import the result. A direct patch changes the source SHA-256, so discard stale imported provenance and create fresh JSON from the patched model before later JSON edits.
Promote any recurring direct edit into the importer, schema, preservation writer, and regression tests. Do not maintain a parallel ad hoc XML implementation.
Make supported edits safely
- Rename the model, diagram, boundary, element, or flow by changing its
name; keep its tm7_guid.
- Move or resize imported shapes by changing
bounds. Keep containment fields and geometry consistent.
- Relink a flow by changing
source_id or target_id; keep its tm7_guid when it remains the same logical connector.
- Add a boundary, generic element, or flow with a new agent-facing
id and no tm7_guid. In manual mode, supply bounds for a new shape; a new flow route is optional.
- Delete an object by removing its JSON entry and all references to it. Delete or retarget attached flows and threats in the same edit.
- Edit threat title, severity, category, descriptions, justification, interaction, state, element context, and flow attachments. Keep an imported
tm7_type_id unless intentionally replacing its native threat type.
- Do not change
kind while retaining an imported element's tm7_guid. To replace its native shape, remove the old element and add a new one without tm7_guid, then retarget flows.
- Treat custom/configurable stencil properties as preserved but opaque. The converter keeps them on a GUID-matched source object; the current JSON contract does not edit them.
- To clear an imported flow description, set
description to null. Omitting that property during a preservation edit leaves the source property unchanged.
- On verification re-import, match boundaries, elements, and flows by
tm7_guid, not by the generated agent-facing id, because renaming an object can change its slug. Match an existing threat by tm7_type_id plus its flow's tm7_guid.
Validate or inspect
Use Test-Tm7.ps1 -Kind Auto. JSON receives schema, graph, generated-layout, and estimated overlap validation. Layout findings are warnings because a dense graph may be structurally correct but still require judgment. TM7 receives secure XML parsing, structural/reference validation, and—when requested—the installed Microsoft serializer plus ObjectModel post-load validation.
Use ConvertFrom-Tm7.ps1 when a semantic JSON view is useful. Import supports exactly one diagram with rectangular trust boundaries, ellipse processes, rectangle external interactors, parallel-line data stores, connectors, and threats. Source-backed export preserves custom stencil identity and properties carried by those supported native shape classes, although those opaque properties are not exposed for editing.
Run the scripts
$tm7SkillRoot = 'C:\path\to\tm7-modeling'
$specPath = 'C:\work\store-model.tm7.json'
$modelPath = 'C:\work\store-model.tm7'
pwsh -NoLogo -NoProfile -NonInteractive -File `
(Join-Path $tm7SkillRoot 'scripts\Test-Tm7.ps1') `
-InputPath $specPath -Kind Spec
if ($LASTEXITCODE -ne 0) { throw 'TM7 JSON validation failed.' }
pwsh -NoLogo -NoProfile -NonInteractive -File `
(Join-Path $tm7SkillRoot 'scripts\ConvertTo-Tm7.ps1') `
-InputPath $specPath -OutputPath $modelPath `
-MicrosoftCompatibility Required
if ($LASTEXITCODE -ne 0) { throw 'TM7 conversion failed.' }
For an edit, preserve and reuse the original model:
$sourceModel = 'C:\work\existing.tm7'
$editSpec = 'C:\work\existing.edit.tm7.json'
$editedModel = 'C:\work\existing.edited.tm7'
pwsh -NoLogo -NoProfile -NonInteractive -File `
(Join-Path $tm7SkillRoot 'scripts\ConvertFrom-Tm7.ps1') `
-InputPath $sourceModel -OutputPath $editSpec
if ($LASTEXITCODE -ne 0) { throw 'TM7 import failed.' }
# Edit and validate $editSpec before compiling it.
pwsh -NoLogo -NoProfile -NonInteractive -File `
(Join-Path $tm7SkillRoot 'scripts\ConvertTo-Tm7.ps1') `
-InputPath $editSpec -OutputPath $editedModel `
-TemplatePath $sourceModel -MicrosoftCompatibility Required
if ($LASTEXITCODE -ne 0) { throw 'Edited TM7 conversion failed.' }
# Re-import the output as a semantic postcondition check.
$verificationSpec = 'C:\work\existing.edited.verify.tm7.json'
pwsh -NoLogo -NoProfile -NonInteractive -File `
(Join-Path $tm7SkillRoot 'scripts\ConvertFrom-Tm7.ps1') `
-InputPath $editedModel -OutputPath $verificationSpec -Force
if ($LASTEXITCODE -ne 0) { throw 'Edited TM7 re-import failed.' }
Pass -ToolDirectory only when automatic discovery does not find the intended Microsoft installation. Use -Force only when overwriting the exact destination is authorized.
Model deliberately
- Give boundaries, elements, flows, and threats readable stable IDs. References use these IDs, not display names.
- Keep a flow
name short because Microsoft renders it directly on the connector. Aim for two to five words and at most 28 characters. Put the full payload or interaction meaning in the optional flow description; the converter preserves it as a TMT string property and imports it again on round trip.
- Treat boundary and element array order as an auto-layout hint. List peers in architectural, pipeline, or interaction order. The packer preserves that order and orders busy connector slots by graph-neighbor position.
- Model security-relevant transfers, not every method call or acknowledgement. More than about 30 flows on one supported canvas triggers a density warning; reduce redundant flows when semantics permit. Do not delete a distinct trust crossing merely to make the picture attractive.
- Attach each threat to at least one
flow_id; TM7 threat instances are flow interactions. Add element_ids for contextual endpoints.
- Use
tm7_type_id: null for a new custom threat type. Preserve imported tm7_type_id values during edits.
- Prefer native threat states. The converter normalizes only the documented aliases.
- Use nested rectangular boundaries only when containment is meaningful. Auto layout calculates node geometry, graph-aware connector slots, and obstacle-aware curves, but cannot guarantee a crossing-free drawing for an arbitrary dense graph.
- Do not claim the model is security-complete merely because it is structurally valid. Compatibility validation proves loadability, not threat-analysis quality.
Handle failures
- Fix JSON Schema or semantic-reference errors in JSON; do not weaken validation.
- Treat
Layout.ElementOverlaps as a converter defect or invalid manual geometry. Treat estimated label/element, label/label, route/element, and route/foreign-label warnings as an instruction to shorten labels, reorder peer arrays, remove redundant non-security flows, switch to deliberate manual geometry, or document why density remains.
- Treat a Microsoft
ObjectModel rejection as a compiler failure. Keep the failed output temporary and diagnose the converter or template.
- Treat an import rejection as the default scope boundary. Existing line boundaries, annotations, unsupported native shape classes, or multiple diagrams require converter support for normal editing. Use the direct-XML guide only for a user-authorized, source-proven leaf patch; never improvise graph mutations around the rejection.
- Treat a
source_model.sha256 mismatch as stale input, not as a nuisance check. Re-import the current source TM7, replay the intended JSON edits, and convert from that exact source.
- If Microsoft validation is unavailable in
Auto mode, state that only structural validation ran. For a final file on a machine with the tool installed, rerun with Required.