Commit Graph

391 Commits

Author SHA1 Message Date
88b02cc43b docs(memory-dream): drop additive-only framing; reflect mirror-mode policy
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>
2026-06-02 16:27:47 -07:00
ae51988557 feat(sync-memory): switch to mirror mode — repo is authoritative
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>
2026-06-02 15:15:16 -07:00
90f59dc1da fix(memory): drop 49 stale index entries pointing at deleted files
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>
2026-06-02 15:06:57 -07:00
dd414c424a sync: auto-sync from HOWARD-HOME at 2026-06-02 15:03:53
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-06-02 15:03:53
2026-06-02 15:04:49 -07:00
c759f04674 chore(memory): re-apply consolidation deletions + lift additive-only constraint
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>
2026-06-02 15:03:58 -07:00
4dc4563f09 memory: add 49 orphaned files to MEMORY.md index
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.
2026-06-02 14:57:59 -07:00
4c65942f81 docs(memory): record winget-jq CRLF gotcha for harness scripts
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>
2026-06-02 14:51:09 -07:00
2ad42a2639 sync: auto-sync from Mikes-MacBook-Air.local at 2026-06-02 14:49:12
Author: Mike Swanson
Machine: Mikes-MacBook-Air.local
Timestamp: 2026-06-02 14:49:12
2026-06-02 14:49:13 -07:00
b153ff158b feat(self-check): add harness self-diagnosis / fleet conformance skill
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>
2026-06-02 14:45:42 -07:00
fb9604a312 sync: auto-sync from ACG-TECH03L at 2026-06-02 11:52:51
Author: Howard Enos
Machine: ACG-TECH03L
Timestamp: 2026-06-02 11:52:51
2026-06-02 11:53:00 -07:00
0f6c05ace6 sync: auto-sync from ACG-TECH03L at 2026-06-02 11:30:41
Author: unknown
Machine: ACG-TECH03L
Timestamp: 2026-06-02 11:30:41
2026-06-02 11:34:48 -07:00
61081f70c2 sync: auto-sync from GURU-BEAST-ROG at 2026-06-02 10:44:23
Author: Mike Swanson
Machine: GURU-BEAST-ROG
Timestamp: 2026-06-02 10:44:23
2026-06-02 10:44:29 -07:00
551aaf2fe1 fix(smartbadge-watch): handle null stdout from RMM and add diagnostic context
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>
2026-06-02 09:07:35 -07:00
f8ed03c75a sync: auto-sync from GURU-5070 at 2026-06-02 07:25:49
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-02 07:25:49
2026-06-02 07:25:55 -07:00
5189f28ae7 fix(wiki): forbid inlining raw secrets in recompiled articles
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>
2026-06-02 06:18:04 -07:00
581906a04c sync: auto-sync from Mikes-MacBook-Air.local at 2026-06-01 19:42:24
Author: Mike Swanson
Machine: Mikes-MacBook-Air.local
Timestamp: 2026-06-01 19:42:24
2026-06-01 19:42:27 -07:00
c893d3eebe feat(wiki): draft wiki articles with a Sonnet subagent, not Ollama
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>
2026-06-01 19:39:17 -07:00
2a5476f8be feat(save): full wiki recompile on save (was refresh-only)
/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>
2026-06-01 19:28:52 -07:00
f44a96b0d1 feat(save): refresh worked-on wiki article before sync
/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>
2026-06-01 19:26:31 -07:00
59397e8de3 fix(recovery): never write recovered logs into a git submodule
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>
2026-06-01 19:15:11 -07:00
eed3ece2c7 feat: session recovery toolset (orphan detector + /recover)
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>
2026-06-01 18:33:07 -07:00
c8f0006d25 sync: auto-sync from HOWARD-HOME at 2026-06-01 18:17:08
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-06-01 18:17:08
2026-06-01 18:17:15 -07:00
eb5c147bcd sync: auto-sync from HOWARD-HOME at 2026-06-01 17:07:55
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-06-01 17:07:55
2026-06-01 17:10:07 -07:00
f682ad93c3 sync: auto-sync from GURU-5070 at 2026-06-01 16:38:08
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-01 16:38:08
2026-06-01 16:38:12 -07:00
f7cc0cf257 sync: auto-sync from GURU-5070 at 2026-06-01 16:30:28
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-01 16:30:28
2026-06-01 16:33:58 -07:00
805b902ca5 sync: auto-sync from GURU-KALI at 2026-06-01 16:28:01
Author: Mike Swanson
Machine: GURU-KALI
Timestamp: 2026-06-01 16:28:01
2026-06-01 16:29:09 -07:00
66733d47ea sync: auto-sync from GURU-BEAST-ROG at 2026-06-01 16:26:01
Author: Mike Swanson
Machine: GURU-BEAST-ROG
Timestamp: 2026-06-01 16:26:01
2026-06-01 16:26:08 -07:00
0c000109dc chore(memory): consolidate scattered feedback/project/reference files
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.
2026-06-01 16:25:45 -07:00
2a1ccfac73 Add memory-dream skill + additive cross-machine memory sync
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>
2026-06-01 15:22:12 -07:00
96fb4110ea Add b2 skill: Backblaze B2 management CLI (storage cost, prefix purge)
B2 Native API v3 client for the ACG B2 account: status, buckets, keys,
files, bucket-size, usage/cost ($0.00695/GB), gated create/delete bucket+key,
and gated lifecycle-based delete-prefix/lifecycle-remove for prefix purges.
Read-only by default; destructive ops require --confirm.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:31:09 -07:00
501f3eb130 sync: auto-sync from GURU-5070 at 2026-06-01 06:57:20
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-01 06:57:20
2026-06-01 06:57:28 -07:00
887f0a21a9 sync: auto-sync from HOWARD-HOME at 2026-05-31 20:13:56
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-05-31 20:13:56
2026-05-31 20:14:09 -07:00
4c49b85012 sync: auto-sync from GURU-KALI at 2026-05-31 19:37:22
Author: Mike Swanson
Machine: GURU-KALI
Timestamp: 2026-05-31 19:37:22
2026-05-31 19:37:23 -07:00
c37fd11ee9 sync: auto-sync from GURU-KALI at 2026-05-31 19:31:53
Author: Mike Swanson
Machine: GURU-KALI
Timestamp: 2026-05-31 19:31:53
2026-05-31 19:31:56 -07:00
959b3a159d fix(onboarding-diag): harden 3rd-party AV detection against false positives
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>
2026-05-31 18:47:54 -07:00
d17e9be135 sync: auto-sync from GURU-5070 at 2026-05-31 16:35:50
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-05-31 16:35:50
2026-05-31 16:35:57 -07:00
85509a71dc feat(onboarding-diag): allowlist ACG's own stack; downgrade Defender-off w/ 3rd-party AV (3d886f1a)
The probe flagged ACG's own MSP tooling (ScreenConnect/ConnectWise Control,
Splashtop, Syncro, Datto RMM, Datto EDR/AV) as CRITICAL "foreign agent" and
flagged Defender-off as CRITICAL even when a 3rd-party AV had legitimately
disabled it. Now: allowlisted tools emit an INFO "expected ACG tooling"
finding (genuinely-foreign tools still CRITICAL); Defender-off is downgraded
to INFO only when a 3rd-party AV is active. JSON contract + grading unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 16:22:38 -07:00
a735d8c220 fix(onboarding-diag): jq-normalize single-element facts arrays (cc5dbdfa)
PowerShell ConvertTo-Json collapses a single-element array into a bare
object (or, for string arrays, a bare string). The runner iterated/joined
several facts.* fields, so single-volume / single-NIC / single-admin
machines silently dropped the Fixed Volumes table and errored the network
adapter, local-administrator, and installed-software-diff lines.

