Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions .cards/local/graphModels/dataflow/model.lp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ view(X, N) :- entity(X), entityLevel(X, 1), viewAll(N), not hide(X).

% graphs

% nearestVisibleAncestor(X, A): A is the nearest visible ancestor of X,
% found by walking up through invisible intermediaries.
nearestVisibleAncestor(X, A) :- consistsOf(A, X), visible(A).
nearestVisibleAncestor(X, A) :- consistsOf(P, X), entity(P), not visible(P), nearestVisibleAncestor(P, A).

% top level graph is for top level entities and enties whose parent is not visible
graph(toplevelGraph).

Expand All @@ -109,25 +114,27 @@ graph(toplevelGraph).

% graphTopLevelEntity(X) means that X is a top-level entity that must be drawn as a graph,
% because it has visible "children"
graphTopLevelEntity(X) :- entity(X), visible(X), not consistsOf(_, X), visible(Y), consistsOf(X, Y).
graphTopLevelEntity(X) :- entity(X), visible(X), not consistsOf(_, X), contains(X, Y), visible(Y).
graph(X, toplevelGraph) :- graphTopLevelEntity(X).
node(X, X) :- graphTopLevelEntity(X).
invisible(X) :- graphTopLevelEntity(X).
attr(node, X, shape, point) :- graphTopLevelEntity(X).
attr(node, X, style, invis) :- graphTopLevelEntity(X).

% graphEntityHiddenAncestors(X) means that X is an entity that must be drawn as a graph in the toplevelGraph,
% because it has visible "children", and its own parent is not visible
graphEntityHiddenAncestors(X) :- visible(X), not visible(P), consistsOf(P, X), entity(X), visible(Y), consistsOf(X, Y).
graph(X, toplevelGraph) :- graphEntityHiddenAncestors(X).
% graphEntityHiddenAncestors(X) means that X is an entity that must be drawn as a graph,
% because it has visible "children", and its own parent is not visible.
% If a nearest visible ancestor exists, X is placed inside it; otherwise at the top level.
graphEntityHiddenAncestors(X) :- visible(X), not visible(P), consistsOf(P, X), entity(X), contains(X, Y), visible(Y).
graph(X, G) :- graphEntityHiddenAncestors(X), nearestVisibleAncestor(X, G).
graph(X, toplevelGraph) :- graphEntityHiddenAncestors(X), not nearestVisibleAncestor(X, _).
node(X, X) :- graphEntityHiddenAncestors(X).
invisible(X) :- graphEntityHiddenAncestors(X).
attr(node, X, shape, point) :- graphEntityHiddenAncestors(X).
attr(node, X, style, invis) :- graphEntityHiddenAncestors(X).

% graphLowerLevel(X, P) means that X has visible children and a visible parent,
% so it must be drawn as a subgraph of P
graphLowerLevel(X, P) :- visible(X), entity(X), visible(P), consistsOf(P, X), visible(Y), consistsOf(X, Y).
graphLowerLevel(X, P) :- visible(X), entity(X), visible(P), consistsOf(P, X), contains(X, Y), visible(Y).
graph(X, P) :- graphLowerLevel(X, P).
node(X, X) :- graphLowerLevel(X, P).
invisible(X) :- graphLowerLevel(X, P).
Expand All @@ -136,10 +143,13 @@ attr(node, X, style, invis) :- graphLowerLevel(X, P).

% nodes

% if an entity is visible, but it's not a graph (= does not have visible children), then it is a node
% if an entity is visible, but it's not a graph (= does not have visible children), then it is a node.
% if the immediate parent is not visible, the node is placed in the nearest visible ancestor graph,
% or at the top level if no such ancestor exists.
node(X, toplevelGraph) :- entity(X), visible(X), not consistsOf(_, X), not graph(X, toplevelGraph).
node(X, Y) :- entity(X), visible(X), consistsOf(Y, X), not graph(X, _), visible(Y).
node(X, toplevelGraph) :- entity(X), visible(X), consistsOf(Y, X), not graph(X, _), not visible(Y).
node(X, G) :- entity(X), visible(X), consistsOf(Y, X), not graph(X, _), not visible(Y), nearestVisibleAncestor(X, G).
node(X, toplevelGraph) :- entity(X), visible(X), consistsOf(Y, X), not graph(X, _), not visible(Y), not nearestVisibleAncestor(X, _).

