Status: ✅ Complete
Delivered: March 2026
PyPI tag: Not yet published (git install only)
What Was Built
Phase 1 established the core framework — the scanner architecture, the 24 check implementations, and the scoring engine. Everything built in later phases sits on top of this foundation.
Core Architecture
The six-module pipeline was designed from the start:
Scanners → Checks → Scoring → Storage → Reporting → Remediation
The key architectural decision was to separate data collection (scanners) from security evaluation (checks). Every check is a pure Python function that accepts a scanner object and returns a CheckResult. This means:
- Every check is independently unit-testable with a mock scanner
- No network connections are made during testing
- Adding a new check requires writing one function and one test — no framework changes
The 24 Checks
All 24 checks were implemented and mapped to OWASP Top 10:2025 categories using a four-criterion selection process:
- Externally detectable without agent access
- Targets configuration, not runtime vulnerabilities
- Maps to at least one OWASP Top 10:2025 category
- Has an automatable remediation pathway The checks were selected after reviewing OWASP guidance, NCSC education sector advisories, and CIS benchmarks for Docker and Linux hosts.
Scoring Engine
The priority formula was designed to rank fixes by effort versus impact rather than severity alone:
priority_score = (severity_score × impact_weight) ÷ effort_score
This produces the Day 1 / Day 7 / Day 30 remediation roadmap — the feature that most distinguishes StackSentry from tools that return unordered findings lists.
Grade Scale
| Grade | Score | Rationale |
|---|---|---|
| A | ≥90% | Even well-maintained systems have outstanding items |
| B | 80–89% | Good posture with minor gaps |
| C | 70–79% | Material risk — one in three checks failing |
| D | 60–69% | Significant gaps requiring prompt action |
| F | <60% | Majority of checks failing |
The scale is deliberately conservative — a 70% pass rate in security means real, unacceptable risk in a production context.
PDF Reporting
The ReportLab-based PDF generator produced a 14-section report including executive summary, OWASP heatmap, attack path detection, and the 30-day simulation roadmap.
The --profile flag introduced audience-adaptive narrative framing — the same OWASP finding described differently for a student, a DevOps engineer, a penetration tester, and a CTO.
Technical Decisions Made in Phase 1
Python 3.10+ only — match statements and dataclasses with __post_init__ were used throughout the scoring engine. The minimum version was chosen deliberately rather than supporting older Pythons.
requests for HTTP — considered httpx for async scanning but chose requests for simplicity. Multi-check scanning does not benefit significantly from async at 24 checks.
CheckResult as a frozen dataclass — making CheckResult immutable prevents accidental mutation of findings during report generation, which caused subtle bugs in early prototypes.
SQLite for history — no separate database server required. The single-user CLI model makes a file-based database the right choice.
Phase 1 Test Suite
tests/test_branch_logic.py — 31 tests (PASS/FAIL/WARN branching per check)
tests/test_scan_result.py — 20 tests (scoring, grades, OWASP aggregation)
tests/test_guards.py — 35 tests (guard clause behaviour)
Total at Phase 1 completion: 86 tests, all passing.