<!-- Generated by Vibe Doc v0.3.2 -->
<!-- Date: 2026-04-17T00:38:02.515Z -->
<!-- Classification: IntegrationConnector -->
<!-- Source artifacts: 69 files scanned -->

---
docType: runbook
version: 1.1
templateVersion: 1
---

# Runbook — Sanduhr für Claude (Windows v2)

## Service Overview

Sanduhr für Claude is a frameless PySide6 desktop widget for Windows that polls the
`claude.ai` REST API and displays real-time token-usage bars for all active Claude tiers
(Session 5hr, Weekly All Models, Sonnet, Opus, Cowork, Routines). It is a client-only
integration connector — no server component, no daemon, no background service. Credentials
are stored in Windows Credential Manager under service `com.626labs.sanduhr`. The widget
auto-refreshes every 5 minutes; sparkline history is persisted to
`%APPDATA%\Sanduhr\history.json`.

Distribution model: end-user Windows install via `Sanduhr-Setup-vX.Y.Z.exe` from GitHub
Releases. Build pipeline: GitHub Actions (`windows-release.yml`) triggered by a
`v*.*.*-windows` tag. No separate server infra to operate.

<!-- Source: windows/README.md, CHANGELOG.md, docs/superpowers/specs/2026-04-16-windows-v2-diamond-design.md -->

---

## Release Process (cutting a new v2.x release)

### Prerequisites

- All CI green on `windows-native` (pytest passing, no merge conflicts).
- Manual test plan completed on a clean Windows 11 VM (see `windows/TEST_PLAN.md`).
- `windows/RELEASE_NOTES.md` updated with user-facing changes.
- `windows/installer/Sanduhr.iss` version string (`MyAppVersion`) bumped to match the
  intended tag.

### Steps

1. **Ensure CI is green.**
   Open the `windows-native` branch in GitHub Actions → `Windows CI` workflow. All checks
   must pass before tagging.

2. **Run the manual test plan.**
   On a clean Windows 11 22H2+ VM, execute every item in `windows/TEST_PLAN.md`
   (estimated 20 minutes). All boxes must be checked before proceeding.

3. **Update `RELEASE_NOTES.md`.**
   Edit `windows/RELEASE_NOTES.md` to describe the release. This file becomes the GitHub
   Release body automatically via `body_path` in the release workflow.

4. **Bump the installer version.**
   Edit the `#define MyAppVersion` line in `windows/installer/Sanduhr.iss` to match the
   new version number (e.g., `2.0.1`).

5. **Commit and push.**
   ```bash
   git add windows/installer/Sanduhr.iss windows/RELEASE_NOTES.md CHANGELOG.md
   git commit -m "chore: bump to v2.0.1-windows"
   git push origin windows-native
   ```

6. **Tag the release.** Tag format must be `v<semver>-windows` — the release workflow
   only fires on this pattern.
   ```bash
   git tag v2.0.1-windows
   git push origin v2.0.1-windows
   ```

7. **Watch the release workflow.**
   GitHub Actions (`Windows Release` workflow) will:
   - Set up Python 3.11
   - Install dependencies from `requirements-dev.txt`
   - Install Inno Setup 6.2.2 via Chocolatey
   - Run pytest (build is gated — failure aborts)
   - Run `./build.ps1` (PyInstaller → Inno Setup → `build/Sanduhr-Setup-vX.Y.Z.exe`)
   - Upload the `.exe` to a GitHub Release using `RELEASE_NOTES.md` as the body

8. **Verify the artifact.**
   On the GitHub Releases page, confirm:
   - `Sanduhr-Setup-vX.Y.Z.exe` is attached and downloadable
   - File size is non-trivially large (expect ~20–40 MB for a bundled Qt app)
   - The release body matches the contents of `RELEASE_NOTES.md`

<!-- Source: .github/workflows/windows-release.yml, windows/TEST_PLAN.md, windows/installer/Sanduhr.iss, windows/RELEASE_NOTES.md -->

---

## Hotfix Process

Use when a critical bug is found in a released version and a patch must ship without
including in-progress `windows-native` work.