Fix jq-side in the runner (backward-compatible with already-written
immutable baselines; PS1 untouched per the todo decision) using
`if type=="array" then . elif .==null then [] else [.] end` at:
volumes, network_adapters (+ inner ip/dns), local_administrators, and
installed_software (both sides of the diff). Verified with synthetic
single-element JSON and a multi-element no-regression check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 14:12:41 -07:00
973e9dbe8f sync: auto-sync from GURU-KALI at 2026-05-31 09:36:59
Author: Mike Swanson
Machine: GURU-KALI
Timestamp: 2026-05-31 09:36:59
2026-05-31 09:37:01 -07:00
80af6eb496 fix: improve git hook JSON escaping
Fixed post-commit hook to properly escape JSON payloads using python.
Previous implementation was vulnerable to breaking on commit messages
with special characters (quotes, newlines, etc.).

CHANGES:
- Use python json.dumps() for proper JSON escaping
- Prevents 422 validation errors from coordination API
- Handles multi-line commit messages correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-31 08:54:53 -07:00
ff3dc12749 feat: add git hooks for automated dev-alerts notifications
Implemented post-commit hooks to automatically send coordination messages
to dev-alerts channel when feature specs are created or builds occur.

HOOKS:
- .git/hooks/post-commit (main repo)
- .git/modules/projects/msp-tools/guru-connect/hooks/post-commit (GC submodule)