% edges and representatives of entities when drawing dataflows

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{{#graph}}
"model": "secdeva/graphModels/dataflow",
"view": "secdeva/graphViews/entity"
{{/graph}}

== Composite elements

[TIP]
====
To add a dataflow to or from this process, click the link symbol in the top level tool bar. Optionally, if you want to model interfaces as well, you can create an interface and link any incoming dataflows to the interface.
====

{{#createCards}}
"buttonLabel": "Create an interface",
"template": "secdeva/templates/interface"
{{/createCards}}

{{#createCards}}
"buttonLabel": "Create a trust boundary",
"template": "secdeva/templates/trustBoundary"
{{/createCards}}

{{#createCards}}
"buttonLabel": "Create an external entity",
"template": "secdeva/templates/external"
{{/createCards}}

{{#createCards}}
"buttonLabel": "Create a person",
"template": "secdeva/templates/person"
{{/createCards}}

{{#createCards}}
"buttonLabel": "Create a process",
"template": "secdeva/templates/process"
{{/createCards}}

{{#createCards}}
"buttonLabel": "Create a data store",
"template": "secdeva/templates/dataStore"
{{/createCards}}

== Interfaces

{{#report}}
"name": "secdeva/reports/entityInterfaces"
{{/report}}

== Security issues

{{#report}}
"name": "secdeva/reports/createThreat"
{{/report}}

{{#report}}
"name": "secdeva/reports/securityIssueList"
{{/report}}

== Decisions and design specifications

Document a technical decision or create a design specification.

{{#createCards}}
"buttonLabel": "Create a decision",
"template": "base/templates/decision"
{{/createCards}}

{{#createCards}}
"buttonLabel": "Create a specification",
"template": "secdeva/templates/designSpecification"
{{/createCards}}

{{#report}}
"name": "base/reports/childrenTable",
"cardType": "base/cardTypes/decision",
"tableCaption": "Decisions"
{{/report}}

{{#report}}
"name": "base/reports/childrenTable",
"cardType": "base/cardTypes/controlledDocument",
"tableCaption": "Specifications"
{{/report}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"title": "Process 1.1.1",
"cardType": "secdeva/cardTypes/process",
"workflowState": "Draft",
"rank": "0|b",
"lastUpdated": "2026-05-06T20:07:54.798Z",
"links": [],
"secdeva/fieldTypes/description": null,
"secdeva/fieldTypes/technology": null,
"templateCardKey": "secdeva_4",
"createdAt": "2026-05-06T20:07:41.635Z",
"labels": [
"example"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"cardType": "secdeva/cardTypes/process",
"workflowState": "Draft",
"rank": "0|b",
"lastUpdated": "2026-04-05T17:37:12.273Z",
"lastUpdated": "2026-05-06T20:07:11.250Z",
"links": [
{
"linkType": "secdeva/linkTypes/dataflow",
Expand All @@ -18,5 +18,6 @@
],
"secdeva/fieldTypes/description": null,
"secdeva/fieldTypes/technology": null,
"templateCardKey": "secdeva_4"
"templateCardKey": "secdeva_4",
"labels": []
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
"cardType": "secdeva/cardTypes/process",
"workflowState": "Draft",
"rank": "0|b",
"lastUpdated": "2026-04-05T17:32:52.526Z",
"lastUpdated": "2026-05-06T20:06:29.925Z",
"links": [],
"secdeva/fieldTypes/description": null,
"secdeva/fieldTypes/technology": null,
"templateCardKey": "secdeva_4"
"templateCardKey": "secdeva_4",
"labels": [
"example"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
"cardType": "secdeva/cardTypes/trustBoundary",
"workflowState": "Draft",
"rank": "0|b",
"lastUpdated": "2026-04-05T17:32:27.754Z",
"lastUpdated": "2026-05-06T20:07:29.610Z",
"links": [],
"secdeva/fieldTypes/description": null,
"secdeva/fieldTypes/technology": null,
"templateCardKey": "secdeva_5"
"templateCardKey": "secdeva_5",
"labels": []
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@
"linkType": "secdeva/linkTypes/dataflow",
"cardKey": "secdeva_ls70gm8a",
"linkDescription": "Call interface"
},
{
"linkType": "secdeva/linkTypes/dataflow",
"cardKey": "secdeva_xzgbmuu7",
"linkDescription": "Call process"
}
],
"templateCardKey": "secdeva_j2q6mk5m",
"lastUpdated": "2026-04-05T17:40:06.412Z"
"lastUpdated": "2026-05-07T05:26:07.028Z",
"labels": [
"example"
]
}
8 changes: 8 additions & 0 deletions cardRoot/secdeva_xb589ep4/c/secdeva_xkmudnfo/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
"view": "secdeva/graphViews/allEntities"
{{/graph}}

== Label diagram

{{#graph}}
"model": "secdeva/graphModels/dataflow",
"view": "secdeva/graphViews/label",
"labels": ["example"]
{{/graph}}

== Interfaces

{{#report}}
Expand Down
2 changes: 1 addition & 1 deletion cardRoot/secdeva_xb589ep4/c/secdeva_xkmudnfo/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"links": [],
"secdeva/fieldTypes/description": null,
"templateCardKey": "secdeva_gidk7o4u",
"lastUpdated": "2026-04-05T17:31:59.848Z"
"lastUpdated": "2026-05-06T20:04:14.072Z"
}