docs: OAuth providers in credential pool + project-shadowed Hermes detector

Alan Wizemann
2026-04-27 22:49:14 +02:00
parent 703d5d6ccc
commit 15d2035511
2 changed files with 19 additions and 1 deletions
+6
@@ -46,6 +46,12 @@ In v2.5 most service code moved out of the Mac target into the shared **ScarfCor
| `CitadelSSHService` | Pure-Swift Ed25519 keypair generation + connection probes via Citadel. Used by Onboarding's "Generate Key" + "Test Connection" steps. | | `CitadelSSHService` | Pure-Swift Ed25519 keypair generation + connection probes via Citadel. Used by Onboarding's "Generate Key" + "Test Connection" steps. |
| `CitadelServerTransport` | Citadel-backed implementation of `ServerTransport` — drives `executeCommandStream` for resilient stdout capture (preserves output on non-zero exit) and prepends `PATH=$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:$PATH` so non-interactive sessions resolve `hermes` and its sub-tools without sourcing user shell rc files. _v2.5.2:_ exposes `cachedSnapshotPath` so `HermesDataService` can fall back to the on-disk snapshot when an SSH pull fails. | | `CitadelServerTransport` | Citadel-backed implementation of `ServerTransport` — drives `executeCommandStream` for resilient stdout capture (preserves output on non-zero exit) and prepends `PATH=$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:$PATH` so non-interactive sessions resolve `hermes` and its sub-tools without sourcing user shell rc files. _v2.5.2:_ exposes `cachedSnapshotPath` so `HermesDataService` can fall back to the on-disk snapshot when an SSH pull fails. |
## v2.5.2 additions (in ScarfCore)
| Service | Isolation | Purpose |
|---|---|---|
| `ProjectHermesShadowDetector` | `Sendable struct` | Detects projects whose directory contains a `<project>/.hermes/` subdirectory. Hermes' CLI uses the closest `.hermes/` as `$HERMES_HOME` when invoked from inside such a project — credentials, config, sessions all bind to the project-local copy without warning, leaving Scarf's global probes ("No AI provider credentials detected") confusingly wrong. The detector enumerates registered projects via the transport, stats `<project>/.hermes/` for existence + directory-ness, and reports auth.json / state.db presence flags per shadow. Mac Dashboard surfaces the result as a yellow banner with a per-project "Copy fix command" affordance that emits the one-line consolidation command. Read-only — no auto-migration, the user decides what to keep. |
## v2.5.2 additions (iOS-only — in ScarfIOS) ## v2.5.2 additions (iOS-only — in ScarfIOS)
| Service | Purpose | | Service | Purpose |
+13 -1
@@ -47,7 +47,19 @@ If the connection pill is green but the Dashboard shows "Stopped", "unknown", or
For the "profile is active" case the popover includes a copy-paste `hermes profile use default` command. See [Projects & Profiles](Projects-and-Profiles) for the full Hermes v0.11 profile model. For the "profile is active" case the popover includes a copy-paste `hermes profile use default` command. See [Projects & Profiles](Projects-and-Profiles) for the full Hermes v0.11 profile model.
**Pill probes `state.db`, not `config.yaml`** _(v2.5.2+)._ The tier-2 readability check now targets `~/.hermes/state.db` because that's the file Scarf actively reads on every Dashboard / Sessions / Chat tick. Hermes v0.11+ doesn't materialize `config.yaml` until the user explicitly changes a setting — a freshly-installed working Hermes would otherwise be marked "degraded — config missing" indefinitely. `state.db` is created on the first agent run and is the actual surface Scarf depends on. **Pill probes `state.db`, not `config.yaml`** _(v2.5.2+)._ The tier-2 readability check now targets `~/.hermes/state.db` because that's the file Scarf actively reads on every Dashboard / Sessions / Chat tick. Hermes v0.11+ doesn't materialize `config.yaml` until the user explicitly changes a setting — a freshly-installed working Hermes would otherwise be marked "degraded — config missing" indefinitely. `state.db` is created on the first agent run and is the actual surface Scarf depends on. The Manage Servers → Run Diagnostics sheet treats `config.yaml` checks the same way: present-and-readable PASS, exists-but-unreadable FAIL, and missing-entirely SKIP (informational, doesn't drag the score).
## Project-shadowed Hermes home _(v2.5.2+)_
Hermes' CLI uses the closest `.hermes/` directory as `$HERMES_HOME` when invoked from inside a directory that has one. If a registered Scarf project carries its own `<project>/.hermes/` (commonly because it was seeded from another machine, checked into git, or because Hermes' first-run setup happened with that directory as `cwd`), every `hermes` invocation from inside that project silently binds to the project-local home — credentials, config, sessions, skills, and memories all land there instead of `~/.hermes/`.
Symptoms users hit:
- They run `hermes auth add nous` during setup; Scarf's Credential Pools view never sees Nous and the Chat tab keeps showing "No AI provider credentials detected."
- New chats started outside that project don't have access to credentials the user thought they registered.
- Dashboard stats, Sessions, and Activity reflect only the global `state.db` while the agent's actual work is being persisted into the project-local one.
The Mac Dashboard surfaces a yellow banner ("Project-local Hermes home shadowing global setup") listing every affected project with `auth.json present` / `state.db present` chips. Each row has a **Copy fix command** button that emits a one-liner like `cp <project>/.hermes/auth.json ~/.hermes/auth.json && chmod 600 ~/.hermes/auth.json` for the user to run on the remote — Scarf doesn't auto-migrate because picking which project-local files to keep vs. discard requires user judgement (e.g. an in-flight session might be worth importing rather than abandoning). Once auth.json is consolidated, the next probe tick clears the banner and the credential pool / chat surfaces pick up the provider.
**Manage Servers → 🩺 Run Diagnostics** runs **fourteen** checks in one SSH session: connectivity, `sqlite3` presence, read access to `config.yaml` and `state.db`, the effective non-login `$PATH`, etc. Each failure explains itself with a remediation hint. **Copy Full Report** dumps the whole output for bug reports. **Manage Servers → 🩺 Run Diagnostics** runs **fourteen** checks in one SSH session: connectivity, `sqlite3` presence, read access to `config.yaml` and `state.db`, the effective non-login `$PATH`, etc. Each failure explains itself with a remediation hint. **Copy Full Report** dumps the whole output for bug reports.