feat(go): persist Python-compatible incidents

This commit is contained in:
Luna 2026-07-22 01:59:49 -07:00
parent f85c2e831a
commit 538d1d954a
No known key found for this signature in database
13 changed files with 555 additions and 46 deletions

View file

@ -1,8 +1,8 @@
# Go Port Handoff
Saved: 2026-07-22T01:40:52-07:00
Saved: 2026-07-22T01:58:38-07:00
Branch: `main`
Base commit: `6a06eba` (`docs(behavior): add behavioral spec for sweep + baseline lifecycle`)
Base commit: `f85c2e8` (`feat(go): advance validation sidecar toward production`)
Status: implemented and green, but uncommitted
## Worktree warning
@ -10,13 +10,10 @@ Status: implemented and green, but uncommitted
The checkout is intentionally dirty and contains work from multiple related
continuations. Do not reset, clean, or broadly restage it.
- At this checkpoint, `git status --short` has 62 entries (105 when every
untracked file is expanded instead of collapsing directories).
- This handoff is itself currently untracked and should be included when the
Go migration tranche is eventually committed.
- `docs/behavior/02-poll-detectors.md` and `docs/behavior/index.md` already had
staged content plus later unstaged edits (`AM` / `MM`). This save did not
change the index.
- The completed validation-sidecar tranche was committed as `f85c2e8` before
this continuation. The current Go incident tranche is not yet committed.
- At this checkpoint, `git status --short` has 20 entries with untracked
directories collapsed.
- The Python GUI files and tests are separate pre-existing work. Preserve them
while continuing the Go port.
- `build/` is ignored and contains only local build output.
@ -84,9 +81,18 @@ static binary.
- `enodia.status.v1` totals, severity counts, and last-alert time are populated
only from parseable retained Go snapshots. Python's unchanged `list_alerts`
and `get_alert` data layer successfully consumed a Go-produced pair.
- Snapshot incident IDs remain null and enrichment currently contains only a
Go-source marker plus process detail; incident indexing, rich enrichment,
assurance chaining, and notification fan-out are not yet ported.
- Snapshot incident IDs now reference an atomic private `incidents.json` using
the required `enodia.incident.v1` fields. Grouping mirrors Python's process-
lineage-first, time-window fallback behavior, the index is bounded to 1000
recent incidents, and same-second alert batches update one incident without
duplicating the snapshot name.
- Incident severity/signatures/SIDs/PIDs/lineage/timestamps are updated
additively and correlation SID `100080` is persisted. Python's unchanged
`list_incidents` and `get_incident` consumers successfully loaded a live
Go-produced index, snapshot, and timeline.
- Enrichment currently contains only a Go-source marker plus process detail;
rich enrichment, assurance chaining, and notification fan-out are not yet
ported.
- No live system service was installed or enabled during development.
## Last green verification
@ -131,14 +137,12 @@ the suite still exits successfully.
## Resume here
1. Add Python-compatible incident grouping/index persistence so retained Go
snapshots can carry real `incident_id` values and correlation timelines.
2. Port bounded post-alert enrichment and local assurance chaining without
1. Port bounded post-alert enrichment and local assurance chaining without
adding destructive response behavior or blocking the event loop on slow
collectors.
3. Connect the isolated Go snapshot/event state to explicit read-only
2. Connect the isolated Go snapshot/event state to explicit read-only
management consumers while keeping Python authoritative.
4. Continue broader Phase 3 rule metadata/state parity before considering any
3. Continue broader Phase 3 rule metadata/state parity before considering any
default-service or package cutover.
Keep the validation sidecar opt-in, preserve its separate state tree, and keep

View file

@ -91,8 +91,11 @@ Alert events are additionally retained as private
Same-second events are merged into one snapshot, required
`enodia.alert.snapshot.v1` fields are preserved, and the shared
`max_snapshots` / `max_snapshot_age_days` settings bound retention. The current
Go enrichment block is intentionally minimal; Python remains authoritative for
incident grouping, rich enrichment, assurance chaining, and notifications.
sidecar also writes a private atomic `incidents.json` with the required
`enodia.incident.v1` fields, process-lineage/time-window grouping, and additive
correlation evidence. The Go enrichment block is intentionally minimal; Python
remains authoritative for rich enrichment, assurance chaining, notifications,
and management consumers.
Each successful sweep atomically refreshes
`/var/lib/enodia-sentinel-go/heartbeat` as a Unix timestamp with mode `0600`;

View file

@ -288,10 +288,12 @@ Exit criteria:
journal JSONL. A bounded rotating JSONL copy provides isolated retained event
history, and an atomic heartbeat gives external watchdogs a non-journal
liveness signal. Bounded Python-schema-compatible JSON/text alert snapshots
now provide truthful retained counts and basic process context. The Python
service remains the production default until incident grouping, rich
enrichment/assurance, management-console consumers, and broader subsystem
parity land.
now provide truthful retained counts and basic process context. A private,
atomic `enodia.incident.v1` index now applies the shared lineage-first/time-
window grouping, assigns real snapshot `incident_id` values, and persists
correlation SID `100080`. The Python service remains the production default
until rich enrichment/assurance, management-console consumers, and broader
subsystem parity land.
## Backlog

View file

@ -249,10 +249,11 @@ signature keeps `sid` / `signature` / `classtype` / tests / docs.
isolated baseline state, journal JSONL, a bounded retained JSONL stream, and
an atomic health marker. All current typed-host families now have native
transports. Bounded `enodia.alert.snapshot.v1` JSON/text pairs now retain
alerts with basic process context and feed truthful status counts. Incident
grouping, rich enrichment/assurance, management-consumer integration, and
broader parity must land before the bcc/Python runtime dependency can be
dropped.
alerts with basic process context and feed truthful status counts. An atomic
`enodia.incident.v1` index supplies lineage/time grouping, snapshot IDs, and
correlation evidence. Rich enrichment/assurance, management-consumer
integration, and broader parity must land before the bcc/Python runtime
dependency can be dropped.
- **Phase 3 — Rule-engine parity + assimilation.** `rev`/`reference`/`metadata`,
statebits (flowbits), thresholding, suppression, and — if rule count warrants
— the MPM prefilter. `rules list/show/test/docs` parity.