@exellix/graph-composer 2.0.0

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.
Files changed (103) hide show
  1. package/.env.example +66 -0
  2. package/LICENSE +21 -0
  3. package/README.md +329 -0
  4. package/dist/aiTaskProfile.d.ts +66 -0
  5. package/dist/aiTaskProfile.d.ts.map +1 -0
  6. package/dist/aiTaskProfile.js +179 -0
  7. package/dist/canonicalGraphDocument.d.ts +8 -0
  8. package/dist/canonicalGraphDocument.d.ts.map +1 -0
  9. package/dist/canonicalGraphDocument.js +344 -0
  10. package/dist/canonicalGraphWarnings.d.ts +6 -0
  11. package/dist/canonicalGraphWarnings.d.ts.map +1 -0
  12. package/dist/canonicalGraphWarnings.js +140 -0
  13. package/dist/catalogMatchAssist.d.ts +20 -0
  14. package/dist/catalogMatchAssist.d.ts.map +1 -0
  15. package/dist/catalogMatchAssist.js +203 -0
  16. package/dist/cataloxCatalogBridge.d.ts +103 -0
  17. package/dist/cataloxCatalogBridge.d.ts.map +1 -0
  18. package/dist/cataloxCatalogBridge.js +222 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +43 -0
  22. package/dist/composeInstructions.d.ts +11 -0
  23. package/dist/composeInstructions.d.ts.map +1 -0
  24. package/dist/composeInstructions.js +39 -0
  25. package/dist/defaultUtilitySkills.d.ts +4 -0
  26. package/dist/defaultUtilitySkills.d.ts.map +1 -0
  27. package/dist/defaultUtilitySkills.js +5 -0
  28. package/dist/exampleGeneration.d.ts +15 -0
  29. package/dist/exampleGeneration.d.ts.map +1 -0
  30. package/dist/exampleGeneration.js +72 -0
  31. package/dist/exampleInputs.d.ts +12 -0
  32. package/dist/exampleInputs.d.ts.map +1 -0
  33. package/dist/exampleInputs.js +181 -0
  34. package/dist/graphComposerActions.d.ts +22 -0
  35. package/dist/graphComposerActions.d.ts.map +1 -0
  36. package/dist/graphComposerActions.js +168 -0
  37. package/dist/graphComposerAgent.d.ts +26 -0
  38. package/dist/graphComposerAgent.d.ts.map +1 -0
  39. package/dist/graphComposerAgent.js +175 -0
  40. package/dist/graphComposerOutputValidation.d.ts +23 -0
  41. package/dist/graphComposerOutputValidation.d.ts.map +1 -0
  42. package/dist/graphComposerOutputValidation.js +709 -0
  43. package/dist/graphConceptPatchMerge.d.ts +10 -0
  44. package/dist/graphConceptPatchMerge.d.ts.map +1 -0
  45. package/dist/graphConceptPatchMerge.js +40 -0
  46. package/dist/graphEngineBridge.d.ts +7 -0
  47. package/dist/graphEngineBridge.d.ts.map +1 -0
  48. package/dist/graphEngineBridge.js +5 -0
  49. package/dist/index.d.ts +24 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +19 -0
  52. package/dist/openRouterConnectTimeout.d.ts +3 -0
  53. package/dist/openRouterConnectTimeout.d.ts.map +1 -0
  54. package/dist/openRouterConnectTimeout.js +48 -0
  55. package/dist/packDir.d.ts +7 -0
  56. package/dist/packDir.d.ts.map +1 -0
  57. package/dist/packDir.js +23 -0
  58. package/dist/parseGraphConceptStory.d.ts +21 -0
  59. package/dist/parseGraphConceptStory.d.ts.map +1 -0
  60. package/dist/parseGraphConceptStory.js +105 -0
  61. package/dist/redactForLog.d.ts +2 -0
  62. package/dist/redactForLog.d.ts.map +1 -0
  63. package/dist/redactForLog.js +37 -0
  64. package/dist/runGraphComposer.d.ts +54 -0
  65. package/dist/runGraphComposer.d.ts.map +1 -0
  66. package/dist/runGraphComposer.js +444 -0
  67. package/dist/scopingCatalogHostTypes.d.ts +28 -0
  68. package/dist/scopingCatalogHostTypes.d.ts.map +1 -0
  69. package/dist/scopingCatalogHostTypes.js +6 -0
  70. package/dist/scopingNeedMatchAssist.d.ts +14 -0
  71. package/dist/scopingNeedMatchAssist.d.ts.map +1 -0
  72. package/dist/scopingNeedMatchAssist.js +58 -0
  73. package/dist/taskNodeTaskVariable.d.ts +44 -0
  74. package/dist/taskNodeTaskVariable.d.ts.map +1 -0
  75. package/dist/taskNodeTaskVariable.js +347 -0
  76. package/dist/types.d.ts +174 -0
  77. package/dist/types.d.ts.map +1 -0
  78. package/dist/types.js +1 -0
  79. package/examples/network-vuln-subnet-triage.v2.json +389 -0
  80. package/functions/graph-composer/meta.json +607 -0
  81. package/functions/graph-composer/prompts/README.md +46 -0
  82. package/functions/graph-composer/prompts/action-create.md +51 -0
  83. package/functions/graph-composer/prompts/action-explain.md +26 -0
  84. package/functions/graph-composer/prompts/action-modify.md +32 -0
  85. package/functions/graph-composer/prompts/action-review-concept.md +97 -0
  86. package/functions/graph-composer/prompts/action-suggest-catalog-creations.md +31 -0
  87. package/functions/graph-composer/prompts/action-suggest-catalog-resolution.md +42 -0
  88. package/functions/graph-composer/prompts/action-suggest-concept-objective.md +38 -0
  89. package/functions/graph-composer/prompts/action-suggest-scoping-map-creation.md +31 -0
  90. package/functions/graph-composer/prompts/action-suggest-scoping-need-match.md +25 -0
  91. package/functions/graph-composer/prompts/default-utility-skills.json +22 -0
  92. package/functions/graph-composer/prompts/judge-rules.md +30 -0
  93. package/functions/graph-composer/prompts/orchestrator-system.md +21 -0
  94. package/functions/graph-composer/prompts/shared/graph-format.md +124 -0
  95. package/functions/graph-composer/prompts/shared/request-context.md +12 -0
  96. package/functions/graph-composer/prompts/shared/skill-selection.md +6 -0
  97. package/functions/graph-composer/prompts/shared/structural-validation.md +19 -0
  98. package/functions/graph-composer/prompts/skill-catalog-ai-header.md +3 -0
  99. package/functions/graph-composer/prompts/skill-catalog-utility-header.md +3 -0
  100. package/functions/graph-composer/prompts/skill-mode-extensible.md +7 -0
  101. package/functions/graph-composer/prompts/skill-mode-locked.md +7 -0
  102. package/functions/graph-composer/test-cases.json +52 -0
  103. package/package.json +86 -0
@@ -0,0 +1,389 @@
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
+ }