@exellix/graph-composer 2.0.0 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,389 +1,525 @@
1
- {
2
- "id": "network-vuln-subnet-triage.v2",
3
- "name": "Network vulnerability triage — subnet",
4
- "description": "Step 1 of Network vulnerability triage (v2). Runs on one subnet snapshot at a time. Produces: subnet reachability, zone classification, composition, blast radius profile. CVSS-based tier skips LLM for low severity on input.raw. Output written to x-scoped-data (inferences + decisions) with scopingMapId xmemory:scopemap:v1:subnet-triage-verdicts.",
5
- "variables": {
6
- "locale": "en"
7
- },
8
- "woroxContractTarget": {
9
- "version": 1,
10
- "referenceRole": "network-vuln-subnet-triage.v2",
11
- "intent": "Declarative integration target (.docs/worox-graph-format.md — Platform contract vs runtime guarantee). Runtime ignores this object; close gaps in upstream + executor.",
12
- "targets": {
13
- "nestedAnswerInMongo": true,
14
- "xmemoryThingWithEdge": true,
15
- "linkedFieldProvenanceOnRead": true,
16
- "preSynthesisBeforeMainLLM": true,
17
- "persistSynthesisOnScopedDoc": true,
18
- "opaqueRecordMitigations": ["mitreAttack"]
19
- }
20
- },
21
- "nodes": [
22
- {
23
- "id": "sq-4",
24
- "type": "task",
25
- "skillKey": "scoped-data-reader",
26
- "metadata": {
27
- "scopingMapId": "xmemory:scopemap:v1:subnet-asset-inventory",
28
- "entityIdPath": "input.subnetId"
29
- },
30
- "outputMapping": {
31
- "path": "scoped.subnet.importance",
32
- "mode": "replace"
33
- }
34
- },
35
- {
36
- "id": "sq-10",
37
- "type": "task",
38
- "skillKey": "scoped-data-reader",
39
- "metadata": {
40
- "scopingMapId": "xmemory:scopemap:v1:subnet-risk-summary",
41
- "entityIdPath": "input.subnetId"
42
- },
43
- "outputMapping": {
44
- "path": "scoped.subnet.priority",
45
- "mode": "replace"
46
- }
47
- },
48
- {
49
- "id": "sq-12",
50
- "type": "task",
51
- "skillKey": "scoped-data-reader",
52
- "metadata": {
53
- "scopingMapId": "xmemory:scopemap:v1:topology-to-subnet-exposure",
54
- "entityIdPath": "input.subnetId"
55
- },
56
- "outputMapping": {
57
- "path": "scoped.topology.subnet",
58
- "mode": "replace"
59
- }
60
- },
61
- {
62
- "id": "iq-7",
63
- "type": "task",
64
- "skillKey": "deterministic-rule",
65
- "metadata": {
66
- "rules": [
67
- {
68
- "id": "dmz-external-adjacency",
69
- "label": "DMZ/portal subnet with external adjacency → critical-zone",
70
- "condition": {
71
- "any": [
72
- {
73
- "all": [
74
- { "path": "scoped.topology.subnet.fields.zoneClass.value", "in": ["DMZ", "dmz", "portal"] },
75
- { "path": "scoped.topology.subnet.fields.outsideExposure.value", "in": ["EXTERNALLY_ADJACENT", "PUBLIC_EDGE"] }
76
- ]
77
- }
78
- ]
79
- },
80
- "output": {
81
- "context_verdict": "critical-zone",
82
- "context_tag": "CONFIRMED"
83
- }
84
- },
85
- {
86
- "id": "high-connectivity-internal",
87
- "label": "Internal subnet with >50 routable peers → high-connectivity-zone",
88
- "condition": {
89
- "all": [
90
- { "path": "scoped.topology.subnet.fields.zoneClass.value", "eq": "internal" },
91
- { "path": "scoped.topology.subnet.fields.routablePeerSubnetCount.value", "gte": 50 }
92
- ]
93
- },
94
- "output": {
95
- "context_verdict": "high-connectivity-zone",
96
- "context_tag": "CONFIRMED"
97
- }
98
- },
99
- {
100
- "id": "standard-internal-low-risk",
101
- "label": "Internal subnet with low overall risk → standard-zone",
102
- "condition": {
103
- "all": [
104
- { "path": "scoped.topology.subnet.fields.zoneClass.value", "eq": "internal" },
105
- { "path": "scoped.subnet.priority.fields.overallRisk.value", "in": ["Low", "low"] }
106
- ]
107
- },
108
- "output": {
109
- "context_verdict": "standard-zone",
110
- "context_tag": "CONFIRMED"
111
- }
112
- },
113
- {
114
- "id": "internal-mapped",
115
- "label": "Internal subnet (topology mapped) → standard-zone inferred",
116
- "condition": {
117
- "all": [
118
- { "path": "scoped.topology.subnet.answer_status", "eq": "answered" },
119
- { "path": "scoped.topology.subnet.fields.zoneClass.value", "eq": "internal" }
120
- ]
121
- },
122
- "output": {
123
- "context_verdict": "standard-zone",
124
- "context_tag": "INFERRED"
125
- }
126
- },
127
- {
128
- "id": "topology-not-mapped",
129
- "label": "Topology not mapped → unknown-context",
130
- "condition": {
131
- "any": [
132
- { "path": "scoped.topology.subnet.answer_status", "in": ["not_found", "empty"] }
133
- ]
134
- },
135
- "output": {
136
- "context_verdict": "unknown-context",
137
- "context_tag": "UNKNOWN"
138
- }
139
- }
140
- ],
141
- "firstMatchWins": true,
142
- "defaultOutput": {
143
- "context_verdict": "unknown-context",
144
- "context_tag": "UNKNOWN"
145
- }
146
- },
147
- "outputMapping": {
148
- "path": "inference.subnet_context",
149
- "mode": "replace"
150
- }
151
- },
152
- {
153
- "id": "resolve-subnet-tier",
154
- "type": "task",
155
- "skillKey": "deterministic-rule",
156
- "metadata": {
157
- "rules": [
158
- {
159
- "id": "tier-low-cvss",
160
- "label": "CVSS base score present and < 4 → low tier (skip subnet LLM)",
161
- "condition": {
162
- "all": [
163
- { "path": "input.raw.cvssBaseScore", "exists": true },
164
- { "path": "input.raw.cvssBaseScore", "lt": 4 }
165
- ]
166
- },
167
- "output": { "severity_tier": "low" }
168
- },
169
- {
170
- "id": "tier-medium-cvss",
171
- "label": "CVSS 4–6.9 → medium tier (full LLM)",
172
- "condition": {
173
- "all": [
174
- { "path": "input.raw.cvssBaseScore", "exists": true },
175
- { "path": "input.raw.cvssBaseScore", "gte": 4 },
176
- { "path": "input.raw.cvssBaseScore", "lte": 6.9 }
177
- ]
178
- },
179
- "output": { "severity_tier": "medium" }
180
- }
181
- ],
182
- "firstMatchWins": true,
183
- "defaultOutput": { "severity_tier": "full" }
184
- },
185
- "outputMapping": {
186
- "path": "triage",
187
- "mode": "replace",
188
- "map": {
189
- "severity_tier": "parsed.output.severity_tier",
190
- "tier_rule_id": "parsed.rule_id"
191
- }
192
- }
193
- },
194
- {
195
- "id": "iq-subnet-priority",
196
- "type": "task",
197
- "skillKey": "professional-answer",
198
- "metadata": {
199
- "aiTaskProfile": {
200
- "preStrategyKey": "subnet-context-pre-v1",
201
- "postStrategyKey": "subnet-answer-post-v1",
202
- "webScoping": { "enabled": false },
203
- "inputSynthesis": { "enabled": false }
204
- },
205
- "narrix": {
206
- "datasetId": "network.subnets",
207
- "layer": "subnet"
208
- },
209
- "outputConstraints": {
210
- "format": "structured",
211
- "requiredFields": ["priority_verdict", "priority_tag", "reasoning", "unknowns", "assumptions"],
212
- "allowedValues": {
213
- "priority_verdict": ["immediate_attention", "planned_review", "monitor", "acceptable"],
214
- "priority_tag": ["CONFIRMED", "INFERRED", "ASSUMED"]
215
- }
216
- }
217
- },
218
- "taskVariable": {
219
- "question": "You are acting as a professional security analyst. Operating assumptions: (1) Scope is this subnet only unless the record says otherwise. (2) Prefer instrumented and scoped-data signals; label gaps UNKNOWN. (3) Consider exposure, composition, and risk labels together. (4) When MITRE ATT&CK tactics/techniques appear on the record, reason about them; do not invent TTP IDs. (5) Web evidence is off for this node unless the deployment overrides it — treat claims as supplementary if enabled upstream. (6) Do not false-downgrade when KEV/active-exploitation signals exist on linked vulnerability context. Given the subnet's zone classification, external exposure, composition (asset types and count), recommended actions, and current risk label — what is the triage priority for this subnet and what should happen next?"
220
- },
221
- "inputs": {
222
- "record": {
223
- "type": "executionMemoryPath",
224
- "path": "input.raw"
225
- }
226
- },
227
- "outputMapping": {
228
- "path": "inference.subnet_priority",
229
- "mode": "replace",
230
- "map": {
231
- "answer": "output.parsed.answer",
232
- "meta": "output.parsed.meta"
233
- }
234
- }
235
- },
236
- {
237
- "id": "iq-subnet-priority-low",
238
- "type": "task",
239
- "skillKey": "deterministic-rule",
240
- "metadata": {
241
- "rules": [
242
- {
243
- "id": "subnet-priority-low-synth",
244
- "label": "Low severity tier — deterministic subnet priority (no LLM)",
245
- "condition": { "path": "input.raw", "exists": true },
246
- "output": {
247
- "priority_verdict": "monitor",
248
- "priority_tag": "INFERRED",
249
- "reasoning": "Low-severity call-budget path: subnet priority set to monitor without LLM (CVSS base score < 4 when present). Re-run as medium/full tier if severity context changes.",
250
- "unknowns": [],
251
- "assumptions": ["Assumes CVSS base score on input.raw reflects the driving vulnerability context for this subnet-level run."]
252
- }
253
- }
254
- ],
255
- "firstMatchWins": true,
256
- "defaultOutput": {
257
- "priority_verdict": "monitor",
258
- "priority_tag": "INFERRED",
259
- "reasoning": "Low-severity synthetic default.",
260
- "unknowns": [],
261
- "assumptions": []
262
- }
263
- },
264
- "outputMapping": {
265
- "path": "inference.subnet_priority",
266
- "mode": "replace",
267
- "map": {
268
- "answer": "parsed.output"
269
- }
270
- }
271
- },
272
- {
273
- "id": "assemble-subnet-payload",
274
- "type": "task",
275
- "skillKey": "scoped-answer-assembler",
276
- "metadata": {
277
- "mergeInferencePaths": [
278
- "inference.subnet_context.output",
279
- "inference.subnet_priority.answer"
280
- ],
281
- "mergeDecisionPaths": []
282
- },
283
- "outputMapping": {
284
- "path": "scopedAnswer.subnet",
285
- "mode": "replace",
286
- "map": {
287
- "inferences": "parsed.inferences",
288
- "decisions": "parsed.decisions"
289
- }
290
- }
291
- },
292
- {
293
- "id": "write-subnet-verdict",
294
- "type": "task",
295
- "skillKey": "scoped-answer-writer",
296
- "metadata": {
297
- "scopingMapId": "xmemory:scopemap:v1:subnet-triage-verdicts",
298
- "entityIdPath": "input.subnetId",
299
- "staticEntityType": "subnet",
300
- "questionTitle": "Subnet triage: scoped inferences and decisions",
301
- "payloadPath": "scopedAnswer.subnet",
302
- "woroxContractTarget": {
303
- "writer": {
304
- "mongoUpsert": true,
305
- "thingUpsert": true,
306
- "thingType": "triage-scoped-answer",
307
- "entityEdge": "has-triage-scoped-answer"
308
- }
309
- }
310
- },
311
- "outputMapping": {
312
- "path": "scopedAnswer.write_result",
313
- "mode": "replace"
314
- }
315
- },
316
- {
317
- "id": "finalize-subnet",
318
- "type": "finalizer",
319
- "finalizerType": "aggregate",
320
- "inputs": {},
321
- "config": {
322
- "strategy": "report-schema",
323
- "collect_tags": true,
324
- "sections": {
325
- "subnet_context": {
326
- "path": "inference.subnet_context.output",
327
- "title": "Subnet zone and context"
328
- },
329
- "subnet_priority": {
330
- "path": "inference.subnet_priority.answer",
331
- "title": "Subnet triage priority",
332
- "optional": true
333
- },
334
- "topology": {
335
- "path": "scoped.topology.subnet.fields",
336
- "title": "Topology data",
337
- "optional": true
338
- },
339
- "composition": {
340
- "path": "scoped.subnet.importance.fields",
341
- "title": "Asset composition",
342
- "optional": true
343
- },
344
- "severity_tier": {
345
- "path": "triage.severity_tier",
346
- "title": "Call-budget severity tier",
347
- "optional": true
348
- },
349
- "write_result": {
350
- "path": "scopedAnswer.write_result",
351
- "title": "Verdict write status",
352
- "optional": true
353
- }
354
- },
355
- "meta": {
356
- "graph": "network-vuln-subnet-triage.v2",
357
- "schemaVersion": "v2"
358
- }
359
- }
360
- }
361
- ],
362
- "edges": [
363
- { "from": "sq-4", "to": "iq-7" },
364
- { "from": "sq-10", "to": "iq-7" },
365
- { "from": "sq-12", "to": "iq-7" },
366
- { "from": "iq-7", "to": "resolve-subnet-tier" },
367
- {
368
- "from": "resolve-subnet-tier",
369
- "to": "iq-subnet-priority",
370
- "when": {
371
- "any": [
372
- { "path": "executionMemory.triage.severity_tier", "eq": "full" },
373
- { "path": "executionMemory.triage.severity_tier", "eq": "medium" }
374
- ]
375
- }
376
- },
377
- {
378
- "from": "resolve-subnet-tier",
379
- "to": "iq-subnet-priority-low",
380
- "when": { "path": "executionMemory.triage.severity_tier", "eq": "low" }
381
- },
382
- { "from": "iq-subnet-priority", "to": "assemble-subnet-payload" },
383
- { "from": "iq-subnet-priority-low", "to": "assemble-subnet-payload" },
384
- { "from": "iq-7", "to": "assemble-subnet-payload" },
385
- { "from": "sq-12", "to": "assemble-subnet-payload" },
386
- { "from": "assemble-subnet-payload", "to": "write-subnet-verdict" },
387
- { "from": "write-subnet-verdict", "to": "finalize-subnet" }
388
- ]
389
- }
1
+ {
2
+ "id": "network-vuln-subnet-triage.v2",
3
+ "variables": {
4
+ "locale": "en"
5
+ },
6
+ "nodes": [
7
+ {
8
+ "id": "sq-4",
9
+ "type": "task",
10
+ "skillKey": "scoped-data-reader",
11
+ "executionMapping": {
12
+ "path": "scoped.subnet.importance",
13
+ "mode": "replace"
14
+ },
15
+ "taskConfiguration": {
16
+ "scopingMapId": "xmemory:scopemap:v1:subnet-asset-inventory",
17
+ "entityIdPath": "input.subnetId"
18
+ }
19
+ },
20
+ {
21
+ "id": "sq-10",
22
+ "type": "task",
23
+ "skillKey": "scoped-data-reader",
24
+ "executionMapping": {
25
+ "path": "scoped.subnet.priority",
26
+ "mode": "replace"
27
+ },
28
+ "taskConfiguration": {
29
+ "scopingMapId": "xmemory:scopemap:v1:subnet-risk-summary",
30
+ "entityIdPath": "input.subnetId"
31
+ }
32
+ },
33
+ {
34
+ "id": "sq-12",
35
+ "type": "task",
36
+ "skillKey": "scoped-data-reader",
37
+ "executionMapping": {
38
+ "path": "scoped.topology.subnet",
39
+ "mode": "replace"
40
+ },
41
+ "taskConfiguration": {
42
+ "scopingMapId": "xmemory:scopemap:v1:topology-to-subnet-exposure",
43
+ "entityIdPath": "input.subnetId"
44
+ }
45
+ },
46
+ {
47
+ "id": "iq-7",
48
+ "type": "task",
49
+ "skillKey": "deterministic-rule",
50
+ "executionMapping": {
51
+ "path": "inference.subnet_context",
52
+ "mode": "replace"
53
+ },
54
+ "taskConfiguration": {
55
+ "rules": [
56
+ {
57
+ "id": "dmz-external-adjacency",
58
+ "label": "DMZ/portal subnet with external adjacency → critical-zone",
59
+ "condition": {
60
+ "any": [
61
+ {
62
+ "all": [
63
+ {
64
+ "path": "scoped.topology.subnet.fields.zoneClass.value",
65
+ "in": [
66
+ "DMZ",
67
+ "dmz",
68
+ "portal"
69
+ ]
70
+ },
71
+ {
72
+ "path": "scoped.topology.subnet.fields.outsideExposure.value",
73
+ "in": [
74
+ "EXTERNALLY_ADJACENT",
75
+ "PUBLIC_EDGE"
76
+ ]
77
+ }
78
+ ]
79
+ }
80
+ ]
81
+ },
82
+ "output": {
83
+ "context_verdict": "critical-zone",
84
+ "context_tag": "CONFIRMED"
85
+ }
86
+ },
87
+ {
88
+ "id": "high-connectivity-internal",
89
+ "label": "Internal subnet with >50 routable peers → high-connectivity-zone",
90
+ "condition": {
91
+ "all": [
92
+ {
93
+ "path": "scoped.topology.subnet.fields.zoneClass.value",
94
+ "eq": "internal"
95
+ },
96
+ {
97
+ "path": "scoped.topology.subnet.fields.routablePeerSubnetCount.value",
98
+ "gte": 50
99
+ }
100
+ ]
101
+ },
102
+ "output": {
103
+ "context_verdict": "high-connectivity-zone",
104
+ "context_tag": "CONFIRMED"
105
+ }
106
+ },
107
+ {
108
+ "id": "standard-internal-low-risk",
109
+ "label": "Internal subnet with low overall risk → standard-zone",
110
+ "condition": {
111
+ "all": [
112
+ {
113
+ "path": "scoped.topology.subnet.fields.zoneClass.value",
114
+ "eq": "internal"
115
+ },
116
+ {
117
+ "path": "scoped.subnet.priority.fields.overallRisk.value",
118
+ "in": [
119
+ "Low",
120
+ "low"
121
+ ]
122
+ }
123
+ ]
124
+ },
125
+ "output": {
126
+ "context_verdict": "standard-zone",
127
+ "context_tag": "CONFIRMED"
128
+ }
129
+ },
130
+ {
131
+ "id": "internal-mapped",
132
+ "label": "Internal subnet (topology mapped) → standard-zone inferred",
133
+ "condition": {
134
+ "all": [
135
+ {
136
+ "path": "scoped.topology.subnet.answer_status",
137
+ "eq": "answered"
138
+ },
139
+ {
140
+ "path": "scoped.topology.subnet.fields.zoneClass.value",
141
+ "eq": "internal"
142
+ }
143
+ ]
144
+ },
145
+ "output": {
146
+ "context_verdict": "standard-zone",
147
+ "context_tag": "INFERRED"
148
+ }
149
+ },
150
+ {
151
+ "id": "topology-not-mapped",
152
+ "label": "Topology not mapped → unknown-context",
153
+ "condition": {
154
+ "any": [
155
+ {
156
+ "path": "scoped.topology.subnet.answer_status",
157
+ "in": [
158
+ "not_found",
159
+ "empty"
160
+ ]
161
+ }
162
+ ]
163
+ },
164
+ "output": {
165
+ "context_verdict": "unknown-context",
166
+ "context_tag": "UNKNOWN"
167
+ }
168
+ }
169
+ ],
170
+ "firstMatchWins": true,
171
+ "defaultOutput": {
172
+ "context_verdict": "unknown-context",
173
+ "context_tag": "UNKNOWN"
174
+ }
175
+ }
176
+ },
177
+ {
178
+ "id": "resolve-subnet-tier",
179
+ "type": "task",
180
+ "skillKey": "deterministic-rule",
181
+ "executionMapping": {
182
+ "path": "triage",
183
+ "mode": "replace",
184
+ "map": {
185
+ "severity_tier": "parsed.output.severity_tier",
186
+ "tier_rule_id": "parsed.rule_id"
187
+ }
188
+ },
189
+ "taskConfiguration": {
190
+ "rules": [
191
+ {
192
+ "id": "tier-low-cvss",
193
+ "label": "CVSS base score present and < 4 → low tier (skip subnet LLM)",
194
+ "condition": {
195
+ "all": [
196
+ {
197
+ "path": "input.raw.cvssBaseScore",
198
+ "exists": true
199
+ },
200
+ {
201
+ "path": "input.raw.cvssBaseScore",
202
+ "lt": 4
203
+ }
204
+ ]
205
+ },
206
+ "output": {
207
+ "severity_tier": "low"
208
+ }
209
+ },
210
+ {
211
+ "id": "tier-medium-cvss",
212
+ "label": "CVSS 4–6.9 → medium tier (full LLM)",
213
+ "condition": {
214
+ "all": [
215
+ {
216
+ "path": "input.raw.cvssBaseScore",
217
+ "exists": true
218
+ },
219
+ {
220
+ "path": "input.raw.cvssBaseScore",
221
+ "gte": 4
222
+ },
223
+ {
224
+ "path": "input.raw.cvssBaseScore",
225
+ "lte": 6.9
226
+ }
227
+ ]
228
+ },
229
+ "output": {
230
+ "severity_tier": "medium"
231
+ }
232
+ }
233
+ ],
234
+ "firstMatchWins": true,
235
+ "defaultOutput": {
236
+ "severity_tier": "full"
237
+ }
238
+ }
239
+ },
240
+ {
241
+ "id": "iq-subnet-priority",
242
+ "type": "task",
243
+ "skillKey": "professional-answer",
244
+ "taskVariable": {
245
+ "question": "You are acting as a professional security analyst. Operating assumptions: (1) Scope is this subnet only unless the record says otherwise. (2) Prefer instrumented and scoped-data signals; label gaps UNKNOWN. (3) Consider exposure, composition, and risk labels together. (4) When MITRE ATT&CK tactics/techniques appear on the record, reason about them; do not invent TTP IDs. (5) Web evidence is off for this node unless the deployment overrides it — treat claims as supplementary if enabled upstream. (6) Do not false-downgrade when KEV/active-exploitation signals exist on linked vulnerability context. Given the subnet's zone classification, external exposure, composition (asset types and count), recommended actions, and current risk label — what is the triage priority for this subnet and what should happen next?"
246
+ },
247
+ "inputsConfig": {
248
+ "record": {
249
+ "type": "executionMemoryPath",
250
+ "path": "input.raw"
251
+ }
252
+ },
253
+ "executionMapping": {
254
+ "path": "inference.subnet_priority",
255
+ "mode": "replace",
256
+ "map": {
257
+ "answer": "output.parsed.answer",
258
+ "meta": "output.parsed.meta"
259
+ }
260
+ },
261
+ "taskConfiguration": {
262
+ "aiTaskProfile": {
263
+ "preStrategyKey": "subnet-context-pre-v1",
264
+ "postStrategyKey": "subnet-answer-post-v1",
265
+ "webScoping": {
266
+ "enabled": false
267
+ },
268
+ "inputSynthesis": {
269
+ "enabled": false
270
+ }
271
+ },
272
+ "narrix": {
273
+ "datasetId": "network.subnets",
274
+ "layer": "subnet"
275
+ },
276
+ "aiTasksOutputValidation": {
277
+ "schema": {
278
+ "format": "structured",
279
+ "requiredFields": [
280
+ "priority_verdict",
281
+ "priority_tag",
282
+ "reasoning",
283
+ "unknowns",
284
+ "assumptions"
285
+ ],
286
+ "allowedValues": {
287
+ "priority_verdict": [
288
+ "immediate_attention",
289
+ "planned_review",
290
+ "monitor",
291
+ "acceptable"
292
+ ],
293
+ "priority_tag": [
294
+ "CONFIRMED",
295
+ "INFERRED",
296
+ "ASSUMED"
297
+ ]
298
+ }
299
+ }
300
+ }
301
+ }
302
+ },
303
+ {
304
+ "id": "iq-subnet-priority-low",
305
+ "type": "task",
306
+ "skillKey": "deterministic-rule",
307
+ "executionMapping": {
308
+ "path": "inference.subnet_priority",
309
+ "mode": "replace",
310
+ "map": {
311
+ "answer": "parsed.output"
312
+ }
313
+ },
314
+ "taskConfiguration": {
315
+ "rules": [
316
+ {
317
+ "id": "subnet-priority-low-synth",
318
+ "label": "Low severity tier — deterministic subnet priority (no LLM)",
319
+ "condition": {
320
+ "path": "input.raw",
321
+ "exists": true
322
+ },
323
+ "output": {
324
+ "priority_verdict": "monitor",
325
+ "priority_tag": "INFERRED",
326
+ "reasoning": "Low-severity call-budget path: subnet priority set to monitor without LLM (CVSS base score < 4 when present). Re-run as medium/full tier if severity context changes.",
327
+ "unknowns": [],
328
+ "assumptions": [
329
+ "Assumes CVSS base score on input.raw reflects the driving vulnerability context for this subnet-level run."
330
+ ]
331
+ }
332
+ }
333
+ ],
334
+ "firstMatchWins": true,
335
+ "defaultOutput": {
336
+ "priority_verdict": "monitor",
337
+ "priority_tag": "INFERRED",
338
+ "reasoning": "Low-severity synthetic default.",
339
+ "unknowns": [],
340
+ "assumptions": []
341
+ }
342
+ }
343
+ },
344
+ {
345
+ "id": "assemble-subnet-payload",
346
+ "type": "task",
347
+ "skillKey": "scoped-answer-assembler",
348
+ "executionMapping": {
349
+ "path": "scopedAnswer.subnet",
350
+ "mode": "replace",
351
+ "map": {
352
+ "inferences": "parsed.inferences",
353
+ "decisions": "parsed.decisions"
354
+ }
355
+ },
356
+ "taskConfiguration": {
357
+ "mergeInferencePaths": [
358
+ "inference.subnet_context.output",
359
+ "inference.subnet_priority.answer"
360
+ ],
361
+ "mergeDecisionPaths": []
362
+ }
363
+ },
364
+ {
365
+ "id": "write-subnet-verdict",
366
+ "type": "task",
367
+ "skillKey": "scoped-answer-writer",
368
+ "metadata": {
369
+ "exellixContractTarget": {
370
+ "writer": {
371
+ "mongoUpsert": true,
372
+ "thingUpsert": true,
373
+ "thingType": "triage-scoped-answer",
374
+ "entityEdge": "has-triage-scoped-answer"
375
+ }
376
+ }
377
+ },
378
+ "executionMapping": {
379
+ "path": "scopedAnswer.write_result",
380
+ "mode": "replace"
381
+ },
382
+ "taskConfiguration": {
383
+ "scopingMapId": "xmemory:scopemap:v1:subnet-triage-verdicts",
384
+ "entityIdPath": "input.subnetId",
385
+ "staticEntityType": "subnet",
386
+ "payloadPath": "scopedAnswer.subnet",
387
+ "questionTitle": "Subnet triage: scoped inferences and decisions"
388
+ }
389
+ },
390
+ {
391
+ "id": "finalize-subnet",
392
+ "type": "finalizer",
393
+ "finalizerType": "aggregate",
394
+ "inputs": {},
395
+ "config": {
396
+ "strategy": "report-schema",
397
+ "collect_tags": true,
398
+ "sections": {
399
+ "subnet_context": {
400
+ "path": "inference.subnet_context.output",
401
+ "title": "Subnet zone and context"
402
+ },
403
+ "subnet_priority": {
404
+ "path": "inference.subnet_priority.answer",
405
+ "title": "Subnet triage priority",
406
+ "optional": true
407
+ },
408
+ "topology": {
409
+ "path": "scoped.topology.subnet.fields",
410
+ "title": "Topology data",
411
+ "optional": true
412
+ },
413
+ "composition": {
414
+ "path": "scoped.subnet.importance.fields",
415
+ "title": "Asset composition",
416
+ "optional": true
417
+ },
418
+ "severity_tier": {
419
+ "path": "triage.severity_tier",
420
+ "title": "Call-budget severity tier",
421
+ "optional": true
422
+ },
423
+ "write_result": {
424
+ "path": "scopedAnswer.write_result",
425
+ "title": "Verdict write status",
426
+ "optional": true
427
+ }
428
+ },
429
+ "meta": {
430
+ "graph": "network-vuln-subnet-triage.v2",
431
+ "schemaVersion": "v2"
432
+ }
433
+ }
434
+ }
435
+ ],
436
+ "edges": [
437
+ {
438
+ "from": "sq-4",
439
+ "to": "iq-7"
440
+ },
441
+ {
442
+ "from": "sq-10",
443
+ "to": "iq-7"
444
+ },
445
+ {
446
+ "from": "sq-12",
447
+ "to": "iq-7"
448
+ },
449
+ {
450
+ "from": "iq-7",
451
+ "to": "resolve-subnet-tier"
452
+ },
453
+ {
454
+ "from": "resolve-subnet-tier",
455
+ "to": "iq-subnet-priority",
456
+ "when": {
457
+ "any": [
458
+ {
459
+ "path": "executionMemory.triage.severity_tier",
460
+ "eq": "full"
461
+ },
462
+ {
463
+ "path": "executionMemory.triage.severity_tier",
464
+ "eq": "medium"
465
+ }
466
+ ]
467
+ }
468
+ },
469
+ {
470
+ "from": "resolve-subnet-tier",
471
+ "to": "iq-subnet-priority-low",
472
+ "when": {
473
+ "path": "executionMemory.triage.severity_tier",
474
+ "eq": "low"
475
+ }
476
+ },
477
+ {
478
+ "from": "iq-subnet-priority",
479
+ "to": "assemble-subnet-payload"
480
+ },
481
+ {
482
+ "from": "iq-subnet-priority-low",
483
+ "to": "assemble-subnet-payload"
484
+ },
485
+ {
486
+ "from": "iq-7",
487
+ "to": "assemble-subnet-payload"
488
+ },
489
+ {
490
+ "from": "sq-12",
491
+ "to": "assemble-subnet-payload"
492
+ },
493
+ {
494
+ "from": "assemble-subnet-payload",
495
+ "to": "write-subnet-verdict"
496
+ },
497
+ {
498
+ "from": "write-subnet-verdict",
499
+ "to": "finalize-subnet"
500
+ }
501
+ ],
502
+ "metadata": {
503
+ "name": "Network vulnerability triage — subnet",
504
+ "description": "Step 1 of Network vulnerability triage (v2). Runs on one subnet snapshot at a time. Produces: subnet reachability, zone classification, composition, blast radius profile. CVSS-based tier skips LLM for low severity on input.raw. Output written to x-scoped-data (inferences + decisions) with scopingMapId xmemory:scopemap:v1:subnet-triage-verdicts.",
505
+ "woroxContractTarget": {
506
+ "version": 1,
507
+ "referenceRole": "network-vuln-subnet-triage.v2",
508
+ "intent": "Declarative integration target (.docs/worox-graph-format.md — Platform contract vs runtime guarantee). Runtime ignores this object; close gaps in upstream + executor.",
509
+ "targets": {
510
+ "nestedAnswerInMongo": true,
511
+ "xmemoryThingWithEdge": true,
512
+ "linkedFieldProvenanceOnRead": true,
513
+ "preSynthesisBeforeMainLLM": true,
514
+ "persistSynthesisOnScopedDoc": true,
515
+ "opaqueRecordMitigations": [
516
+ "mitreAttack"
517
+ ]
518
+ }
519
+ }
520
+ },
521
+ "response": {
522
+ "missing": "null",
523
+ "shape": []
524
+ }
525
+ }