Good observation! The shift is intentional - safety-critical code typically doesn't "output" in the printf sense. Instead it returns status codes and modifies state that the caller inspects.
The pulse monitor example returns PULSE_OK/PULSE_ERR_* codes, and the caller queries state via pulse_status(). In a real system, that status feeds into a larger state machine or triggers hardware responses - not console output.
I like the shift in emphasis to testing over just looking for output, but part of the point of a "hello world" program is to make sure the output is working. If it helps, you could frame it as debug output instead of a result. "Sending pulse...", "Received pulse!".
C-Sentinel came from 30 years of UNIX systems work and one frustration: monitoring tools tell you what happened, not why it matters.
The idea is simple: capture a system "fingerprint" (processes, configs, network, audit events), let an LLM reason about the combination of signals, and surface non-obvious risks.
Some design choices that might interest HN:
Pure C99, 99KB binary - no runtime dependencies, runs anywhere
Privacy-first - usernames hashed, no PII in output
Auditd integration - who accessed /etc/shadow and why
"Why this score?" - explainable risk factors, not black box
Built as a wee project, launched on LinkedIn, somehow hit 23K impressions. Now here. Wild.
Happy to answer questions about the architecture, the C choices, or why I didn't use Rust (short answer: portability and simplicity).
Repo: github.com/williamofai/c-sentinel
Live demo: sentinel.speytech.com