You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to PR #208 (closes #202). The atom-fetcher's opt-in pinning landed in #208 with the trust-model improvements (caps, perm gate, deny_unknown_fields, hard-fail on typo, per-tick reload). Drift detection — telling operators when their pin is N commits behind upstream — is the UX layer that makes pinning practical to maintain without external tooling.
journald WARNING on first drift transition (in-sync → behind). Throttled to once per drift window so the log doesn't fill up.
`atty doctor` integration — extend the doctor command (Zig side) to query `atoms_drift` and print a yellow line when a source is behind its pin. Falls back silently if daemon unreachable.
Deferred (`atoms_drift` is read-only so simple; `atty-guard atoms status` builds on existing UDS client; the journald + atty doctor pieces follow standard patterns).
Splitting kept #208 focused on the security improvements (caps, perm gate, opt-in pinning with digest verify, doc honesty). Drift detection is UX over a security feature that already works manually (`gh api .../commits/master` + diff the SHA against the pin file). Different review surface; one PR per concept.
Acceptance
`atoms.drift.json` written after each successful cron tick.
`atoms_drift` UDS RPC returns the same shape as the JSON file.
`atty-guard atoms status` reads via direct file OR UDS, prints human-readable report, exits 0/1 by drift state.
`atty doctor` prints yellow drift line when applicable.
journald breadcrumb on first drift transition, throttled.
Follow-up to PR #208 (closes #202). The atom-fetcher's opt-in pinning landed in #208 with the trust-model improvements (caps, perm gate, deny_unknown_fields, hard-fail on typo, per-tick reload). Drift detection — telling operators when their pin is N commits behind upstream — is the UX layer that makes pinning practical to maintain without external tooling.
Agreed design (from PR #208 review discussion)
Detection
Lightweight head-SHA probe per source, once per cron tick:
```
GET https://api.github.com/repos///commits/master?per_page=1
→ .sha (~1 KB JSON response, unauthenticated, 60 req/h limit, plenty for 6h cadence)
```
Compare to `cfg.pins..commit` (pinned mode) or to the previous tick's seen SHA (live-tracking mode, optional drift telemetry).
State
`/var/lib/atty-guard/atoms.drift.json` — daemon-written, atty:atty 0640:
```json
{
"updated_at": "2026-05-22T10:00:00Z",
"sources": [
{
"name": "gtfobins",
"pinned": "7382261ef936e35896ba70e7a6b833352ffb9a22",
"upstream": "5dc1f4a8a1b2c3d4e5f6789012345678901234ab",
"behind_since": "2026-05-20T14:33:00Z"
}
]
}
```
Surfaces
Deferred (`atoms_drift` is read-only so simple; `atty-guard atoms status` builds on existing UDS client; the journald + atty doctor pieces follow standard patterns).
Why not in #208
Splitting kept #208 focused on the security improvements (caps, perm gate, opt-in pinning with digest verify, doc honesty). Drift detection is UX over a security feature that already works manually (`gh api .../commits/master` + diff the SHA against the pin file). Different review surface; one PR per concept.
Acceptance
Tracker: this issue. Parent: #205.