working-on-daemon — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited working-on-daemon (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Read docs/daemon.md for the full architecture reference.
Registration and linking are separate concerns:
/ws/register, sends Register proto, receives RegisterResult (source_uuid, source_token, link_code), disconnects./ws/source/{uuid} with Bearer auth. It is now online and can push saves, send events, receive config. The server silently drops pushes from unlinked sources (no user_uuid to store against), but the connection is live.Key principle: The daemon has exactly one network channel to the server — a single WebSocket connection. There are zero HTTP calls except downloading WASM plugin binaries from R2. Registration, save push, status, link notifications, config updates, link-code refresh, unlink, deregister — all flow over WS as proto messages.
All source management operations (link state, link-code refresh, unlink, deregister) flow over WS as proto messages. The daemon has zero HTTP calls to the server except downloading WASM plugin binaries from R2.
After changes, run in order:
just fmt-go # goimports
just lint-go # staticcheck + go vet
just test-go # unit tests
just test-go-race # race detector (before committing)Every external dependency has an interface in internal/daemon/. Tests inject hand-written fakes. Real implementations live in separate packages and satisfy interfaces implicitly.
| Interface | Real impl | Fake location |
|---|---|---|
Watcher | internal/watcher/ | internal/daemon/daemon_test.go |
Runner | internal/runner/ | internal/daemon/daemon_test.go |
WSClient | internal/wsconn/ | internal/daemon/daemon_test.go |
FS | internal/osfs/ | internal/daemon/daemon_test.go |
PluginManager | internal/pluginmgr/ | internal/daemon/daemon_test.go |
No mocking libraries. Hand-written fakes that implement the same interface. Fakes go in _test.go files next to the code they test.
Interface design:
Type safety:
interface{} or any unless absolutely required (JSON unmarshaling).SaveUUID, GameID).Error handling:
fmt.Errorf("context: %w", err). Check immediately, never ignore.Concurrency:
time.Sleep().context.Context or sync.WaitGroup.Code style:
context.Context as first parameter on anything that blocks.t.Run() subtests, comprehensive coverage.main().Never do:
init() for setup.main())._ for unused parameters — remove them.GetUserV2) — delete the old one.//nolint comments — fix the issue.nhooyr.io/websocket — context-aware, clean shutdown.Message oneof over this single WS connection.internal/daemon/daemon.go # Orchestrator, Run loop, event handling
internal/daemon/daemon_test.go # Tests + all fakes
internal/runner/wazero.go # WASM execution
internal/watcher/watcher.go # fsnotify + debounce + hash
internal/wsconn/client.go # WebSocket client
cmd/savecraftd/main.go # Entrypoint
cmd/savecraftd/cmd/config.go # Registration (wsRegister), config loading
cmd/savecraftd/cmd/run.go # Boot flow, link waiting
cmd/savecraftd/cmd/link.go # Link polling + code refresh (TO BE REPLACED with WS)~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.