feat(memory): introduce .claude/{tasks,memory,audits}/ governance layout

Move tasks/ into .claude/tasks/ and create .claude/memory/ with 5
persistent registries (decisions/learnings/blockers/journal/evals) plus
.claude/audits/ for audit reports. Also seed templates/memory/ for
onboarder to copy into user projects.

- tasks/TODO.md, tasks/rtk-upstream-issue.md → .claude/tasks/
- tasks/LESSONS.md deleted (empty template; superseded by learnings.md)
- .claude/memory/: 5 append-only registries with YAML schema + seed entries
- templates/memory/: 5 empty-index templates for new projects

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
bastien
2026-04-23 16:06:00 +02:00
co-authored by Claude Opus 4.7
parent 6f5f4fe5b5
commit 892de288fe
13 changed files with 334 additions and 4 deletions
+36
View File
@@ -0,0 +1,36 @@
---
type: blockers_registry
entry_prefix: BLK
schema:
id: BLK-XXX
date: YYYY-MM-DD
friction: string (what was blocked)
real_cause: string (root cause, not symptom)
solution: string (workaround or fix)
status: [open | resolved | upstream]
rules:
- Open a blocker as soon as friction > 15 min wasted. Close it with a real cause, not "moved on".
- Link to upstream issue / PR / commit when applicable.
- If cause is a bug in a dependency, set status upstream with a pointer to the tracker.
---
# Blockers registry (BLK)
## Index
| ID | Date | Friction | Status |
|----|------|---------|--------|
| BLK-001 | 2026-04-22 | `rtk curl` breaks JSON pipelines | upstream |
---
## BLK-001 — `rtk curl` returns compressed schema in pipes
- **Date** : 2026-04-22
- **Friction** : toute pipeline `rtk curl ... | python -c "json.load(sys.stdin)"` (ou `jq`, `awk`) échoue sans message clair.
- **Cause réelle** : `rtk curl` auto-compresse stdout indépendamment du TTY — documenté dans `.claude/tasks/rtk-upstream-issue.md`.
- **Solution** :
- Workaround court terme : `exclude_commands=["curl"]` dans `~/.config/rtk/config.toml`.
- Workaround alternatif : utiliser `rtk proxy`.
- Fix upstream : issue reportée, voir `.claude/tasks/rtk-upstream-issue.md`.
- **Statut** : upstream (bug chez `rtk`, workaround appliqué).
+51
View File
@@ -0,0 +1,51 @@
---
type: decisions_registry
entry_prefix: BDR
schema:
id: BDR-XXX
date: YYYY-MM-DD
title: string (<= 80 chars)
decision: string (what was chosen)
why: string (motivation, context)
alternatives: list of strings (what was rejected + why)
status: [proposed | accepted | deprecated | superseded]
supersedes: BDR-XXX (optional)
rules:
- Append-only. Never rewrite past entries - add a new one with status superseded if needed.
- One entry per non-trivial choice. Trivial = reversible in under 10 min with no cross-file impact.
- Capture why more carefully than what - the what rots, the why lasts.
---
# Decisions registry (BDR)
## Index
| ID | Date | Title | Status |
|----|------|-------|--------|
| BDR-001 | 2026-04-22 | --help helper uniforme via hook post-start (option C) | accepted |
| BDR-002 | 2026-04-23 | Restructurer tasks/ + memory + audits sous .claude/ | accepted |
---
## BDR-001 — --help helper uniforme via hook post-start (option C)
- **Date** : 2026-04-22
- **Statut** : accepted
- **Décision** : tous les skills exposent `--help` via un snippet partagé injecté par le session-start hook, plutôt que dupliquer le helper dans chaque SKILL.md.
- **Pourquoi** : 25+ skills, maintenir le même helper dans chaque fichier = drift garanti. Un point d'injection = une seule source de vérité.
- **Alternatives rejetées** :
- Option A (copier le helper dans chaque SKILL.md) — refusée : entropie de maintenance.
- Option B (wrapper externe `/help <skill>`) — refusée : casse l'expérience "une commande = un skill".
- **Référence** : commit 3968a29.
## BDR-002 — Restructurer tasks/ + memory + audits sous .claude/
- **Date** : 2026-04-23
- **Statut** : accepted
- **Décision** : migrer `./tasks/` vers `.claude/tasks/`, créer `.claude/memory/` (5 registres BDR/LRN/BLK/journal/EVAL) et `.claude/audits/` pour les fichiers AUDIT_*. Adapter skills/agents/CLAUDE.md. Intégrer un rituel de capitalisation dans les skills de complétion (ship-feature, feat, bugfix, hotfix, commit-change) + créer un skill `/close` pour le rituel de fin de session.
- **Pourquoi** : regrouper tout le méta-projet (config IA + tâches + mémoire + audits) sous `.claude/` isole la gouvernance Claude du code réel. Alignement sur la doc officielle Claude Code memory. Sans intégration dans les skills, les registres resteraient vides (aspirational text).
- **Alternatives rejetées** :
- Laisser `./tasks/` à la racine — refusée : encombre le repo, mélange signal code / signal gouvernance.
- Utiliser `.claude/agent-memory/` pour tout — refusée : `agent-memory/` a un rôle distinct (déjà utilisé par d'autres outils).
- Rituel uniquement en texte aspirationnel dans CLAUDE.md — refusée : zéro garantie d'exécution, les registres resteraient vides.
- Hook `Stop` pour poser les 3 questions à chaque tour — refusée : trop bruyant.
+34
View File
@@ -0,0 +1,34 @@
---
type: evals_registry
entry_prefix: EVAL
schema:
id: EVAL-XXX
date: YYYY-MM-DD
output: string (what was produced)
method: string (how it was evaluated - manual read, test, benchmark, user feedback)
anomalies: list of strings (what was wrong, missing, surprising)
action: [keep | correct | deprecate]
rules:
- Log an eval whenever you validate the quality of something Claude produced (report, audit, plan, generated code).
- Action keep - the output is fit for purpose as-is.
- Action correct - needs revision; capture what.
- Action deprecate - the approach itself is flawed; link to the decision that replaces it.
---
# Evals registry (EVAL)
## Index
| ID | Date | Output | Action |
|----|------|--------|--------|
| EVAL-001 | 2026-04-23 | Plan de restructuration .claude/ (STEP 2 de ship-feature) | keep |
---
## EVAL-001 — Plan de restructuration `.claude/`
- **Date** : 2026-04-23
- **Output** : plan 21 tâches pour migrer `tasks/` vers `.claude/tasks/` + créer `.claude/memory/` + `.claude/audits/` + intégrer CAPITALIZE dans 5 skills + créer `/close`.
- **Méthode** : relecture manuelle des 5 skills/agents impactés, vérification que rtk est path-agnostic, symlink `~/.claude/CLAUDE.md` → projet confirmé (un seul fichier à éditer). Radical-honesty check sur le ritual "session-close" : confirmé comme aspirationnel sans intégration dans les skills → scope élargi à Option D.
- **Anomalies** : aucune bloquante. Note : `tasks/LESSONS.md` était vide (101B, juste un header) — migration vers `learnings.md` symbolique.
- **Action** : keep — plan validé, prêt pour exécution.
+19
View File
@@ -0,0 +1,19 @@
---
type: journal
schema:
entry: one date heading per working session
body: 3-5 lines max - what was done, decided, blocked
rules:
- One heading per date (YYYY-MM-DD), not per session.
- Append at the end. Never edit past entries.
- Keep it terse. Details belong in decisions/learnings/blockers - this is a timeline only.
---
# Journal
## 2026-04-23
- Restructuré l'arborescence : `tasks/` → `.claude/tasks/`, créé `.claude/memory/` (5 registres) + `.claude/audits/`.
- Adapté CLAUDE.md + skills `onboard`, `init-project` + agent `onboarder` + `lib/project-archetypes/dotfiles-meta.md`.
- Ajouté un step CAPITALIZE dans `ship-feature`, `bugfix`, `hotfix`, `feat`, `commit-change` + créé skill `/close` pour rituel de fin de session.
- Décision BDR-002 actée.
+32
View File
@@ -0,0 +1,32 @@
---
type: learnings_registry
entry_prefix: LRN
schema:
id: LRN-XXX
date: YYYY-MM-DD
pattern: string (what was observed, abstracted)
context: string (where/when it happened - concrete)
future_application: string (when to recall this)
rules:
- Capture learnings that apply beyond the current task.
- Abstract from the incident - the pattern is what is reusable, not the one-shot fact.
- Link to source (commit, file, PR) when possible.
- Replaces the previous LESSONS.md format. Old file was empty - no content to migrate.
---
# Learnings registry (LRN)
## Index
| ID | Date | Pattern | Applies to |
|----|------|---------|------------|
| LRN-001 | 2026-04-22 | `rtk` shape-compression breaks pipes | any pipeline chaining `rtk curl/cat/read` into `jq`, `python -c`, `awk` |
---
## LRN-001 — `rtk` shape-compression breaks downstream parsers
- **Date** : 2026-04-22
- **Pattern** : quand un outil de tracking (`rtk`) intercepte stdout et retourne une représentation schématisée/compressée au lieu du payload brut, tout parseur en aval casse silencieusement — parce que l'utilisateur (ou le LLM) ne voit jamais la sortie `rtk`, seulement l'erreur du parseur.
- **Contexte** : `rtk curl` remplace la sortie JSON brute par une version tokenisée, indépendamment du TTY vs pipe. Les hooks Claude Code réécrivent `curl` → `rtk curl` automatiquement, donc impossible à prévoir sans connaître le hook.
- **Application future** : pour tout outil qui auto-réécrit des commandes standard, vérifier explicitement le comportement en pipe. Workaround documenté : `exclude_commands=["curl"]` dans `~/.config/rtk/config.toml`, ou `rtk proxy`. Voir `BLK-001`.
+108
View File
@@ -0,0 +1,108 @@
# TODO
## README.md overhaul
- [x] Plan
- [x] Corriger section install ctx7 (retirer MCP, clarifier CLI + API key)
- [x] Marquer ruflo comme désactivé
- [x] Supprimer section Troubleshooting/bugs courants
- [x] Simplifier stacks tierces (gstack, ruflo, ctx7, GSD) — juste description + lien
- [x] Ajouter section skills personnels (skills-perso)
- [x] Ajouter section système d'autogestion (plugin-advisor, tokens, synergies)
- [x] Nettoyer section Updating (retirer instructions manuelles par outil)
- [x] Nettoyer section Maintenance (retirer doublon updating)
- [x] Mettre à jour table Plugins reference (ctx7 row, ruflo OFF)
- [x] Corriger lien USAGE.md dans l'intro (retirer mention cas/erreurs)
## USAGE.md cleanup
- [x] Supprimer tous les "Cas de figure — corrections vX.X.X validées"
- [x] Supprimer table "Erreurs fréquentes"
- [x] Corriger `/readme` → `/doc` dans bonnes pratiques
- [x] Supprimer séparateurs orphelins
## Skill /doc
- [x] Mettre à jour doc-syncer.md pour gérer ajouts/suppressions de features
- [x] Mettre à jour SKILL.md description pour mentionner feature delta
## Auto-activation ui-ux-pro-max sur détection design
- [x] Créer `lib/design-gate.md` — snippet réutilisable (detect design signals + ask to activate ui-ux-pro-max)
- [x] Intégrer dans feater.md — STEP 0.5 entre scope check et mini-plan
- [x] Intégrer dans hotfixer.md — STEP 1.5 (si CSS/style/animation)
- [x] Intégrer dans bugfixer.md — STEP 1.5 (si bug UI/style)
- [x] Mettre à jour plugin-advisor.md — PHASE 4 : cohérence avec le design gate
- [x] Mettre à jour CLAUDE.md skill routing — documenter le comportement auto
## Refonte agents/seo-analyzer.md
- [x] Lire agent actuel + plugin-advisor + interviewer + feater + hotfixer + analyzer
- [x] Réécrire l'agent complet v1 (11 étapes)
- [x] Ajouter orchestration sub-agents (hotfixer/feater) + triage par batches
- [x] Déplacer plugin-advisor après détection stack (STEP 3 au lieu de STEP 0)
- [x] Ajouter 2 niveaux d'audit (LOCAL code-only / FULL live+externe)
- [x] Adapter scoring, legal, GEO aux deux niveaux
- [x] Renumeroter proprement (0-14) + corriger toutes les refs internes
- [ ] Commit
## /onboard — cso archetype-aware
Problème : prompt cso fallback est non-adaptatif — cherche XSS/SQLi/CORS même sur firmware.
Objectif : charger `## Typical pain points` + `Surface sécurité` de l'archétype et les injecter dans le prompt cso.
- [x] STEP 4.5 → ajouter extraction de archetype-context.md (pain points + Surface sécurité + category) — validé sur firmware-embedded / nextjs-app-router / library
- [x] STEP 6 dispatch cso fallback → re-écrire prompt : universal checks + sections conditionnelles par category (web / embedded / library / cli / infra / data / desktop)
- [x] STEP 6 dispatch cso gstack ON → passer `--archetype <name> --context-file .onboard-audit/archetype-context.md` dans args
- [ ] OUT-OF-SCOPE ce fix : étendre le pattern à analyze/code-clean/doc (déjà reçoivent `ARCHETYPE: <name>`, juste pas le context-file). À faire dans un 2e passage si besoin.
## /validate — nouveau skill W3C + WCAG (option A)
Scope : W3C HTML validity (validator.nu API) + W3C CSS validity (jigsaw API) + WCAG a11y (axe-core CLI / pa11y / WAVE API / fallback statique). Même pattern que /harden (audit par défaut, --fix avec confirmation A/B/C/D). Rapport = VALIDATE.md racine. Complémentaire à /onboard (qui audite a11y au setup initial — /validate est l'outil on-demand réutilisable).
Design décisions :
- **Agent dédié** : `agents/validator-analyzer.md` (nouveau). Pas de réutilisation de seo-analyzer — scope différent (validité syntaxique vs indexabilité).
- **Depth** : LOCAL (fichiers HTML/CSS statiques, tools npm locaux si dispo) | FULL (URL live + APIs distantes W3C/WAVE).
- **External validators** : validator.nu/?out=json (HTML), jigsaw.w3.org/css-validator (CSS), WAVE API optionnelle (quota gratuit ~100/mois), axe-cli local, pa11y-cli local.
- **Tools fallback order** : npm tools locaux → APIs distantes → agent général statique (cas onboard). Aucun install forcé.
- **--fix conservateur** : `alt=""` sur images décoratives évidentes, `lang` sur `<html>`, fermetures de tags manquantes, sauts de niveau heading renumérotés. PAS : labels forms, contraste couleurs, landmarks (demandent décision humaine).
- **Out of scope** : meta tags/SEO → /seo ; JSON-LD → /geo ; security headers → /harden ; code linting générique (ESLint/Prettier) → hors scope web standards.
Subtasks :
- [x] Créer `agents/validator-analyzer.md` — spec 6 étapes (478 lignes)
- [x] Créer `skills/validate/SKILL.md` — dispatcher (378 lignes)
- [x] Ajouter routage `/validate` dans `~/.claude/CLAUDE.md` section "Skill routing"
- [x] Mettre à jour `skills/harden/SKILL.md` — W3C/a11y redirigé vers /validate
- [x] Mettre à jour `skills/seo/SKILL.md` — cross-ref /validate pour W3C/WCAG
- [x] Grep cohérence : refs /validate correctes, skill détecté par la harness
## Helper `--help` / `help` sur tous les skills (option C)
Problème : aucun skill ne gère `--help` aujourd'hui. `argument-hint` affiche juste la syntaxe en autocomplétion, pas de description/exemples. L'utilisateur doit lire le SKILL.md ou deviner.
Objectif : `/<skill> --help` (ou `/<skill> help`) affiche un bloc standardisé (description, args, exemples, cross-refs) et exit SANS dispatcher l'agent ni modifier quoi que ce soit.
Design :
- **Lib partagée** : créer `skills/lib/help-handler.md` — snippet réutilisable "if $ARGUMENTS contains --help|help|-h, extract frontmatter fields (description, argument-hint, cross-refs) + afficher bloc d'aide standardisé + STOP".
- **Format d'aide** standardisé :
```
/<skill> — <titre court>
DESCRIPTION
<extrait de la frontmatter description, dépouillé des Triggers>
USAGE
/<skill> <argument-hint>
ARGUMENTS
<liste détaillée de chaque flag avec son effet — nouvelle section
dans les SKILL.md, ou parsée depuis STEP 0 arg parsing>
EXAMPLES
<3-4 exemples concrets>
SEE ALSO
<extrait des "For X → use /Y" de la frontmatter>
```
- **Intégration** : ajouter STEP 0.5 ("Handle --help") dans chaque SKILL.md juste après STEP 0 parsing args. Ordre : parse args → check --help → si oui afficher + exit → sinon continuer.
- **Skills à patcher** : `~/Documents/claude/skills/` = ~20 skills persos + skills-perso list pour référence. Ne PAS toucher skills-external/gstack (ownership externe) ni example-skills.
Subtasks :
- [ ] Créer `skills/lib/help-handler.md` — snippet réutilisable (détection + extraction + affichage)
- [ ] Définir format d'aide standard + section "ARGUMENTS" vs reuse de argument-hint
- [ ] Décider : sections ARGUMENTS/EXAMPLES doivent-elles être dans la frontmatter (nouveau champ YAML) ou dans le corps du SKILL.md (nouvelle section `## Help`) ?
- [ ] Patcher un skill pilote (`/validate`) — valider UX
- [ ] Patcher les skills perso restants : analyze, bugfix, code-clean, commit-change, doc, feat, geo, graphify, harden, hotfix, init-project, make-pdf, onboard, plan-tune, plugin-check, refactor, seo, ship-feature, skills-perso, status, benchmark-models, context-save, context-restore
- [ ] Mettre à jour `~/.claude/CLAUDE.md` — mentionner convention --help disponible sur tous les skills perso
- [ ] Note : skills-external/gstack ont leur propre convention, ne pas toucher
+85
View File
@@ -0,0 +1,85 @@
# `rtk curl` breaks downstream parsers by returning compressed schema instead of raw payload when stdout is piped
## Summary
`rtk curl` always returns a token-compressed, schema-like representation of the response body, regardless of whether stdout is a TTY or a pipe. This silently breaks any command that pipes `rtk curl` into a parser expecting the raw payload (`python -c "json.load(sys.stdin)"`, `jq`, `node -e`, `awk`, `sed`, etc.).
Because the Claude Code hook (`rtk-rewrite.sh`) auto-rewrites `curl` → `rtk curl`, this affects every such pipeline the LLM constructs — even though the LLM never sees the rtk-compressed output, only the downstream parser error.
## Reproduction
```bash
# Expected: prints "Hello World"
curl -s "https://api.mymemory.translated.net/get?q=Bonjour%20monde&langpair=fr%7Cen" \
| python3 -c "import json,sys; d=json.load(sys.stdin); print(d['responseData']['translatedText'])"
```
Under the Claude Code hook (or when the user explicitly writes `rtk curl`), this pipeline fails:
```
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 2 column 3 (char 4)
```
Because `rtk curl` returns:
```
{
exception_code: null,
matches:
[{
create-date: string,
created-by: string,
...
```
instead of the raw JSON body that `json.load` expects.
## Impact
- Any LLM-generated pipeline using `curl | <parser>` breaks silently.
- Root cause is opaque to the LLM: the tool sees a JSONDecodeError and blames its own parsing code, not rtk.
- The Claude Code hook compounds the issue: users running `curl ... | jq` from the assistant never typed `rtk`, yet get hit by it.
- Other rtk subcommands that transform output (`rtk aws`, `rtk psql`, `rtk json`, `rtk cat`) likely have the same class of bug.
## Root cause
`rtk curl` is not a passthrough — it post-processes the response body for LLM consumption. This is correct behavior when an LLM is the consumer. It is incorrect when a parser is the consumer.
The tool currently has no way to distinguish those two cases.
## Suggested fix
Detect `isatty(stdout)` at startup. If stdout is **not** a TTY (i.e., it is piped, redirected to a file, or captured), skip the compression layer and passthrough the raw response bytes from the underlying `curl`.
This matches the long-standing Unix convention followed by `ls`, `grep`, `diff`, etc., which disable colors and column formatting when piped.
```rust
// pseudo-code inside rtk curl
if !io::stdout().is_terminal() {
return run_native_curl_passthrough(args);
}
// else: existing compression path
```
The same fix should apply to every rtk subcommand that transforms output (`cat`, `read`, `json`, `aws`, `psql`, `git`, `gh`, etc.).
## Alternative / workaround
- Users can prefix with `rtk proxy <cmd>` to bypass rewriting. But the Claude Code hook rewrites `curl` unconditionally, so the LLM has to *remember* to write `rtk proxy curl` every time it pipes, which does not scale.
- Users can set `[hooks] exclude_commands = ["curl"]` in `~/.config/rtk/config.toml`, but this disables all rtk curl savings globally, even when the LLM IS the consumer.
Neither replaces a proper TTY-aware passthrough inside rtk itself.
## Environment
- rtk: 0.34.3
- OS: Linux 6.17
- Shell: bash
- Claude Code hook: `hooks/rtk-rewrite.sh` (rtk-hook-version: 3)
## Checklist
- [ ] `rtk curl` passes through raw bytes when stdout is not a TTY
- [ ] Same behavior for `rtk cat`, `rtk read`, `rtk json`, `rtk aws`, `rtk psql`, `rtk git`, `rtk gh`
- [ ] Add a test matrix: piped to `jq`, `python -c "json.load"`, file redirect, `/dev/null`
- [ ] Document the TTY-aware behavior in the README