1. **Branch from the release tag.**
   ```bash
   git checkout -b hotfix/v2.0.1-windows v2.0.0-windows
   ```

2. **Apply the fix.** Keep scope minimal — one bug, one commit.

3. **Run tests locally.**
   ```powershell
   cd windows
   pytest
   ```

4. **Build locally to confirm the installer produces.**
   ```powershell
   cd windows
   ./build.ps1
   ```
   Verify `build/Sanduhr-Setup-v2.0.1.exe` is produced and the widget opens.

5. **Bump version, update `RELEASE_NOTES.md`, commit.**
   ```bash
   git add windows/installer/Sanduhr.iss windows/RELEASE_NOTES.md
   git commit -m "fix: <describe fix>"
   ```

6. **Tag and push** — release workflow fires automatically.
   ```bash
   git tag v2.0.1-windows
   git push origin hotfix/v2.0.1-windows v2.0.1-windows
   ```

7. **Cherry-pick the fix back to `windows-native`** after the release is confirmed.
   ```bash
   git checkout windows-native
   git cherry-pick <commit-sha>
   git push origin windows-native
   ```

<!-- Source: .github/workflows/windows-release.yml, windows/build.ps1 -->

---

## Rollback Process

Sanduhr has no server state. "Rolling back" means pointing users to the prior installer.

1. **Identify the last known-good release** on the GitHub Releases page
   (`https://github.com/estevanhernandez-stack-ed/Sanduhr_f-r_Claude/releases`).

2. **Direct the user to download the prior `.exe`** and run it. The Inno Setup installer
   installs over the top without requiring a manual uninstall first (`CloseApplications=yes`
   is set; it will close the running widget before overwriting files).

3. **Settings and history are preserved** — `%APPDATA%\Sanduhr\` is not touched by the
   installer; only the app binaries under `{app}` are replaced.

4. **If the broken release should not be downloadable**, delete or mark the GitHub Release
   as a pre-release to hide it from the "latest" download link. The prior release becomes
   the default.

5. No database migrations, no API configuration changes, no server restarts — nothing else
   is required.

<!-- Source: windows/installer/Sanduhr.iss, .github/workflows/windows-release.yml -->

---

## Startup Procedure (first-run / user install)

1. Download `Sanduhr-Setup-vX.Y.Z.exe` from GitHub Releases.
2. Run the installer. When SmartScreen warns "Windows protected your PC," click
   **More info** → **Run anyway**. This is expected for an unsigned app.
3. Step through the wizard. "Start Menu shortcut" is pre-checked; "Desktop shortcut" and
   "Launch at login" are opt-in.
4. The widget launches automatically after install (post-install task in the `.iss`).
5. On first launch the setup dialog walks through the F12 → DevTools → Application →
   Cookies flow to locate the `sessionKey`.
6. Paste the `sessionKey` → **OK**. The credential is stored in Windows Credential Manager
   under service `com.626labs.sanduhr`. Usage bars appear within ~5 seconds.

**v1 upgrade path:** If `~/.claude-usage-widget/config.json` exists from v1, the
credentials module migrates the session key, theme, and history automatically on first
launch. The old config file is deleted; history lands in `%APPDATA%\Sanduhr\history.json`.

<!-- Source: windows/TEST_PLAN.md, windows/RELEASE_NOTES.md, windows/installer/Sanduhr.iss -->

---

## Health Checks

Sanduhr is a desktop widget, not a hosted service. "Health" is observable from the widget
itself and from log files:

| Signal | Healthy | Unhealthy |
|---|---|---|
| Status bar | Shows tier bars with percentages | "Session expired", "Cloudflare", or "Network error" text |
| Auto-refresh | Bars update silently every 5 min | Stale data / timestamp never advances |
| Credential Manager | `com.626labs.sanduhr` entry exists in Windows Credential Manager | Missing or blank — triggers re-auth prompt |
| Log file | `%APPDATA%\Sanduhr\sanduhr.log` exists, no ERROR lines | ERROR or CRITICAL lines present |

**Quick diagnostic:**
```powershell
# Check log for errors
Get-Content "$env:APPDATA\Sanduhr\sanduhr.log" | Select-String -Pattern "ERROR|CRITICAL"

