Verification
After 10 minutes with a kitty window focused for part of them, and one agent turn:
tagwerk doctortagwerk dayWhat a working sensor looks like
Section titled “What a working sensor looks like”doctor prints one row per sensor (poll, beat and idle mark) with when it last appended and a verdict. Three live rows mean the focus poller, the agent hooks and the idle listener all reach the ledger, and day lists the repo you were in.
A row reads unknown when no poll proves the machine was ever on, so there is nothing to measure that sensor’s silence against. A row reads dark when a sensor has appended nothing while the machine was demonstrably on, for longer than sensor_dark_h.
Wiring
Section titled “Wiring”Below the sensors, doctor reports the two agent hook installs: wired, missing with the command to type, or unknown when it cannot read ~/.claude/settings.json. The settings schema is Anthropic’s, so a file that is absent, unreadable or shaped unexpectedly reads unknown rather than a false missing. Wiring is advisory and never changes the exit code.
Suspect config
Section titled “Suspect config”Last, doctor lists config that cannot be doing anything: a root that is no directory on disk, and a [[title]] pattern that no title in the ledger ever matched. Both read suspect, never dark: a root may sit on an unmounted drive, and a pattern may simply describe an app you have not opened. Each row names the path or pattern as your config wrote it, so you can grep for the line, and says where the minutes go instead.
A config straight from tagwerk init reads suspect in every root and pattern until you edit it, because the template names an org that is not yours. That is the check working, not a fault, and it is why tagwerk init && $EDITOR ~/.config/tagwerk/config.toml is one command in the install.
Exit codes
Section titled “Exit codes”They let a shell prompt or a timer alarm on wiring without a suspect pattern lighting it up:
| Code | Means |
|---|---|
| 0 | every sensor live and no suspect config |
| 1 | tagwerk itself failed |
| 2 | at least one sensor dark, whatever the config says |
| 3 | every sensor live, but the config is suspect |
Exit 2 is shared with argparse usage errors, one of the known ceilings.
Fixing a dark row
Section titled “Fixing a dark row”A dark row names what to fix.
pollis the focus poller: checksystemctl --user status tagwerk-focus.serviceandjournalctl --user -u tagwerk-focus.service; systemd restarts it after 5 s.idle markistagwerk-idle.service, or hypridle running your own config without thetagwerk idleandtagwerk activelines.beatmeans the agent hooks never landed, or every turn ran outside your[roots]:tagwerk beatdrops a cwd it cannot resolve and exits 0, so nothing else reports it. The wiring rows tell the two apart: amissingrow is the install you still owe, twowiredrows point at[roots].
A sensor you deliberately never wired is a known ceiling rather than a fault. Troubleshooting has that one and the rest.