Files
legal-ai/docs/superpowers/plans/2026-05-16-per-agent-claude-md.md
Chaim 4de555367d
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m32s
G12 Leak-Guard / leak-guard (push) Successful in 5s
Lint — undefined names / undefined-names (push) Successful in 11s
chore: fix .gitignore inline comments + add untracked code files
Inline # comments in gitignore are not supported — they were silently
breaking three patterns (data/checkpoints/, data/adapter-migration-state.json,
.claude/agents/.generated/). Moved comments to their own lines and added
missing entries for runtime dirs (data/audit/, data/logs/, etc.) and
temp files (.interaction_tmp.json, .design-build/, .taskmaster bak files).

Also tracks previously untracked legitimate files: scripts, tests, docs,
skills references, .env.example, taskmaster templates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 12:49:32 +00:00

307 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Per-Agent CLAUDE.md Versioning & Validation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** הוסף validation ו-version tracking לקבצי הוראות הסוכנים. כעת, לפני שה-sync script מחיל שינויים, הוא מאמת שכל `instructionsFilePath` קיים. בנוסף, metadata של הסוכן ב-DB יכיל `claude_md_mtime` — השינוי האחרון בקובץ — כדי לזהות drift.
**Architecture:** `sync_agents_across_companies.py` מקבל `--check-instructions` flag שסורק את כל הסוכנים ומדווח על קבצים חסרים/ישנים. ב-`--apply`, מתווספת בדיקת pre-flight שמבטלת את הsync אם קובץ חסר. `agents.metadata` מקבל `claude_md_mtime` עם ה-mtime בפועל של הקובץ.
**Tech Stack:** Python 3.10+, asyncpg, httpx, `os.path.getmtime()`, Paperclip REST API (`PATCH /api/agents/{id}`).
---
## File Map
| Action | File |
|--------|------|
| Modify | `legal-ai/scripts/sync_agents_across_companies.py``--check-instructions` flag, pre-flight, metadata update |
זה הקובץ היחיד שצריך לגעת בו. כל שאר הלוגיקה קיימת כבר.
---
## Task 1: הוסף `--check-instructions` flag
**Files:**
- Modify: `legal-ai/scripts/sync_agents_across_companies.py`
- [ ] **Step 1: קרא את החלק של `argparse` בסקריפט**
```bash
grep -n "argparse\|add_argument\|--verify\|--dry-run\|--apply" \
/home/chaim/legal-ai/scripts/sync_agents_across_companies.py | head -20
```
- [ ] **Step 2: הוסף את הargument**
מצא את הסקציה שמגדירה `args` והוסף:
```python
parser.add_argument(
"--check-instructions",
action="store_true",
help="Scan all agents' instructionsFilePath and report missing/outdated files",
)
```
- [ ] **Step 3: הוסף את הפונקציה `check_instructions()`**
הוסף לפני `async def main()`:
```python
async def check_instructions(agents: list[dict]) -> bool:
"""Print a report of all agents' instruction files. Returns True if all OK."""
all_ok = True
print(f"\n{'Agent':<30} {'File':<60} {'Status':<15} {'Size':>8} {'Modified'}")
print("-" * 120)
for agent in agents:
adapter_cfg = agent.get("adapter_config") or {}
if isinstance(adapter_cfg, str):
import json as _json
adapter_cfg = _json.loads(adapter_cfg)
file_path = adapter_cfg.get("instructionsFilePath", "")
name = agent.get("name", agent.get("id", "?"))[:29]
if not file_path:
print(f"{name:<30} {'(none)':<60} {'⚠️ NOT SET':<15}")
continue
if not os.path.exists(file_path):
print(f"{name:<30} {file_path[-59:]:<60} {'❌ MISSING':<15}")
all_ok = False
continue
stat = os.stat(file_path)
size_kb = stat.st_size // 1024
mtime = datetime.fromtimestamp(stat.st_mtime).strftime("%Y-%m-%d %H:%M")
# Compare with DB metadata
metadata = agent.get("metadata") or {}
if isinstance(metadata, str):
import json as _json
metadata = _json.loads(metadata)
db_mtime = metadata.get("claude_md_mtime", "")
actual_mtime = str(int(stat.st_mtime))
drift = " ⚠️ DRIFT" if db_mtime and db_mtime != actual_mtime else ""
print(f"{name:<30} {file_path[-59:]:<60} {'✅ OK':<15} {size_kb:>6}KB {mtime}{drift}")
print()
return all_ok
```
> `from datetime import datetime` ו-`import os` — בדוק שמיובאים בראש הסקריפט. אם לא, הוסף.
- [ ] **Step 4: הוסף קריאה ל-`check_instructions()` ב-`main()`**
בתוך `async def main()`, אחרי שloading הagents מה-DB:
```python
if args.check_instructions:
all_ok = await check_instructions(master_agents + mirror_agents)
sys.exit(0 if all_ok else 1)
```
- [ ] **Step 5: בדיקה**
```bash
cd /home/chaim/legal-ai
python scripts/sync_agents_across_companies.py --check-instructions
```
Expected: טבלה עם כל הסוכנים, paths, סטטוס ✅/❌.
- [ ] **Step 6: Commit**
```bash
cd /home/chaim/legal-ai
git add scripts/sync_agents_across_companies.py
git commit -m "feat: add --check-instructions flag to sync script"
```
---
## Task 2: הוסף pre-flight validation לפני `--apply`
**Files:**
- Modify: `legal-ai/scripts/sync_agents_across_companies.py`
- [ ] **Step 1: מצא את נקודת הכניסה של `--apply`**
```bash
grep -n "args.apply\|if.*apply\|apply.*mode" \
/home/chaim/legal-ai/scripts/sync_agents_across_companies.py | head -10
```
- [ ] **Step 2: הוסף pre-flight לפני apply**
בתחילת בלוק `--apply`, לפני כל שינוי:
```python
if args.apply:
# Pre-flight: abort if any agent is missing its instructions file
print("🔍 Pre-flight: checking instruction files...")
all_ok = await check_instructions(master_agents + mirror_agents)
if not all_ok:
print("❌ Abort: one or more instruction files are missing. Fix paths before --apply.")
sys.exit(1)
print("✅ Pre-flight passed.\n")
# ... rest of apply logic ...
```
- [ ] **Step 3: בדיקה — הפעל עם קובץ חסר (סימולציה)**
```bash
# שנה זמנית path לקובץ שלא קיים
cd /home/chaim/legal-ai
python scripts/sync_agents_across_companies.py --dry-run 2>&1 | head -5
```
Expected: dry-run עובר. אם תנסה `--apply` עם agent שhis file חסר — הsync יבוטל.
- [ ] **Step 4: Commit**
```bash
cd /home/chaim/legal-ai
git add scripts/sync_agents_across_companies.py
git commit -m "feat: add pre-flight instruction file validation before --apply"
```
---
## Task 3: עדכן `agents.metadata` עם `claude_md_mtime`
**Files:**
- Modify: `legal-ai/scripts/sync_agents_across_companies.py`
- [ ] **Step 1: מצא את `compute_diff()` או `apply_diff()`**
```bash
grep -n "def compute_diff\|def apply_diff\|def build_patch\|metadata" \
/home/chaim/legal-ai/scripts/sync_agents_across_companies.py | head -20
```
- [ ] **Step 2: הוסף פונקציה `get_claude_md_mtime()`**
```python
def get_claude_md_mtime(adapter_config: dict) -> str | None:
"""Return the Unix mtime of the agent's instructionsFilePath, or None if missing."""
path = adapter_config.get("instructionsFilePath", "")
if not path or not os.path.exists(path):
return None
return str(int(os.path.getmtime(path)))
```
- [ ] **Step 3: שלב mtime בbuild של metadata patch**
מצא את המקום שמכין את ה-`metadata` לsync. הוסף:
```python
# Build metadata patch with claude_md_mtime
current_metadata = master_agent.get("metadata") or {}
if isinstance(current_metadata, str):
import json as _json
current_metadata = _json.loads(current_metadata)
adapter_cfg = master_agent.get("adapter_config") or {}
if isinstance(adapter_cfg, str):
import json as _json
adapter_cfg = _json.loads(adapter_cfg)
mtime = get_claude_md_mtime(adapter_cfg)
if mtime:
current_metadata["claude_md_mtime"] = mtime
current_metadata["claude_md_last_synced"] = datetime.utcnow().isoformat() + "Z"
```
כלול את ה-`current_metadata` המעודכן ב-PATCH לAPI.
- [ ] **Step 4: בדוק שה-metadata מתעדכן**
הפעל `--dry-run` וחפש `claude_md_mtime` בoutput:
```bash
python scripts/sync_agents_across_companies.py --dry-run 2>&1 | grep -i "mtime\|metadata" | head -10
```
לאחר `--apply`, בדוק ב-DB:
```bash
psql -h localhost -p 54329 -U paperclip -c \
"SELECT name, metadata->>'claude_md_mtime' AS mtime FROM agents WHERE metadata->>'claude_md_mtime' IS NOT NULL LIMIT 5" \
paperclip
```
- [ ] **Step 5: Commit**
```bash
cd /home/chaim/legal-ai
git add scripts/sync_agents_across_companies.py
git commit -m "feat: track claude_md_mtime in agents.metadata during sync"
```
---
## Task 4: הוסף `make check-agents` shortcut
**Files:**
- Modify: `legal-ai/Makefile` (אם קיים) אחרת הוסף alias
- [ ] **Step 1: בדוק אם Makefile קיים**
```bash
ls /home/chaim/legal-ai/Makefile 2>/dev/null && echo "EXISTS" || echo "MISSING"
```
- [ ] **Step 2א: אם Makefile קיים — הוסף target**
```makefile
check-agents:
python scripts/sync_agents_across_companies.py --check-instructions
sync-agents-dry:
python scripts/sync_agents_across_companies.py --dry-run
sync-agents:
python scripts/sync_agents_across_companies.py --apply
```
- [ ] **Step 2ב: אם Makefile לא קיים — הוסף alias ל-`~/.bashrc`**
```bash
echo "alias check-agents='cd /home/chaim/legal-ai && python scripts/sync_agents_across_companies.py --check-instructions'" >> ~/.bashrc
source ~/.bashrc
```
- [ ] **Step 3: בדוק**
```bash
# אם Makefile:
make -C /home/chaim/legal-ai check-agents
# אם alias:
check-agents
```
Expected: טבלת סוכנים מוצגת.
- [ ] **Step 4: Commit (אם Makefile)**
```bash
cd /home/chaim/legal-ai
git add Makefile
git commit -m "feat: add check-agents and sync-agents make targets"
```
---
## אימות סופי
| בדיקה | פקודה | תוצאה מצופה |
|-------|-------|-------------|
| `--check-instructions` | `python sync_agents... --check-instructions` | טבלה עם ✅ לכל agent |
| Pre-flight בולם apply | מחק קובץ זמנית + `--apply` | Abort עם הודעה ברורה |
| mtime ב-DB | `SELECT metadata->>'claude_md_mtime' FROM agents` | timestamp לכל agent |
| DRIFT זוהה | שנה קובץ + `--check-instructions` | ⚠️ DRIFT מוצג |
| shortcut | `check-agents` או `make check-agents` | עובד |