# Confirm credential entry exists
cmdkey /list | Select-String "sanduhr"
```

<!-- Source: windows/TEST_PLAN.md, windows/installer/Sanduhr.iss, docs/superpowers/specs/2026-04-16-windows-v2-diamond-design.md -->

---

## Common Issues and Remediation

### SmartScreen warning on install

**Symptom:** "Windows protected your PC" dialog when running the `.exe` installer.

**Cause:** The installer is not code-signed (intentional for v2.0 — see design doc
non-goals).

**Fix:** Click **More info** → **Run anyway**. This is expected behavior and not a
security issue for users who downloaded from the official GitHub Releases URL.

<!-- Source: windows/RELEASE_NOTES.md, windows/TEST_PLAN.md -->

---

### Session expired

**Symptom:** Widget status bar shows "Session expired — click Key."

**Cause:** The `sessionKey` cookie from `claude.ai` has expired or been invalidated (e.g.,
the user signed out of claude.ai in their browser).

**Fix:**
1. Open claude.ai in a browser and ensure you are logged in.
2. Open DevTools (F12) → **Application** → **Cookies** → `claude.ai`.
3. Copy the `sessionKey` value.
4. Click the **Key** button in the widget title bar (or right-click → **Credentials**).
5. Paste the new `sessionKey` → **OK**. The widget recovers within ~5 seconds.

<!-- Source: windows/TEST_PLAN.md -->

---

### Cloudflare block

**Symptom:** Widget status bar shows "Cloudflare — add cf_clearance (click Key)."

**Cause:** Cloudflare's bot detection has flagged the API request. The `cf_clearance`
cookie bypasses this.

**Fix:**
1. Open claude.ai in a browser and browse normally until the Cloudflare challenge resolves.
2. Open DevTools → **Application** → **Cookies** → `claude.ai`.
3. Copy the `cf_clearance` cookie value.
4. Click **Key** in the widget — the credentials dialog opens with the `cf_clearance`
   field.
5. Paste the value → **OK**. The widget recovers on the next refresh.

**Note:** `cf_clearance` cookies expire. If this recurs, repeat the process.

<!-- Source: windows/TEST_PLAN.md -->

---

### Network error / widget not updating

**Symptom:** Bars are stale or show a network error status. `sanduhr.log` contains
`NetworkError` entries.

**Triage:**
1. Confirm `claude.ai` is reachable in a browser.
2. Check `%APPDATA%\Sanduhr\sanduhr.log` for the specific error.
3. Check `%APPDATA%\Sanduhr\last_error.json` if it exists — it captures the last exception
   details for crash triage.
4. If the error is intermittent (e.g., a brief outage), click **Refresh** to force a
   retry.

<!-- Source: windows/TEST_PLAN.md, docs/superpowers/specs/2026-04-16-windows-v2-diamond-design.md -->

---

### Credential Manager corruption / re-auth loop

**Symptom:** Widget immediately shows "Session expired" even after pasting a valid key.
Credentials do not persist between restarts.

**Fix:** Clear the Credential Manager entry manually and re-enter credentials.

```powershell
cmdkey /delete:com.626labs.sanduhr
```

Then relaunch Sanduhr and re-enter the `sessionKey` via the Key dialog.

**Note:** The uninstaller always runs `cmdkey /delete:com.626labs.sanduhr` automatically
(as a hidden step in `[UninstallRun]`). If uninstalling and reinstalling doesn't clear a
corrupt entry, run the command above manually.

<!-- Source: windows/installer/Sanduhr.iss -->

---

### Mica backdrop not showing (Win10 / unsupported build)

**Symptom:** Widget has a solid background instead of the translucent Mica effect.

**Expected behavior:** This is by design. Mica requires Windows 11 22H2+. On Windows 10
or unsupported builds the widget falls back to the theme's solid `bg` color. No crash, no
visual glitch — just no translucency.

<!-- Source: windows/TEST_PLAN.md, docs/superpowers/specs/2026-04-16-windows-v2-diamond-design.md -->

---

## Log Locations and Diagnostics

| File | Path | Contents |
|---|---|---|
| Application log | `%APPDATA%\Sanduhr\sanduhr.log` | Runtime events, errors, refresh cycles |
| Last error | `%APPDATA%\Sanduhr\last_error.json` | Last exception — type, message, traceback |
| Sparkline history | `%APPDATA%\Sanduhr\history.json` | 24-point rolling usage windows per tier |
| Window / theme settings | `%APPDATA%\Sanduhr\settings.json` | Last window position, active theme |

**To enable debug output (verbose console tracebacks):**
Build with the `-DebugBuild` flag; this keeps the console window open during execution:
```powershell
cd windows
./build.ps1 -DebugBuild
.\dist\Sanduhr\Sanduhr.exe
```

Alternatively, run directly from source:
```powershell
cd windows
python -m sanduhr
```

<!-- Source: windows/build.ps1, windows/installer/Sanduhr.iss, docs/superpowers/specs/2026-04-16-windows-v2-diamond-design.md -->

---

## Credentials Management

Credentials are stored in Windows Credential Manager (not in any file on disk).

| Account | Contents |
|---|---|
| `sessionKey` | The claude.ai session cookie |
| `cf_clearance` | Optional Cloudflare bypass cookie |

**Service name:** `com.626labs.sanduhr`

**View entries:**
```powershell
cmdkey /list | Select-String "sanduhr"
```

**Delete entries manually:**
```powershell
cmdkey /delete:com.626labs.sanduhr
```

**The uninstaller deletes these automatically.** If the user checks "Also remove my settings
and history" in the uninstall wizard, `%APPDATA%\Sanduhr\` is also deleted.

<!-- Source: windows/installer/Sanduhr.iss, CHANGELOG.md -->

---

## CI / Release Workflow Failures

### pytest fails in release workflow

The release workflow gates the build on `pytest`. If tests fail, the `.exe` is never
produced and the GitHub Release is not created.

**Fix:** Investigate the test failure in the Actions log, fix the code or test, push a new
commit to the hotfix/feature branch, then re-tag.

```bash
# Delete the failed tag, fix the issue, re-tag
git push --delete origin v2.0.1-windows
git tag -d v2.0.1-windows
# ... fix and commit ...
git tag v2.0.1-windows
git push origin v2.0.1-windows
```

### Build step fails (`build.ps1` or Inno Setup)

Check the Actions log for the "Build installer" step. Common causes:
- PyInstaller can't find an import — check `sanduhr.spec` hidden imports
- Inno Setup `.iss` references a file that doesn't exist in `dist/Sanduhr/`

Fix the root cause, delete the tag, and re-tag as above.

### Release artifact upload fails

If `softprops/action-gh-release` fails with "file not found," the `OutputBaseFilename` in
`Sanduhr.iss` didn't match the version extracted from the tag. Verify that the `#define
MyAppVersion` in `Sanduhr.iss` exactly matches the semver in the tag (without the leading
`v` and without the `-windows` suffix).

### Re-running a failed workflow

GitHub does not support re-running a workflow on the same tag after a code fix. You must
delete the tag, fix the issue, and push a new tag. The release (if partially created) may
need to be manually deleted from the GitHub Releases page first.

<!-- Source: .github/workflows/windows-release.yml, windows/build.ps1, windows/installer/Sanduhr.iss -->

---

## Escalation Path

Solo project — GitHub Issues is the entire escalation path.

- **Bugs, crashes, install failures:** file at `https://github.com/estevanhernandez-stack-ed/Sanduhr_f-r_Claude/issues`
- **Triage:** repository owner reviews and labels; no on-call rotation, no severity tiers
- **CI / release artifact missing from a tag:** owner re-runs the workflow manually from the Actions tab, or re-tags if a fix is needed

Revisit this section if the project gains contributors or goes public enough to need a formal on-call / severity matrix.
<!-- Source: user confirmation during vibe-doc interview 2026-04-16 -->
