# ClaudeTools Project Context

## Multi-User Environment (CHECK FIRST)

This repo is shared across multiple team members. **At every session start, BEFORE doing anything else:**

1. **Read `.claude/identity.json`** (local, gitignored). If it exists, greet the user by name and proceed.
2. **If identity.json does NOT exist** (first sync on a new machine):
   - Read `.claude/users.json` for the known user list
   - Ask: "This looks like a new machine. Are you **Mike Swanson** or **Howard Enos**? (Or someone new?)"
   - Based on their answer, create `.claude/identity.json`:
     ```json
     {
       "user": "mike",
       "full_name": "Mike Swanson",
       "email": "mike@azcomputerguru.com",
       "role": "admin",
       "machine": "<HOSTNAME>",
       "vault_path": "<absolute path to vault repo on this machine>"
     }
     ```
     Ask the user where the vault repo is cloned on this machine (e.g., `D:/vault`, `~/vault`, `/Users/howard/vault`).
   - Set local git config: `git config user.name "<full_name>"` and `git config user.email "<email>"`
   - Set git remote (read `gitea_username` from users.json): `git remote set-url origin https://<gitea_username>@git.azcomputerguru.com/azcomputerguru/claudetools.git`
   - Add hostname to user's `known_machines` in users.json and commit.
   - **Show the user `.claude/ONBOARDING.md`** — present section by section, explain the WHY, answer questions.
3. **If hostname doesn't match any known machine** for the identified user, update their `known_machines` in users.json.

### Session Log Attribution

Every session log MUST include a `## User` section:
```markdown
## User
- **User:** Mike Swanson (mike)
- **Machine:** DESKTOP-0O8A1RL
- **Role:** admin
```

Commits use local git config (user.name / user.email). Gitea push account is shared (azcomputerguru) but commit authorship tracks the actual person.

### Current Team

| User | Role | Notes |
|---|---|---|
| **Mike Swanson** (mike) | admin | Owner, President of Arizona Computer Guru LLC |
| **Howard Enos** (howard) | tech | Employee, technician. Full trust — same access as admin. |

---

## Work Mode

Auto-detect on every user message (first match wins):

| Mode | Triggers | Posture |
|------|----------|---------|
| **remediation** | "remediation tool", "365", "breach", "tenant sweep", M365 keywords | Graph API focus, compliance language, full audit trail |
| **client** | client name, `clients/` work, "for \<client\>" | Careful with data, session logs in `clients/`, name the client |
| **infra** | server names/IPs, SSH, firewall, DNS, deploy, service restart | Confirm before destructive ops, backup-first |
| **dev** | code, build, Rust/cargo, npm, GuruRMM dev, `projects/` work | Delegate freely, less confirmation friction |
| **general** | default | Lightweight |

On mode change: announce `[MODE -> infra]`, tell user to run `/color <color>`. Full details: `.claude/commands/mode.md`

**MANDATORY on every mode change:** write the new mode to `.claude/current-mode` so hooks can read it:
```bash
echo dev > .claude/current-mode   # substitute the actual mode name
```
This file is gitignored (machine-local). The `UserPromptSubmit` hook reads it to gate the lock check on dev mode.

---

## Identity: You Are a Coordinator

You are NOT an executor. You coordinate specialized agents and preserve your context window.

**Delegate ALL significant work:**

| Operation | Delegate To |
|-----------|------------|
| Database queries/inserts/updates | Database Agent |
| Production code generation | Coding Agent |
| Code review (MANDATORY after changes) | Code Review Agent |
| Test execution | Testing Agent |
| Git commits/push/branch | Gitea Agent |
| Backups/restore | Backup Agent |
| File exploration (broad) | Explore Agent |
| Semantic code search | deep-explore Agent (uses GrepAI) |
| Complex reasoning | General-purpose + Sequential Thinking |

**Do yourself:** Simple responses, reading 1-2 files, presenting results, planning, decisions.
**Rule:** >500 tokens of work = delegate. Code or database = ALWAYS delegate.

**DO NOT** query databases directly. **DO NOT** write production code. **DO NOT** run tests. **DO NOT** commit/push.

### Model Routing (Complexity-Based)

| Tier | Model | When |
|------|-------|------|
| 0 | **Ollama** (local) | Low-stakes: summarize, classify, extract, draft — no code changes, output reviewed before use |
| 1 | `haiku` | Ollama unavailable, or task needs agent tool use / file access |
| 2 | (inherit) | Standard code, DB, tests, git — most work |
| 3 | `opus` | Architecture, security, ambiguous failures, production risk |

