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>
Optional desktop system-tray applet as a thin launcher over the existing
CLI and systemd. Core agent stays stdlib-only; tray ships as an optional
[tray] extra (pystray + Pillow). Covers menu actions, icon state, error
handling, packaging, and testing seams.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
test_release_script_generates_checksummed_artifacts hard-coded
`dirty == 1`, which only held while the worktree happened to be dirty. The
script derives `dirty` from actual git state and RELEASE_ALLOW_DIRTY is a
permission flag, not a forced value — so the test failed the moment the tree
was clean (all work committed). Compute the expected dirty flag the same way
the script does so the test is deterministic on both clean and dirty trees.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two gaps in the baseline-reconciliation feature:
- The dashboard claimed to summarise acknowledged drift, but renderIntegrity()
never rendered it. Add a `recon` chip to the integrity summary and a
Reconciliation state-card (accepted/ok/stale counts plus stale items).
- A read-only GET /api/integrity could write the store: list() flushed a
TTL-lapsed ok->stale transition to disk, violating the read-only dashboard
invariant. Add list(persist=False) and use it from the web summary path so
staleness is evaluated in memory without touching the file.
Covered by a new test asserting integrity_report() never rewrites the store.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implements the v0.9 roadmap item from the approved design spec. Operators
accept a specific FIM/package/listener/SUID drift item with a mandatory
reason; the ack suppresses that one alert only while the live state still
matches the recorded fingerprint. Content kinds (fim/pkgfile) re-alert on
further change; identity kinds (listener/suid) retire on TTL or revoke.
- reconcile.py: ReconcileStore (mtime-cached, fails closed on missing/corrupt
store), fingerprint builders, and the filter_alerts chokepoint.
- CLI: baseline accept/revoke/list with --reason/--expires/--force/--stale/--json.
- Wired at the daemon sweep + eBPF chokepoint, fim-check, and /api/integrity.
- RECONCILE_V1 schema, config knob, COMMAND_REFERENCE/SCHEMAS/OPERATIONS/ROADMAP
docs, and reconcile unit/CLI/integration tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Covers the v0.9 roadmap item: accept legitimate FIM/package/listener/SUID
drift with a mandatory reason and audited fingerprint-bound ack store.
Approach A selected: ReconcileStore with re-alert-on-fingerprint-change,
optional TTL, and stale tracking. Filter applied at daemon chokepoint,
CLI fim check, and dashboard API.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Close the remaining v0.8 posture bullet: flag enabled systemd units with
group/world-writable unit files (systemd_unit_writable, sid 100050) and
units whose ExecStart binary runs from a writable/unsafe path such as
/tmp, /dev/shm, /var/tmp, /home, or /run/user (systemd_exec_unsafe_path,
sid 100051).
- posture.systemd_findings/parse_systemctl_show/read_systemd_units, wired
into posture.run() behind the new posture_systemd config knob.
- read_systemd_units shells out to systemctl with timeouts and fails closed
on non-systemd hosts; the dashboard /api/posture surfaces findings for free.
- Unit tests for the parser and evaluator; TestRunIntegration patches the
new reader so run() never touches live systemctl.
- Docs: COMMAND_REFERENCE posture list, ROADMAP v0.8 bullet, RUNBOOKS
Runbook 2 triggers, config TOML knob.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surface integrity and watchdog state in the read-only dashboard via a new
/api/integrity endpoint and integrity_report(): watchdog/heartbeat
verdict, FIM baseline and package-DB anchor freshness, pacman keyring and
SigLevel posture, and Sentinel's own self-integrity footprint. The
endpoint summarizes existing anchors and heartbeats only — it runs no live
FIM or package verification from the request path, keeping the dashboard
read-only.
Add the enodia.integrity.v1 schema (schemas.py + docs/SCHEMAS.md) with a
contract test, a new "Integrity" dashboard tab and summary metric, and
web tests for the report shape, schema contract, endpoint, and console
wiring. Docs updated; completes the v1.0 "dashboard to local console"
roadmap item.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>