Live Mailprotector CloudFilter REST client (emailservice.io/api/v1,
Bearer auth via vault msp-tools/mailprotector.sops.yaml). Lists mail-flow
logs and held/quarantined messages across client domains and releases them
(POST messages/{id}/deliver, deliver_many). Read-only by default; every
release/rule-add/config-change gated behind --confirm. Mirrors the
packetdial skill pattern. Built after diagnosing a Dataforth held-outbound
message that never reached ACG.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
role_assigned() sent an unencoded space in the OData $filter
(principalId eq '...'), so the query always failed and the function
always returned false -> onboard-tenant.sh always printed
"MISSING -> ASSIGNING" and relied on the conflict-tolerant POST for
idempotency. Fixed to %20; corrected the stale PIM-misdiagnosis comment.
Verified live against the ACG tenant. Roles still assign correctly;
PRESENT/MISSING reporting is now accurate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sibling of the grok skill: routes text/verify/review (+ review-files,
review-diff, raw) to the official Google Gemini CLI (gemini, npm global,
v0.45.1) for an independent second model. ask-gemini.sh mirrors ask-grok.sh
(identity-aware gating, binary auto-locate, cygpath hardening, prompt-file
inputs, clean stdout/stderr separation, JSON .response extraction). review
modes copy targets into a temp dir + --include-directories to bypass
Gemini's gitignore/workspace sandbox. verify/review pinned to
gemini-3.1-pro-preview (GEMINI_MODEL overridable). migrate-identity.sh
auto-detects gemini and writes a per-machine identity.json gemini block.
Auth: Google OAuth (no key). Fleet Gemini host: GURU-5070.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes the two Windows pain points when routing code review to the Grok CLI
(native Windows grok.exe driven from Git Bash):
- winpath() (cygpath -w; no-op off Windows) on every path handed to grok.exe
(--prompt-file, --cwd) -> deterministic, space-safe; removes reliance on
MSYS's argv auto-conversion heuristic (the 'confounded by Windows paths').
- review mode resolves to an absolute Windows path (handles absolute/spaced paths).
- NEW review-files [-i instr] <f1> [f2...]: review a set of files together.
- NEW review-diff [-C <repo-dir>] [-i instr] <gitref> [-- <pathspec>]: review a
git diff; -C targets submodules (e.g. guru-rmm). Diff goes via --prompt-file,
not a shell arg -> no 'quote hell'.
Tested: text, review (spaced abs path), review-files (2 tray modules),
review-diff (self-review of these changes). SKILL.md updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The ask-grok.sh wrapper script used 'timeout' command which doesn't
exist on macOS by default. Updated to detect macOS (darwin) and use
'gtimeout' from GNU coreutils instead.
Tested on macOS with:
- Text reasoning queries (working)
- Live web + X/Twitter search (working)
Requires: brew install coreutils (provides gtimeout)
- wiki/projects/gururmm.md: beta-first dashboard channels (rmm-beta) + wiring
- .claude/memory: feedback_dashboard_beta_first + index line
- bump guru-rmm submodule pointer to the beta-channel commit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SKILL.md still narrated the 2026-06-01-and-earlier additive-only stance.
With the policy change captured in feedback_memory_sync_destructive_ok.md
and sync-memory.sh now in mirror mode, the framing needed updating.
Behavior of the tool itself is unchanged (--apply-safe still only does
the low-risk index appends + profile->repo copies; merges/dedups still
land in PROPOSED for a human). The reasons given for that are now:
they're judgment calls, not "we might wipe useful data."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops the additive-union semantics that resurrected deliberate deletions
across the fleet (see feedback_memory_sync_destructive_ok.md and the
2026-06-01 consolidation that came back the next morning).
New behavior:
* file in REPO, not in PROFILE -> copy REPO -> PROFILE (unchanged)
* file in PROFILE, not in REPO -> DELETE from PROFILE (was: copy back)
* file in BOTH, identical -> no-op
* file in BOTH, differ -> overwrite PROFILE (was: log conflict)
Safety: aborts if the repo has <5 .md files (guards against a broken
repo wiping the profile store).
Test plan verified on GURU-BEAST-ROG:
* dry-run + apply matched (2 copies + 10 overwrites + 0 deletes)
* idempotent re-run = 79 identical, 0 ops
* self-check memory category PASS
* git status .claude/memory/ clean (script touched profile only)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Commit 4dc4563 had added MEMORY.md entries for the 49 resurrected
orphan files. My deletion commit 720bdd8 removed the files but missed
the matching index lines (read MEMORY.md before the rebase pulled
4dc4563 in). Index now matches the actual on-disk file set.
Self-check: 72 PASS / 0 WARN / 1 FAIL (autotask manifest issue
remains, not fixable on this machine).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 39 files I deleted in 0c00010 got resurrected by sync-memory.sh on
GURU-5070 (f8ed03c) because the script is additive-only. Re-deleted them
(49 files this time -- some additional drift between machines).
Also added feedback_memory_sync_destructive_ok.md capturing the policy
shift: with everyone onboarded, the memory tooling no longer needs
additive-only safety. memory-dream may apply proposed merges/deletions
and sync-memory.sh should propagate repo-side deletions back to profile
stores. Script updates to honor that are still pending -- without them,
this round of cleanup is also vulnerable to resurrection.
Self-check: 0 WARN, 1 FAIL remaining (autotask command -- manifest issue,
not fixable on this machine; needs Mike to either un-localize /autotask
or move it to capability-gated in baseline/manifest.json).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Applied memory-dream --apply-safe to resolve orphan warning from self-check.
- Added all 49 orphaned feedback/project/reference memories to index
- Index now complete with all 127 memory files properly referenced
This resolves the WARN from self-check about orphaned memory files.
The winget jq build on Windows emits CRLF; a trailing \r silently corrupts
`for x in $(jq ...)` loops and read-from-@tsv fields (single-value $() hides it).
Fix: override `jq(){ command jq "$@" | tr -d '\r'; }`. Windows-build-specific,
so it passes review on Mac/Linux. First hit + fix: the self-check skill engine.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New /self-check skill: each machine probes its own ClaudeTools harness wiring
(identity.json paths, required tooling, settings.json hooks, skill/command/script
set, vault decrypt, coord/Gitea connectivity, Ollama capability tier) and grades
RED/AMBER/GREEN against a checked-in provisional baseline manifest.
- Capability-tier model: architectural/OS/hardware differences (e.g. no local
Ollama) select a fallback ruleset instead of failing.
- Duplicate detection: flags command/skill names that diverge between the repo
and ~/.claude (the "same /cmd, different behaviour" cross-machine bug);
CRLF-only diffs ignored.
- Memory check: index + orphan detection, plus a model-driven semantic pass for
memories that contradict identity/settings.
- V1 is a census tool: --publish writes a per-machine census to coord
(component selfcheck_<host>); fanout requests the fleet to self-check +
self-remediate + re-publish; aggregate derives the proposed baseline. No
machine ever fixes another.
Reviewed twice by the Code Review Agent; three CRITICAL coord-API bugs and the
CRLF false-WARN found and fixed, verified live against the coord API.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jq -r '.stdout' returns the literal string "null" when the API field is JSON
null, causing the RESULT: grep to fail and fire a false drift alert. Fixes:
- Use `.stdout // empty` so null becomes empty string
- Add FINAL_ST tracking; treat non-terminal status as INFRA-ERROR, not drift
- Increase poll window from 20x4s=80s to 30x4s=120s for slow commands
- Read .stderr and .exit_code; include them in the no-RESULT diagnostic
Live check 2026-06-02: KSTEENBB2025 is PASS (today's alert was a false positive).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Live Sonnet-subagent recompile test inlined real passwords/PSK/RADIUS
secret from a session log into the article; review caught it. Added rule
6b to the synthesis brief: wiki references vault paths only, never raw
secrets (carry-over of values the existing article already discloses is
the only exception).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Seed/full synthesis in /wiki-compile (and the /save Phase 3 recompile) now
delegates the draft to a Sonnet subagent (model: "sonnet") instead of
Ollama qwen3 — better prose quality, no local-Ollama dependency. Refresh
mode unchanged (surgical, no model). Main agent still reviews the draft
before writing (billing/IPs/vault-paths; Patterns/History preserved).
Softfail now keys on subagent unavailability -> surgical refresh.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
/save now full-recompiles the worked-on article (Ollama, preserving
Patterns/History) so the session's findings land in the wiki, not just
dynamic fields. Seeds the article if missing. Softfalls to a surgical
refresh when Ollama is down so a save is never blocked. Still pre-sync,
so the article ships in the same commit; /scc inherits via /save logic.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
/save now refreshes the client/project wiki article (refresh-only: live
Syncro fields, sources, last_compiled -- never narrative/Patterns/History)
before sync.sh, so the article + index ship in the same commit as the
session log. Skips root/general scope; suggests /wiki-compile seed when no
article exists; softfails so a wiki hiccup never blocks the save. Folds in
the old post-sync unseeded-wiki check. /scc inherits via /save logic.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
compute_output_path now parses .gitmodules and, for a project scope whose
dir is a submodule (guru-rmm, guru-connect, youtube-sync-docker), falls
back to the MAIN repo root session-logs/ per convention. Non-submodule
projects (gururmm-agent, dataforth-dos) unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reconstructs session logs from Claude Code transcripts when a session
crashes or is closed before /save. Two entry points:
- /recover <uuid|latest> : manual, Claude-reviewed reconstruction
- detect_orphaned_sessions.py : scheduled scan that auto-builds logs for
substantive, unsaved, not-yet-recovered transcripts (banner-marked
RECOVERED-UNVERIFIED), commits them, and posts a #bot-alerts FYI.
recover_session.py is the shared engine: Python extracts the verbatim
command/config/reference timeline; Ollama drafts prose-only narrative.
Machine-local ledger (.claude/state/) prevents reprocessing. Reviewed:
git add scoped to own files, ledger written only after successful push,
per-uuid idempotency, --max cap for unattended runs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compressed memory store 104 -> 71 files via four passes:
- Syncro: 19 scattered feedback_syncro_* files merged into 3 rule files
(api/billing/workflow) + an on-demand feedback_syncro_history.md for
incident detail, quotes, and tech/product ID tables.
- Four near-duplicate merges: Howard paste-safety, Pluto build server,
Howard backend deferral, IX server access (ssh+tailscale).
- Per-cluster rule/state/history split applied to GuruConnect (2->1),
Dataforth (3->2), Cascades (7->3), GuruRMM (13->3).
- New reference_resource_map.md: single auto-loaded cheatsheet for
"do I have access to X and how do I connect from this machine?"
- MEMORY.md rewritten to match the new layout.
Health: broken backlinks 8->7, overlap clusters 12->5, orphans 17->0.
memory-dream: read-only memory lint/consolidation analyzer (index, backlinks,
stale refs, dup clusters, profile drift); additive-only --apply-safe, all
merges/deletes are proposals. sync-memory.sh: additive repo<->harness-profile
union (no delete/overwrite, conflicts surfaced), wired to a SessionStart hook.
Migrates the useful profile-only memories into the synced repo store.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Require SecurityCenter2 productState RTP-enabled bit before treating a
registered AV as active (lapsed/disabled AV no longer suppresses the
critical Defender finding), and tighten the Datto fallback to AV/EDR
services only — excluding Datto RMM/Backup/Workplace/Continuity/File so
non-AV Datto products can't masquerade as antivirus. Fix misleading comment.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>