enodia-sentinal/docs/superpowers/specs/2026-07-04-sid-drill-coverage-design.md
Luna 2d23e8b878 Record tray applet completion and SID coverage design draft
Update the CLAUDE.md snapshot and roadmap for the merged tray applet,
note the shared-checkout commit hygiene rule, and save the agreed
SID drill coverage design as a draft spec.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 06:37:07 -07:00

72 lines
3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SID Drill Coverage Design
**Status:** Draft — design agreed in session Q&A, spec not yet user-reviewed.
No implementation plan written yet.
**Goal:** Fixture or drill coverage for every built-in SID, enforced by a
CI gate that cannot rot: adding a detection without a drill fails the suite.
## Context
Enodia Sentinel has 53 built-in SIDs across six engines:
| Range | Engine |
|---|---|
| 100001100004 | eBPF exec rules (`events/rules.py`) |
| 100010100016 | poll detectors (inline sids) |
| 100017100021, 100026100027 | FIM / pkgdb / pkgverify |
| 100022100025, 100028100031, 100034100035, 100037100038 | rootcheck |
| 100032100033, 100036, 100039, 100048 | poll detectors (constants) |
| 100040100047, 100050100051 | posture |
| 100060100066 | eBPF syscall rules (`events/syscall_rules.py`) |
Existing engine test files cover most behavior but nothing proves per-SID
completeness, and the bash red-team harness covers only ~9 core signatures.
## Decisions (from brainstorming Q&A)
1. **Deliverable:** coverage gate + fixtures (not fixtures-only, not bash
harness extension).
2. **Registry:** new product module `enodia_sentinel/sids.py` — aggregates
existing constants by importing them (no renumbering, no moving
definitions) into a `BUILTIN_SIDS` table: `sid`, `name`, `engine`,
defining module.
3. **Gate proof:** emission-based. The gate runs every drill for real and
asserts the union of emitted alert `sid`s equals the registry exactly, in
both directions.
## Components
- `enodia_sentinel/sids.py` — canonical SID table plus a sanity test
(uniqueness, matches imported constants).
- `tests/fixtures/sids/<sid>-<slug>.json` — one event JSON per exec-rule and
syscall-rule SID, in the exact format `rules test` accepts, so each fixture
doubles as an operator drill
(`enodia-sentinel rules test tests/fixtures/sids/100001-*.json`).
- `tests/sid_drills.py``DRILLS: dict[int, Callable[[], list[Alert]]]` for
non-event engines. Each drill builds minimal fake state (fake
`SystemState`, monkeypatched rootcheck views, temp FIM tree, posture file
fakes — same styles the existing tests use) and invokes the real engine
code.
- `tests/test_sid_coverage.py` — the gate: replays all fixtures through the
real rule engines, runs all drills, and asserts emitted sids == registry.
Failure messages name the uncovered or unregistered SID.
## Docs
- `docs/RULES.md`: short "drill fixtures" note documenting the fixture naming
convention and replay command.
- `docs/ROADMAP.md`: tick the per-SID fixture/drill item when implemented.
## Out of scope (YAGNI)
- Extending the bash red-team harness — live-host drills for rootkit-module,
kernel-taint, and pkg-DB-tamper SIDs are not safely simulable on a real
host.
- Correlation SIDs — none exist yet; the gate will catch them when they land.
## Execution note
Implement in an isolated git worktree: a concurrent session holds uncommitted
edits in this checkout (triage/enrichment work touching `cli.py`,
`respond.py`, `snapshot.py`, event sources, and docs).