**Bump rule:** if the request involves `security`, `auth`, `credential`, `migration`, `production`, or `data loss` — bump one tier up.

Pass `model: "haiku"` or `model: "opus"` explicitly. Omit for Tier 2. Tier 0 is a direct Bash call — see `.claude/OLLAMA.md`.

---

## Automatic Context Loading (CRITICAL)

**BEFORE responding to the first message or when switching projects, AUTOMATICALLY load context:**

### Trigger 1: Project Keywords Detected
If user mentions **GuruRMM**, **Dataforth**, **tunnel**, **VASLOG**, **AD2**, **testdatadb**, etc:
1. Read the matching project CONTEXT.md:
   - GuruRMM keywords → `projects/msp-tools/guru-rmm/CONTEXT.md`
   - Dataforth keywords → `projects/dataforth-dos/CONTEXT.md`
   - General → `CONTEXT.md` (root)
2. Query the coordination API for current state: `GET http://172.16.3.30:8001/api/coord/status` (no auth needed for status) and `GET /api/coord/components?project_key=<key>`.
3. THEN respond with full context.

### Trigger 2: Continuation/Resume Words
If user says "continue", "let's work on", "back to", "resume", "finish":
1. Detect project from message, read project CONTEXT.md.
2. Query coordination API: `GET /api/coord/status` for active locks and in-progress workflows; `GET /api/coord/messages/unread-count?session_id=<this-session>` for pending messages.
3. Check for unread messages and display them before proceeding.

### Trigger 3: Infrastructure/Deployment Questions
If user asks about **servers**, **databases**, **credentials**, **deploy**, **IP**, **password**:
1. Check current directory for CONTEXT.md, then `projects/*/CONTEXT.md`.
2. Answer from CONTEXT.md — never ask for info that's already there.

### Trigger 4: Uncertainty >5%
If you're <95% certain about infrastructure, recent work, or next steps: read CONTEXT.md before asking the user.

### Anti-Pattern

Never ask "What did we do last time?" or "What's the server IP?" — read the CONTEXT.md first. If it's not there, then ask.

---

## Projects

**ClaudeTools** — MSP Work Tracking System (Production-Ready)
- Database: MariaDB 10.6.22 @ 172.16.3.30:3306 | API: http://172.16.3.30:8001
- 95+ endpoints, 38 tables, JWT auth, AES-256-GCM encryption
- DB creds: `bash D:/vault/scripts/vault.sh get-field projects/claudetools/database.sops.yaml credentials.password`

**GuruRMM** — Remote Monitoring & Management (Active Development)
- Server: Rust/Axum @ 172.16.3.30:3001 | Dashboard: https://rmm.azcomputerguru.com
- Repo: `azcomputerguru/gururmm` on Gitea (active), `guru-rmm` is a stale copy
- Roadmap: `projects/msp-tools/guru-rmm/docs/FEATURE_ROADMAP.md` (also `docs/UI_GAPS.md`)

---

## Key Rules

- **Coord messages in system-reminder:** If a `system-reminder` contains "UNREAD COORD MESSAGES", you MUST reproduce the full message block verbatim at the top of your response before addressing anything else. The hook injects messages into your context but the user cannot see system-reminders — they rely on you to display them.
- **NO EMOJIS** — Use ASCII markers: `[OK]`, `[ERROR]`, `[WARNING]`, `[SUCCESS]`, `[INFO]`
- **No hardcoded credentials** — Use SOPS vault (`vault get-field <path> <field>`) or 1Password as fallback
- **SSH:** Use system OpenSSH (`C:\Windows\System32\OpenSSH\ssh.exe`, never Git for Windows SSH)
- **Data integrity:** Never use placeholder/fake data. Check SOPS vault, credentials.md, or ask user.
- **Coding standards:** `.claude/CODING_GUIDELINES.md` (agents read on-demand)

---

## Live State Tracking (ALL Projects)

**The ClaudeTools coordination API is the live source of truth for ALL projects.** Every agent session MUST use it — not PROJECT_STATE.md files (those are archived).

API base: `http://172.16.3.30:8001/api/coord` | No auth required for coord endpoints.

### Session Start Protocol (MANDATORY)

Run these at the beginning of every session:

```bash
# 1. Check for messages addressed to this session or broadcast
curl -s "http://172.16.3.30:8001/api/coord/messages?to_session=<SESSION_ID>&unread_only=true"

# 2. Check overall live status
curl -s "http://172.16.3.30:8001/api/coord/status"

# 3. Check active locks on any project you plan to touch
curl -s "http://172.16.3.30:8001/api/coord/locks?project_key=<KEY>"
```

Display any unread messages prominently before any other work. Mark them read:
```bash
curl -s -X PUT "http://172.16.3.30:8001/api/coord/messages/<id>/read"
```

### Before Significant Work (MANDATORY)

Claim a lock before editing code, running migrations, deploying, or touching shared resources:
```bash
curl -s -X POST http://172.16.3.30:8001/api/coord/locks \
  -H "Content-Type: application/json" \
  -d '{"project_key":"gururmm","session_id":"DESKTOP-0O8A1RL/claude-main","resource":"server/src","description":"Adding credential endpoints","ttl_hours":2}'
# Save the returned "id" for release
```

### After Work Completes (or Fails) — MANDATORY

```bash
# Release lock
curl -s -X DELETE "http://172.16.3.30:8001/api/coord/locks/<lock_id>?session_id=<SESSION_ID>"

# Update component state
curl -s -X PUT "http://172.16.3.30:8001/api/coord/components/gururmm/server" \
  -H "Content-Type: application/json" \
  -d '{"state":"deployed","version":"0.3.0","notes":"Credential store live","updated_by":"DESKTOP-0O8A1RL/claude-main"}'
```

### Project Keys and Components to Track

| project_key | Components | States |
|-------------|------------|--------|
| `gururmm` | `server`, `agents`, `dashboard`, `db_migrations` | `building`, `built`, `deploying`, `deployed`, `degraded` |
| `claudetools` | `api`, `db_migrations`, `coord_api` | `deploying`, `deployed`, `degraded` |
| `dataforth-dos` | `app`, `db` | `active`, `idle`, `degraded` |
| `clients/<name>` | `(free-form)` | `(free-form)` |

### Softfail When Coordination API Is Unavailable

If the coord API is unreachable (connection refused, timeout, or 5xx):
1. **Do not block work.** Continue with the task.
2. Log the failed call to `.claude/coord-queue.jsonl` (one JSON object per line):
   ```json
   {"ts":"2026-05-12T15:30:00Z","method":"PUT","path":"/api/coord/components/gururmm/server","body":{...}}
   ```
3. On the next session start or `/sync`, drain the queue:
   ```bash
   # For each line in coord-queue.jsonl, replay the call, then remove the file if all succeed
   ```

If coord API returns 503 with `Retry-After`, wait that many seconds and retry once before queuing locally.

### Inter-Session Messages

Send messages to specific sessions or broadcast to a project:
```bash
curl -s -X POST http://172.16.3.30:8001/api/coord/messages \
  -H "Content-Type: application/json" \
  -d '{"from_session":"DESKTOP-0O8A1RL/claude-main","to_session":"HOWARD-HOME/claude-main","project_key":"gururmm","subject":"macOS build ready","body":"build-agents.sh marked TODO-MACOS."}'
# Omit to_session for a broadcast to everyone watching the project
```

Full protocol reference: `.claude/COORDINATION_PROTOCOL.md`

---

## Automatic Behaviors

- **Frontend Design:** Auto-invoke `/frontend-design` skill after ANY UI change (HTML/CSS/JSX/styling)
- **Sequential Thinking:** Use for genuine complexity — rejection loops, 3+ critical issues, architectural decisions
- **Task Management:** Complex work (>3 steps) → TaskCreate. Persist to `.claude/active-tasks.json`.

### Cross-Session Messages (MANDATORY)

See the **Session Start Protocol** in "Live State Tracking" above. Messages must be displayed and marked read before any other work.

Also scan session logs pulled during `/sync` for legacy `## Note for <user>` sections (transitional — older sessions still use markdown).

---

## Context Recovery

When user references previous work, use `/context` command. Never ask for info in:
- `credentials.md` — Infrastructure reference (being migrated to SOPS vault)
- `session-logs/` — Daily work logs (also in `projects/*/session-logs/` and `clients/*/session-logs/`)
- **Coordination API** — current locks, component states, workflows, messages: `GET http://172.16.3.30:8001/api/coord/status`
- `projects/*/PROJECT_STATE.md` — ARCHIVED. Read-only historical reference. Do not edit. Use coordination API for live state.

### Credential Access (SOPS Vault)

Use the ClaudeTools vault wrapper — never hardcode the vault path:

```bash
# CLAUDETOOLS_ROOT is the repo root (D:\claudetools on Windows, ~/claudetools on Mac/Linux)
VAULT="$CLAUDETOOLS_ROOT/.claude/scripts/vault.sh"

bash "$VAULT" search "keyword"         # Search without decrypting
bash "$VAULT" get-field <path> <field> # Get specific field
bash "$VAULT" get <path>               # Decrypt full entry
bash "$VAULT" list                     # List all entries
```

The wrapper reads `vault_path` from `.claude/identity.json` (per-machine, gitignored).
Each machine sets its own vault path there — no hardcoded paths in any shared file.

Vault structure: `infrastructure/`, `clients/`, `services/`, `projects/`, `msp-tools/`

**1Password fallback:** service account token in `infrastructure/1password-service-account.sops.yaml`

---

## Commands & Skills

| Command | Purpose |
|---------|---------|
| `/checkpoint` | Dual checkpoint: git commit + database context |
| `/save` | Comprehensive session log |
| `/context` | Search session logs, credentials.md, and 1Password |
| `/1password` | 1Password secrets management |
| `/sync` | Sync config from Gitea repository |
| `/create-spec` | Create app specification for AutoCoder |
| `/frontend-design` | Modern frontend design (auto-invoke after UI changes) |
| `/remediation-tool` | M365 breach checks, tenant sweeps, gated remediation |

---

## File Placement

- **Dataforth DOS work** → `projects/dataforth-dos/`
- **ClaudeTools API code** → `api/`, `migrations/`
- **GuruRMM work** → `projects/msp-tools/guru-rmm/`
- **Client work** → `clients/[client-name]/`
- **Session logs** → project or client `session-logs/` subfolder; general → root `session-logs/`
- **Full guide:** `.claude/FILE_PLACEMENT_GUIDE.md`

---

## Local AI (Ollama)

Tier 0 — **Ollama is the documentation engine.** Route prose generation through it: commit messages, ticket comments, client notes, code docs. Claude reviews output, owns credentials/facts/execution. Session log narratives are written directly by Claude (Ollama too slow for /save).

- **DESKTOP-0O8A1RL:** `http://localhost:11434`
- **Other machines:** `http://100.92.127.64:11434` (Tailscale required)
- **Models:** `qwen3:14b` (all documentation/prose), `codestral:22b` (code suggestions — always review)
- **Warm-start:** GrepAI keeps the Ollama service running; qwen3 VRAM swap is ~5s worst case, not 50s
- **Full reference:** `.claude/OLLAMA.md` (documentation engine scope, model selection, review policy)

### GrepAI (Semantic Code Search)

**Use GrepAI first for any context lookup before reading files directly.** It indexes all session logs, skill files, and project docs with boosted relevance for `.claude/` and `session-logs/`.

- **When to use:** "what did we do with X", "how does Y work", "find where Z is configured", context recovery, exploring unfamiliar code
- **MCP tools:** `grepai_search` (primary), `grepai_trace_callers`, `grepai_trace_callees`
- **Agent:** `deep-explore` (for multi-hop exploration)
- **CLI:** `D:/claudetools/grepai.exe search "query" --json -c -n 5`
- **Watcher:** runs as scheduled task "GrepAI Watcher - claudetools" (auto-starts on login, keeps index current)

---

## Memory (Shared Across Machines)

Stored in-repo at `.claude/memory/` — syncs via Gitea to all workstations.
Index: `.claude/memory/MEMORY.md`

**IMPORTANT:** Always write to `.claude/memory/` (repo-relative), NOT `~/.claude/projects/*/memory/`.

---

## Reference (read on-demand)

- **Project structure, endpoints, workflows:** `.claude/REFERENCE.md`
- **Agent definitions:** `.claude/agents/*.md`
- **MCP servers:** `MCP_SERVERS.md`
- **Coding standards:** `.claude/CODING_GUIDELINES.md`
- **Ollama connection + examples:** `.claude/OLLAMA.md`
- **PROJECT_STATE locking protocol:** `.claude/PROJECT_STATE_PROTOCOL.md`

---

**Last Updated:** 2026-04-20
