maintenance(harness): [WR-18897] Local AI coding harness (Ollama + Hermes + rs-agents)#50
Conversation
…nsions, quiet system_profiler From the Mac Mini provisioning review (WR-18897): - onboard.sh: add envrc_is_sourceable() so a malformed/old-template .envrc is backed up and regenerated instead of silently adopted — the bug that skipped the prompt and spammed "command not found" on every new shell. Prompt logic extracted into generate_envrc(). - extensions_base.txt: remove GitHub.copilot-chat (now a built-in extension, install conflicts), stkb.rewrap (fails marketplace signature verification), and ms-vscode-remote.remote-wsl (Windows-only, no-op on macOS). - starship.zsh: redirect system_profiler stderr to /dev/null so its hw.cpufamily diagnostic stops leaking into every new shell. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…COMPANY path resolve_repo used CURRENT_COMPANY from the calling shell's environment to decide the clone path, then ensure_envrc prompted the user for the real value — too late. If the calling shell had a stale CURRENT_COMPANY (e.g. from a prior job), the repo landed in the wrong directory and every alias derived from it resolved to a corrupt path. Fix: introduce collect_machine_vars, which runs before resolve_repo. It sources any existing valid .envrc (fast no-op on re-runs) or prompts the user and writes ~/.envrc, then sources it so CURRENT_COMPANY is correct before any path decision is made. ensure_envrc (post-clone) then moves ~/.envrc into $REPO_DIR as before. Additional hardening: - CURRENT_COMPANY prompt default is hardcoded to "Retail-Success" (the correct value for this repo), so a stale env var can never silently win. - IDE_PATH defaults to "code" (VS Code CLI); stale "vscode" values are normalised at both init and post-prompt time. - generate_envrc checks ~/.envrc first to prevent double-prompting on the malformed-repo-.envrc edge case. - Generated .envrc now covers the full variable set from .envrc.example (adds JIRA_API_TOKEN placeholder and GIT_EMAIL_ADDRESS_PERSONAL). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…script Stands up the Docker MCP gateway (stdio, no url/auth) and wires Claude Code to it, replicating the default profile's enabled servers. Includes interactive secret setup and a reboot-survival checklist (auto-login, Docker autostart, sleep prevention, keychain). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ed development support.
…Hermes Agent support.
…ocumentation for Mac Mini setup.
…ardening Signed-off-by: Andrew Barrows <acbarrows@gmail.com>
…+ Hermes + rs-agents) Provision a local AI coding harness — Ollama local models behind the Hermes agent harness, with rs-agents skills synced in: - provision-coding-harness.sh: idempotent, --dry-run; RAM-sized model choice (qwen2.5-coder:7b on <32GB laptops, llama3.1:8b on the 32GB+ mini), Ollama service, model pulls, Hermes config (model + 64K context knobs), skill sync, health check. - sync-rs-agents-to-hermes.sh: mirror rs-agents skills from the installed Claude Code plugin into ~/.hermes/skills (Hermes' equivalent of `reload plugins`). - com.retailsuccess.ollama.plist: always-on launchd unit (perf env vars) for the 24/7 mini; intentionally not loaded on a 16GB laptop. - verify-ollama-hermes.sh: layered PASS/FAIL harness check (tools + 64K context + local routing + memory fit + skill-following). - meta/profiles/ai + meta/configs/hermes.yml + install-hermes-agent.sh: install Hermes via the `ai` profile. - DRY-RUN-PLAN.md / OLLAMA-HERMES-RUNBOOK.md: the plan + the validated runbook. - .yamllint.yml: fix rules nesting; CLAUDE.md/README: document the `ai` profile. Counterpart rs-agents skill guidance: Wayroo.tools#46 (WR-18915), epic WR-18831. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reviewer's GuideAdds a local AI coding harness to the dotfiles: Ollama models managed as a service, Hermes configured to use them with rs-agents skills mirrored in, plus scripts and docs to provision and verify the setup and an 'ai' dotbot profile to install Hermes via onboarding. Sequence diagram for verifying the Ollama + Hermes harnesssequenceDiagram
actor User
participant verify_ollama_hermes_sh
participant Ollama
participant Hermes
participant rs_agents_skills
User->>verify_ollama_hermes_sh: run verify-ollama-hermes.sh
verify_ollama_hermes_sh->>Ollama: curl /api/tags
verify_ollama_hermes_sh->>Ollama: ollama_show MODEL
verify_ollama_hermes_sh->>Ollama: curl /v1/chat/completions
verify_ollama_hermes_sh->>Hermes: hermes -z "math ping"
Hermes->>Ollama: POST /v1/chat/completions
Ollama-->>Hermes: completion
Hermes-->>verify_ollama_hermes_sh: output
verify_ollama_hermes_sh->>Hermes: hermes_skills_list
Hermes->>rs_agents_skills: load commit-conventions SKILL.md
verify_ollama_hermes_sh->>Hermes: hermes -z "use commit-conventions"
Hermes->>Ollama: POST /v1/chat/completions
Ollama-->>Hermes: skill-shaped completion
Hermes-->>verify_ollama_hermes_sh: commit message
verify_ollama_hermes_sh-->>User: PASS/FAIL summary
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues, and left some high level feedback:
- provision-coding-harness.sh hardcodes paths to /opt/homebrew/bin/ollama and the Hermes venv python, which may not exist or may change; consider resolving these via command -v or a config variable instead of fixed paths.
- verify-ollama-hermes.sh expects an Ollama serve log at /tmp/ollama-spike.log for local-routing proof, but the harness never writes to that path (other scripts log to /tmp/ollama.out.log); aligning the log location or wiring it explicitly would make the verification more reliable.
- sync-rs-agents-to-hermes.sh assumes a specific Claude plugin cache layout under ~/.claude/plugins/cache//rs-agents//skills; making the source path configurable or adding more explicit diagnostics when no skills are found would reduce brittleness if the plugin structure changes.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- provision-coding-harness.sh hardcodes paths to /opt/homebrew/bin/ollama and the Hermes venv python, which may not exist or may change; consider resolving these via command -v or a config variable instead of fixed paths.
- verify-ollama-hermes.sh expects an Ollama serve log at /tmp/ollama-spike.log for local-routing proof, but the harness never writes to that path (other scripts log to /tmp/ollama.out.log); aligning the log location or wiring it explicitly would make the verification more reliable.
- sync-rs-agents-to-hermes.sh assumes a specific Claude plugin cache layout under ~/.claude/plugins/cache/*/rs-agents/*/skills; making the source path configurable or adding more explicit diagnostics when no skills are found would reduce brittleness if the plugin structure changes.
## Individual Comments
### Comment 1
<location path="mac-mini-agent/provision-coding-harness.sh" line_range="43-52" />
<code_context>
+command -v "$OLLAMA_BIN" >/dev/null || { warn "ollama not installed — 'brew install ollama' (or run the Brewfile)."; exit 1; }
</code_context>
<issue_to_address>
**issue (bug_risk):** Use a consistent path for Ollama (`$OLLAMA_BIN` vs `ollama`) to avoid PATH-related failures.
You correctly verify and start Ollama via `$OLLAMA_BIN`, but later commands (`ollama list`, `ollama pull`) assume `ollama` is on `PATH`. On systems where Homebrew’s `bin` isn’t yet on `PATH`, these will fail despite the binary existing. Either export `PATH` to include `/opt/homebrew/bin` here, or consistently call `"$OLLAMA_BIN" list/pull ...` to avoid these PATH-dependent failures.
</issue_to_address>
### Comment 2
<location path="mac-mini-agent/verify-ollama-hermes.sh" line_range="17" />
<code_context>
+CFG="$HOME/.hermes/config.yaml"
+MODEL="${1:-$(awk '/^model:/{m=1;next} m&&/default:/{print $2; exit}' "$CFG")}"
+MARK="===VERIFY $(date +%H%M%S)==="
+SLOG=/tmp/ollama-spike.log # the ollama serve log (used to prove a local hit)
+FAILED=0
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The Ollama log path here doesn't match the launchd plist, breaking the local-hit proof.
This script writes the verification marker to `/tmp/ollama-spike.log`, but the `com.retailsuccess.ollama.plist` launchd unit logs to `/tmp/ollama.out.log` and `/tmp/ollama.err.log`. With launchd, the check will always fail because the marker is never written to the files being tailed. Please either point `SLOG` to the launchd log file(s) or update the plist to log to `ollama-spike.log` so the local-hit proof actually works when using launchd.
</issue_to_address>
### Comment 3
<location path="mac-mini-agent/verify-ollama-hermes.sh" line_range="13-18" />
<code_context>
+
+OLLAMA_URL="${OLLAMA_URL:-http://localhost:11434}"
+CFG="$HOME/.hermes/config.yaml"
+MODEL="${1:-$(awk '/^model:/{m=1;next} m&&/default:/{print $2; exit}' "$CFG")}"
+MARK="===VERIFY $(date +%H%M%S)==="
+SLOG=/tmp/ollama-spike.log # the ollama serve log (used to prove a local hit)
</code_context>
<issue_to_address>
**suggestion:** Handle missing/invalid Hermes config more explicitly when deriving the default model.
If `~/.hermes/config.yaml` is missing, unreadable, or lacks a `model: default:` entry, `awk` returns an empty string and `MODEL` is empty, so `ollama show "$MODEL"` and similar calls will fail in a non-obvious way. Consider checking for an empty `MODEL` immediately after deriving it and exiting with a clear error message so configuration problems are easier to diagnose.
```suggestion
OLLAMA_URL="${OLLAMA_URL:-http://localhost:11434}"
CFG="$HOME/.hermes/config.yaml"
MODEL="${1:-$(awk '/^model:/{m=1;next} m&&/default:/{print $2; exit}' "$CFG")}"
if [ -z "$MODEL" ]; then
echo "Error: no default model could be derived." >&2
echo " Checked Hermes config: $CFG" >&2
echo " Expected a 'model:' section with a 'default:' entry, or a model argument:" >&2
echo " $0 <model>" >&2
exit 1
fi
MARK="===VERIFY $(date +%H%M%S)==="
SLOG=/tmp/ollama-spike.log # the ollama serve log (used to prove a local hit)
FAILED=0
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| command -v "$OLLAMA_BIN" >/dev/null || { warn "ollama not installed — 'brew install ollama' (or run the Brewfile)."; exit 1; } | ||
| command -v hermes >/dev/null || { warn "hermes not installed — run onboarding_bin/install-hermes-agent.sh first."; exit 1; } | ||
| bold " ollama: $($OLLAMA_BIN --version 2>/dev/null | head -1)" | ||
| bold " hermes: $(hermes --version 2>/dev/null | head -1)" | ||
|
|
||
| if (( RAM_GB >= 32 )); then MODEL="llama3.1:8b"; else MODEL="qwen2.5-coder:7b"; fi | ||
| SMOKE="llama3.2:3b" | ||
| bold " chosen default model: ${MODEL} (smoke: ${SMOKE})" | ||
|
|
||
| # ── 1. Ollama service ──────────────────────────────────────────────────────── |
There was a problem hiding this comment.
issue (bug_risk): Use a consistent path for Ollama ($OLLAMA_BIN vs ollama) to avoid PATH-related failures.
You correctly verify and start Ollama via $OLLAMA_BIN, but later commands (ollama list, ollama pull) assume ollama is on PATH. On systems where Homebrew’s bin isn’t yet on PATH, these will fail despite the binary existing. Either export PATH to include /opt/homebrew/bin here, or consistently call "$OLLAMA_BIN" list/pull ... to avoid these PATH-dependent failures.
| CFG="$HOME/.hermes/config.yaml" | ||
| MODEL="${1:-$(awk '/^model:/{m=1;next} m&&/default:/{print $2; exit}' "$CFG")}" | ||
| MARK="===VERIFY $(date +%H%M%S)===" | ||
| SLOG=/tmp/ollama-spike.log # the ollama serve log (used to prove a local hit) |
There was a problem hiding this comment.
issue (bug_risk): The Ollama log path here doesn't match the launchd plist, breaking the local-hit proof.
This script writes the verification marker to /tmp/ollama-spike.log, but the com.retailsuccess.ollama.plist launchd unit logs to /tmp/ollama.out.log and /tmp/ollama.err.log. With launchd, the check will always fail because the marker is never written to the files being tailed. Please either point SLOG to the launchd log file(s) or update the plist to log to ollama-spike.log so the local-hit proof actually works when using launchd.
…es onboarding install-hermes-agent.sh now runs the rs-agents skills sync (best-effort, --soft) so a fresh Hermes install auto-connects rs-agents. Note: Hermes cannot consume the rs-agents Claude Code plugin via 'hermes plugins' (that expects Python provider plugins) — rs-agents reaches Hermes through its SKILLS. Sync gains a Wayroo.tools-clone fallback (RS_AGENTS_SKILLS_SRC) and a --soft mode that never fails the install. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…+ auto-resync to Hermes Keep Hermes in lockstep with the rs-agents plugin as skills change upstream: - install-claude-plugins.sh: register the marketplace + install rs-agents (non-interactive, tries retailsuccess@ then wayroo@ marketplace names). Claude Code then auto-updates it on startup (marketplace autoUpdate). - install-hermes-agent.sh: onboarding now installs the plugin THEN mirrors its skills into Hermes. - provision-coding-harness.sh: adds a launchd timer (com.retailsuccess.rs-agents-sync, RunAtLoad + hourly) that re-runs the clean-rebuild sync, so add/modify/DELETE all propagate to Hermes hands-free. - sync: PATH export so it resolves hermes under launchd's minimal env. Only SKILLS port to Hermes (agents/workflows/memories are Claude Code constructs). Source of truth stays Wayroo.tools; requires the plugin version be bumped per release for autoUpdate to pull changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e settings for code actions on save. maintenance(profiles): Added AI profile to base profiles. story(onboarding): Added script to connect Hermes to Docker MCP Toolkit gateway and updated installation script. maintenance(git): Updated .gitignore to exclude local Claude settings.
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Andrew Barrows <acbarrows@gmail.com>
…dditional Bash commands and YAML validations for Hermes integration.
…ardening Signed-off-by: Andrew Barrows <acbarrows@gmail.com>
…c-mini-agent scripts Validated all Sourcery callouts (rs-agents code-reviewer) and fixed the real ones: - provision-coding-harness.sh: export Homebrew-inclusive PATH (Apple-silicon + Intel), resolve OLLAMA_BIN via command -v (env-overridable), guard HERMES_PY existence, and call "$OLLAMA_BIN" consistently for list/pull. - verify-ollama-hermes.sh: point the local-routing proof at the logs Ollama actually writes (launchd err.log / on-demand out.log) instead of the never-written ollama-spike.log; hard-FAIL when neither local proof produces evidence; abort clearly on an empty MODEL; strip YAML quotes when deriving model.default. - sync-rs-agents-to-hermes.sh: stage the mirror in a temp dir and swap only on a non-empty copy, so a restructured/empty plugin source can never silently wipe the working Hermes skill set (the sync runs hourly via launchd); guard the zero-match grep -c pipeline under pipefail. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
Adds the local AI coding harness to the dotfiles: Ollama local models behind the Hermes agent harness, with rs-agents skills synced in. This is the infrastructure half of the local-AI work; the portable skill guidance ships separately in Wayroo.tools#46 (WR-18915, epic WR-18831).
Jira: WR-18897.
What's included
mac-mini-agent/provision-coding-harness.sh--dry-run). RAM-sizes the model, sets up Ollama, pulls models, configures Hermes, syncs skills, health-checks.mac-mini-agent/sync-rs-agents-to-hermes.sh~/.hermes/skills(Hermes' equivalent ofreload plugins).mac-mini-agent/com.retailsuccess.ollama.plistmac-mini-agent/verify-ollama-hermes.shmeta/profiles/ai,meta/configs/hermes.yml,onboarding_bin/install-hermes-agent.shaiprofile.mac-mini-agent/DRY-RUN-PLAN.md,OLLAMA-HERMES-RUNBOOK.md.yamllint.yml,CLAUDE.md,README.mdrules:fix; document theaiprofile.Key design decisions (validated on rss-mbp-5, M4, 16 GB)
qwen2.5-coder:7bon <32 GB laptops (fits, ~32K effective);llama3.1:8bon the 32 GB+ mini (true 128K).llama3.1:8b@64k needs ~9.4 GB and thrashes 16 GB into swap — so it's mini-only.context_length+ollama_num_ctxknobs for 32K-native models).reload plugins; Hermes via this bridge). 59 skills sync into a ~8 KB on-demand index (no prompt bloat).Honest limitation
Local 7B skill-use is rough: the model applies rs-agents skill content correctly (e.g.
fix(onboard.sh): … [WR-18897]) but often wraps it in a raw tool-call, and a call takes ~2 min. The local harness is for cheap/offline/private work; live orchestration stays on Claude Code.Test plan
Excludes local-only
.claude/settings.local.jsonand.vscode/.🤖 Generated with Claude Code
Summary by Sourcery
Provision and document a local AI coding harness for macOS that wires Ollama models into the Hermes agent, syncs rs-agents skills, and integrates this setup into the dotfiles via an
aiprofile and supporting scripts, with validation and dry-run support for the Mac mini agent environment.New Features:
Enhancements:
Documentation:
aiprofile, Hermes installation flow, and the local AI coding harness architecture and runbooks in project markdown files.Tests: