Project

Contributing

SentinelLocal is developed in the open on Codeberg, with architecture and contribution docs. The trait-based “add a tool” design invites external scanner contributions.

Adding a tool

Implement the sentinel_tools::Tool trait, register it in sentinel_tools::default_registry, and the agent will pick it up automatically — because tool descriptors are converted to OpenAI-style function definitions on the fly.

my_tool.rs rust
#[async_trait::async_trait]
impl Tool for MyTool {
    fn descriptor(&self) -> ToolDescriptor { /* JSON schema for args */ }
    async fn execute(&self, args: Value) -> Result<ToolOutput> { /* ... */ }
}

Workspace layout

sentinel-local/ text
sentinel-local/
├── crates/
│   ├── sentinel-core/    # Findings, severity, SARIF emitter
│   ├── sentinel-tools/   # Tool trait + scanners (file/yara/process/network/persistence)
│   ├── sentinel-agent/   # LlmClient trait, Ollama client + supervisor, ReAct loop, ChatSession
│   ├── sentinel-web/     # Embedded chat UI + HTTP API for interactive testing
│   └── sentinel-cli/     # `sentinel` binary (scanners, agent, chat REPL, serve)
└── rules/                # Bundled starter YARA rules

Testing

cargo test --workspace

The suite (78 tests) covers severity ordering, the YARA rule compiler, the SARIF emitter, string extraction, tool argument validation, the ReAct loop and plan parsing (against an in-process mock LLM, so no Ollama is needed), the chat REPL command dispatch, the Ollama HTTP probes, and the auto-start supervisor’s decision logic. The build is warning-free.

Versioning

The project follows Semantic Versioning. The current release is 0.2.0; while pre-1.0, minor versions may include breaking changes. The workspace version is single-sourced in the root Cargo.toml ([workspace.package]) and inherited by every crate, so sentinel --version always matches.

License

SentinelLocal is released under the European Union Public Licence v1.2 (EUPL-1.2). Contributions are accepted under the same license.