TRIGGERS:
- Feature spec creation (SPEC-NNN files)
- Build events (spec/feat/fix/build commits on main)

ACTIONS:
- Extract spec metadata (priority, effort, overview)
- Send coordination message to dev-alerts channel
- Include commit hash, author, files changed

DOCUMENTATION:
- .claude/HOOKS.md - Full hook documentation
- .claude/hooks/post-commit.template - Reusable hook template

BENEFITS:
- Automatic notifications for new features
- Build tracking on main branch
- Team awareness of spec changes
- No manual message sending required

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-31 08:52:41 -07:00
2afec8f149 sync: auto-sync from GURU-KALI at 2026-05-31 07:40:31
Author: Mike Swanson
Machine: GURU-KALI
Timestamp: 2026-05-31 07:40:31
2026-05-31 07:40:32 -07:00
c67accddcc memory: record RMM webhook docs-only build guard (SPEC-020 Phase 0)
Host guard in /opt/gururmm/webhook-handler.py skips docs-only pushes; note the
stale repo copy must not be redeployed over it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 17:07:09 -07:00
833815b5f2 memory: add RMM identify-by-IP feedback
Match a known external IP to the RMM agent rather than reconning every
candidate machine (Mike's correction during the Pavon GuruConnect-client
removal). Notes the GuruRMM agent-IP tracking gap (todo 7459428e).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:39:46 -07:00
3895aa363c sync: auto-sync from GURU-5070 at 2026-05-30 15:26:54
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-05-30 15:26:54
2026-05-30 15:27:00 -07:00
5b285321c0 scc: Session save and push from GURU-5070 at 2026-05-30 14:47
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-30 14:46:14 -07:00
2460d52b48 sync: auto-sync from GURU-5070 at 2026-05-30 11:51:56
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-05-30 11:51:56
2026-05-30 11:52:04 -07:00
db6aa3683f fix(bitdefender): all-clients sweep, quarantine path, EDR controls, self-test
Several bugs found and fixed during live testing against the ACG GravityZone
tenant:
- security_sweep_all_clients: iterate each company (the companies container is
  not a valid endpoint parent; passing it 400'd the whole sweep)
- list_quarantine: use service-scoped path quarantine/computers with companyId
  (bare quarantine module 404'd; param is companyId not parentId)
- rename GZEndpointSummary.detection_active -> threat_detected with corrected
  semantics (True = active threat, tracks with infected; not an engine-on flag)
- status: readable sectioned table renderer for the nested apiKey/license dict
- portable CLAUDETOOLS_ROOT resolution (derive from file path, not a Windows
  literal) so it works on the Mac/Linux fleet

Adds scripts/selftest.py: a 29-check read-only harness (all passing) covering
every read command, --json, error exit codes, and destructive-action gating.
EDR/incident commands (blocklist, isolate/unisolate, blocklist-add/remove) and
raw destructive-method gating are included from this session's work.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 07:29:55 -07:00
446d25c66b fix(bitdefender): gate raw destructive calls, allow --json after subcommand
- raw now refuses destructive methods (delete/uninstall/remove/reconfigure)
  without --confirm (it previously bypassed all gating)
- --json is now accepted after the subcommand (shared via a common parent
  parser), matching the documented usage
- drop a placeholder-less f-string
- SKILL.md: document raw gating + that raw echoes upstream responses verbatim

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 07:29:55 -07:00
8ba92bf02b feat(bitdefender): GravityZone Cloud Public API skill
Adds a /bitdefender skill that drives the ACG GravityZone partner tenant
via the JSON-RPC Public API. Read + management ops (companies, endpoints,
live security sweep, policies [read-only/shallow], packages, quarantine,
scans, groups, move/delete). Identity-tier JSON cache (24h TTL,
--refresh); volatile status is always pulled live, never cached.

Security hardening: API key loaded from SOPS vault at runtime (never on
disk/logs/argv/cache); destructive deletes gated behind --confirm; `raw`
also gates destructive methods; upstream error bodies truncated. UNVERIFIED
API methods reachable only via `raw`. Reuses the auth/JSON-RPC pattern from
api/services/gravityzone_service.py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 07:29:55 -07:00