@simbimbo/brainstem 0.0.1 → 0.0.2
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.
- package/CHANGELOG.md +63 -0
- package/README.md +99 -3
- package/brainstem/__init__.py +3 -0
- package/brainstem/api.py +131 -0
- package/brainstem/connectors/__init__.py +1 -0
- package/brainstem/connectors/logicmonitor.py +26 -0
- package/brainstem/connectors/types.py +16 -0
- package/brainstem/demo.py +64 -0
- package/brainstem/fingerprint.py +44 -0
- package/brainstem/ingest.py +101 -0
- package/brainstem/instrumentation.py +38 -0
- package/brainstem/interesting.py +62 -0
- package/brainstem/models.py +78 -0
- package/brainstem/recurrence.py +112 -0
- package/brainstem/scoring.py +38 -0
- package/brainstem/storage.py +182 -0
- package/docs/adapters.md +435 -0
- package/docs/api.md +380 -0
- package/docs/architecture.md +333 -0
- package/docs/connectors.md +66 -0
- package/docs/data-model.md +290 -0
- package/docs/design-governance.md +595 -0
- package/docs/mvp-flow.md +109 -0
- package/docs/roadmap.md +87 -0
- package/docs/scoring.md +424 -0
- package/docs/v0.0.1.md +277 -0
- package/docs/vision.md +85 -0
- package/package.json +6 -14
- package/pyproject.toml +18 -0
- package/tests/fixtures/sample_syslog.log +6 -0
- package/tests/test_api.py +72 -0
- package/tests/test_canonicalization.py +28 -0
- package/tests/test_demo.py +25 -0
- package/tests/test_fingerprint.py +22 -0
- package/tests/test_ingest.py +15 -0
- package/tests/test_instrumentation.py +16 -0
- package/tests/test_interesting.py +36 -0
- package/tests/test_logicmonitor.py +22 -0
- package/tests/test_recurrence.py +16 -0
- package/tests/test_scoring.py +21 -0
- package/tests/test_storage.py +26 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Connectors
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Connectors let brAInstem ingest operational signals from systems that already collect telemetry or manage device/alert context.
|
|
6
|
+
|
|
7
|
+
The product should remain connector-agnostic at its core:
|
|
8
|
+
- same event model
|
|
9
|
+
- same candidate generation
|
|
10
|
+
- same scoring model
|
|
11
|
+
- same promotion pipeline
|
|
12
|
+
|
|
13
|
+
Connectors should enrich, not redefine, the core memory model.
|
|
14
|
+
|
|
15
|
+
## Initial connector targets
|
|
16
|
+
|
|
17
|
+
### 1. Syslog / file ingest
|
|
18
|
+
- local syslog files
|
|
19
|
+
- forwarded syslog
|
|
20
|
+
- line-oriented app logs
|
|
21
|
+
|
|
22
|
+
### 2. LogicMonitor
|
|
23
|
+
A high-value early connector target for MSP use.
|
|
24
|
+
|
|
25
|
+
Why:
|
|
26
|
+
- strong device/resource inventory
|
|
27
|
+
- alert and event context
|
|
28
|
+
- existing operator adoption in MSP environments
|
|
29
|
+
|
|
30
|
+
Integration modes:
|
|
31
|
+
- webhook ingest
|
|
32
|
+
- periodic sync / polling
|
|
33
|
+
- metadata enrichment
|
|
34
|
+
|
|
35
|
+
Recommended imported fields:
|
|
36
|
+
- `resource_id`
|
|
37
|
+
- `resource_name`
|
|
38
|
+
- `datasource`
|
|
39
|
+
- `instance_name`
|
|
40
|
+
- `alert_id`
|
|
41
|
+
- `severity`
|
|
42
|
+
- `acknowledged`
|
|
43
|
+
- `cleared_at`
|
|
44
|
+
- `collector`
|
|
45
|
+
- host group / site metadata
|
|
46
|
+
|
|
47
|
+
### 3. Future candidates
|
|
48
|
+
- LibreNMS
|
|
49
|
+
- Graylog
|
|
50
|
+
- Splunk
|
|
51
|
+
- Elastic
|
|
52
|
+
- Windows Event Forwarding
|
|
53
|
+
- custom webhooks
|
|
54
|
+
|
|
55
|
+
## Connector rules
|
|
56
|
+
|
|
57
|
+
Connectors should:
|
|
58
|
+
- map into native `event` objects
|
|
59
|
+
- preserve provenance
|
|
60
|
+
- attach source-specific metadata without polluting the core schema
|
|
61
|
+
- never bypass scoring / candidate generation / promotion logic
|
|
62
|
+
|
|
63
|
+
## Design principle
|
|
64
|
+
|
|
65
|
+
LogicMonitor should be an excellent source of events and metadata, but brAInstem must remain useful even without it.
|
|
66
|
+
That is what keeps the project universal instead of becoming a thin LogicMonitor add-on.
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Data Model
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
brAInstem needs a canonical model that can represent:
|
|
6
|
+
- raw operational events
|
|
7
|
+
- normalized signatures
|
|
8
|
+
- derived incident candidates
|
|
9
|
+
- promoted operational memory
|
|
10
|
+
- operator review decisions
|
|
11
|
+
- tenant and asset context
|
|
12
|
+
|
|
13
|
+
The model should support both deterministic event analysis and memory-style historical recall.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. Tenant
|
|
18
|
+
|
|
19
|
+
Represents a customer or environment boundary.
|
|
20
|
+
|
|
21
|
+
Fields:
|
|
22
|
+
- `tenant_id`
|
|
23
|
+
- `name`
|
|
24
|
+
- `slug`
|
|
25
|
+
- `environment_type` (msp-client, internal, lab, etc.)
|
|
26
|
+
- `tags`
|
|
27
|
+
- `metadata`
|
|
28
|
+
- `created_at`
|
|
29
|
+
- `updated_at`
|
|
30
|
+
|
|
31
|
+
Purpose:
|
|
32
|
+
- isolate memory, scoring, and recurrence by customer/environment
|
|
33
|
+
- support cross-tenant pattern comparison only when explicitly allowed
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Asset
|
|
38
|
+
|
|
39
|
+
Represents a host, firewall, service instance, application node, or logical system.
|
|
40
|
+
|
|
41
|
+
Fields:
|
|
42
|
+
- `asset_id`
|
|
43
|
+
- `tenant_id`
|
|
44
|
+
- `hostname`
|
|
45
|
+
- `asset_type` (server, firewall, switch, app, vm, workstation, etc.)
|
|
46
|
+
- `service_group`
|
|
47
|
+
- `ip_addresses`
|
|
48
|
+
- `platform`
|
|
49
|
+
- `tags`
|
|
50
|
+
- `metadata`
|
|
51
|
+
- `created_at`
|
|
52
|
+
- `updated_at`
|
|
53
|
+
|
|
54
|
+
Purpose:
|
|
55
|
+
- associate events with concrete systems
|
|
56
|
+
- support spread analysis and asset-local baselines
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 3. Event
|
|
61
|
+
|
|
62
|
+
The raw normalized event unit.
|
|
63
|
+
|
|
64
|
+
Fields:
|
|
65
|
+
- `event_id`
|
|
66
|
+
- `tenant_id`
|
|
67
|
+
- `asset_id`
|
|
68
|
+
- `source_type` (syslog, journald, windows_event, webhook, app_log, etc.)
|
|
69
|
+
- `source_path`
|
|
70
|
+
- `host`
|
|
71
|
+
- `service`
|
|
72
|
+
- `timestamp`
|
|
73
|
+
- `severity`
|
|
74
|
+
- `facility`
|
|
75
|
+
- `message_raw`
|
|
76
|
+
- `message_normalized`
|
|
77
|
+
- `structured_fields`
|
|
78
|
+
- `correlation_keys`
|
|
79
|
+
- `signature_input`
|
|
80
|
+
- `ingest_metadata`
|
|
81
|
+
- `created_at`
|
|
82
|
+
|
|
83
|
+
Purpose:
|
|
84
|
+
- preserve the original operational evidence in normalized form
|
|
85
|
+
- provide the substrate for signatures and candidate generation
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 4. Signature
|
|
90
|
+
|
|
91
|
+
A reusable event fingerprint / pattern family.
|
|
92
|
+
|
|
93
|
+
Fields:
|
|
94
|
+
- `signature_id`
|
|
95
|
+
- `tenant_scope` (global, tenant, asset)
|
|
96
|
+
- `signature_key`
|
|
97
|
+
- `signature_version`
|
|
98
|
+
- `event_family`
|
|
99
|
+
- `service`
|
|
100
|
+
- `normalized_pattern`
|
|
101
|
+
- `example_message`
|
|
102
|
+
- `first_seen_at`
|
|
103
|
+
- `last_seen_at`
|
|
104
|
+
- `occurrence_count`
|
|
105
|
+
- `metadata`
|
|
106
|
+
|
|
107
|
+
Purpose:
|
|
108
|
+
- detect recurrence
|
|
109
|
+
- cluster similar events over time
|
|
110
|
+
- support cross-host and cross-tenant comparison
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 5. Correlation Group
|
|
115
|
+
|
|
116
|
+
A time-bound grouping of related events/signatures.
|
|
117
|
+
|
|
118
|
+
Fields:
|
|
119
|
+
- `group_id`
|
|
120
|
+
- `tenant_id`
|
|
121
|
+
- `group_type` (burst, spread, change-window, precursor-cluster, etc.)
|
|
122
|
+
- `start_at`
|
|
123
|
+
- `end_at`
|
|
124
|
+
- `asset_ids`
|
|
125
|
+
- `signature_ids`
|
|
126
|
+
- `event_count`
|
|
127
|
+
- `metadata`
|
|
128
|
+
|
|
129
|
+
Purpose:
|
|
130
|
+
- represent clusters of weak signals that matter together
|
|
131
|
+
- support temporal correlation and causal analysis
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 6. Candidate
|
|
136
|
+
|
|
137
|
+
A derived object representing a possibly meaningful operational pattern.
|
|
138
|
+
|
|
139
|
+
Fields:
|
|
140
|
+
- `candidate_id`
|
|
141
|
+
- `tenant_id`
|
|
142
|
+
- `candidate_type` (recurrence, self_heal, precursor, anomaly, burst, spread)
|
|
143
|
+
- `source_signature_ids`
|
|
144
|
+
- `source_event_ids`
|
|
145
|
+
- `source_group_ids`
|
|
146
|
+
- `title`
|
|
147
|
+
- `summary`
|
|
148
|
+
- `first_seen_at`
|
|
149
|
+
- `last_seen_at`
|
|
150
|
+
- `score_total`
|
|
151
|
+
- `score_breakdown`
|
|
152
|
+
- `decision_band` (ignore, watch, review, urgent_human_review, promote_to_incident_memory)
|
|
153
|
+
- `explanation`
|
|
154
|
+
- `confidence`
|
|
155
|
+
- `metadata`
|
|
156
|
+
- `created_at`
|
|
157
|
+
- `updated_at`
|
|
158
|
+
|
|
159
|
+
Purpose:
|
|
160
|
+
- bridge raw events and durable incident memory
|
|
161
|
+
- make scoring explainable and reviewable
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 7. Incident Memory
|
|
166
|
+
|
|
167
|
+
A promoted durable record of a pattern that has proven meaningful.
|
|
168
|
+
|
|
169
|
+
Fields:
|
|
170
|
+
- `incident_memory_id`
|
|
171
|
+
- `tenant_id`
|
|
172
|
+
- `title`
|
|
173
|
+
- `summary`
|
|
174
|
+
- `incident_type`
|
|
175
|
+
- `source_candidate_ids`
|
|
176
|
+
- `source_signature_ids`
|
|
177
|
+
- `source_event_ids`
|
|
178
|
+
- `first_observed_at`
|
|
179
|
+
- `last_observed_at`
|
|
180
|
+
- `recurrence_count`
|
|
181
|
+
- `impact_level`
|
|
182
|
+
- `confidence`
|
|
183
|
+
- `status` (active, historical, retired)
|
|
184
|
+
- `metadata`
|
|
185
|
+
- `created_at`
|
|
186
|
+
- `updated_at`
|
|
187
|
+
|
|
188
|
+
Purpose:
|
|
189
|
+
- preserve meaningful operational patterns over time
|
|
190
|
+
- support "have we seen this before?"
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 8. Lesson
|
|
195
|
+
|
|
196
|
+
A distilled durable insight derived from incidents or repeated review.
|
|
197
|
+
|
|
198
|
+
Fields:
|
|
199
|
+
- `lesson_id`
|
|
200
|
+
- `tenant_id`
|
|
201
|
+
- `title`
|
|
202
|
+
- `summary`
|
|
203
|
+
- `recommendation`
|
|
204
|
+
- `source_incident_memory_ids`
|
|
205
|
+
- `source_candidate_ids`
|
|
206
|
+
- `confidence`
|
|
207
|
+
- `metadata`
|
|
208
|
+
- `created_at`
|
|
209
|
+
- `updated_at`
|
|
210
|
+
|
|
211
|
+
Purpose:
|
|
212
|
+
- convert repeated operational pain into reusable knowledge
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 9. Runbook Hint
|
|
217
|
+
|
|
218
|
+
A small operational action suggestion linked to a pattern.
|
|
219
|
+
|
|
220
|
+
Fields:
|
|
221
|
+
- `runbook_hint_id`
|
|
222
|
+
- `tenant_id`
|
|
223
|
+
- `title`
|
|
224
|
+
- `hint_text`
|
|
225
|
+
- `trigger_signature_ids`
|
|
226
|
+
- `trigger_incident_ids`
|
|
227
|
+
- `priority`
|
|
228
|
+
- `confidence`
|
|
229
|
+
- `metadata`
|
|
230
|
+
- `created_at`
|
|
231
|
+
- `updated_at`
|
|
232
|
+
|
|
233
|
+
Purpose:
|
|
234
|
+
- give operators actionable next steps without pretending to be a full runbook engine initially
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 10. Review Decision
|
|
239
|
+
|
|
240
|
+
Captures operator feedback on surfaced candidates or incidents.
|
|
241
|
+
|
|
242
|
+
Fields:
|
|
243
|
+
- `review_id`
|
|
244
|
+
- `tenant_id`
|
|
245
|
+
- `subject_type` (candidate, incident_memory, lesson)
|
|
246
|
+
- `subject_id`
|
|
247
|
+
- `decision` (noise, useful, urgent, false_positive, promote, ignore, investigate)
|
|
248
|
+
- `notes`
|
|
249
|
+
- `reviewer`
|
|
250
|
+
- `reviewed_at`
|
|
251
|
+
|
|
252
|
+
Purpose:
|
|
253
|
+
- improve future memory weight and trust calibration
|
|
254
|
+
- keep a human in the loop
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## 11. Provenance Link
|
|
259
|
+
|
|
260
|
+
Tracks relationships between objects.
|
|
261
|
+
|
|
262
|
+
Fields:
|
|
263
|
+
- `link_id`
|
|
264
|
+
- `source_type`
|
|
265
|
+
- `source_id`
|
|
266
|
+
- `target_type`
|
|
267
|
+
- `target_id`
|
|
268
|
+
- `link_type`
|
|
269
|
+
- `created_at`
|
|
270
|
+
- `metadata`
|
|
271
|
+
|
|
272
|
+
Purpose:
|
|
273
|
+
- connect raw events -> signatures -> candidates -> incidents -> lessons
|
|
274
|
+
- support explainability and drill-down
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## MVP subset
|
|
279
|
+
|
|
280
|
+
For MVP, the essential objects are:
|
|
281
|
+
- Tenant
|
|
282
|
+
- Asset
|
|
283
|
+
- Event
|
|
284
|
+
- Signature
|
|
285
|
+
- Candidate
|
|
286
|
+
- Incident Memory
|
|
287
|
+
- Review Decision
|
|
288
|
+
- Provenance Link
|
|
289
|
+
|
|
290
|
+
The others can be introduced after the first strong demo.
|