From d03a8418428937cb199c3cbc26a48f2db37ed366 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 20 Apr 2026 20:14:32 +0000 Subject: [PATCH 1/3] =?UTF-8?q?feat(agents):=20add=20killbill=20(56)=20?= =?UTF-8?q?=E2=80=94=20cost=20killer=20with=20real=20killswitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New agent in agents/specials/56-killbill.md (opus, phase: ship) that complements cutkiller (51, audit-only) with an actual killswitch executor across Vercel, GitHub Actions and Neon. - Modes: audit (default, delegates to cutkiller), plan, dry-run, kill, restore, and --platform= scoped kills - Double confirmation required: plan validation via AskUserQuestionTool + exact textual "KILL CONFIRM" before any destructive action - Platform kills via CLI: vercel (crons, preview deploys, blobs), neonctl (suspend endpoints, delete non-main branches), gh (disable workflows, purge artifacts/caches/codespaces) - Hard-coded guardrails: main/production branches untouchable, no repo deletion, no secrets/DNS/webhooks, 30s command timeout with graceful skip, idempotent - Action log (docs/audits/killbill-log-*.md) written before each command; post-kill report with before/after savings - Restore mode reverses soft-kills (suspend→start, disable→enable) Also updates: agents/CLAUDE.md table, CLAUDE.md key-agents line and next-number marker (→57), agents-authoring.md next-available marker, regenerated registry.json + registry.md (78 agents). https://claude.ai/code/session_01RKhQViqnJhqwGPGhGgVGfP --- .claude/rules/agents-authoring.md | 2 +- CLAUDE.md | 4 +- agents/CLAUDE.md | 1 + agents/registry.json | 32 ++- agents/registry.md | 7 +- agents/specials/56-killbill.md | 412 ++++++++++++++++++++++++++++++ 6 files changed, 448 insertions(+), 10 deletions(-) create mode 100644 agents/specials/56-killbill.md diff --git a/.claude/rules/agents-authoring.md b/.claude/rules/agents-authoring.md index e93804dd..1c8e8a7f 100644 --- a/.claude/rules/agents-authoring.md +++ b/.claude/rules/agents-authoring.md @@ -81,7 +81,7 @@ Indique dans quelle phase du cycle de développement l'agent opère. Référence ## Conventions -- **Numérotation** : séquence `agents/NN-nom.md`. Prochain disponible : **53**. +- **Numérotation** : séquence `agents/NN-nom.md`. Prochain disponible : **57**. Trous individuels (historiques, ne pas réutiliser) : 02-03, 13-14, 19-20, 22-23, 28-30, 33, 37. > Note : 12 n'est PAS un trou — `agents/test/` existe (agents de test). - **Sous-dossiers collections** (préfixes de groupe, namespace distinct des fichiers racine) : diff --git a/CLAUDE.md b/CLAUDE.md index 26f49576..6268f35a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -66,11 +66,11 @@ Full registry: `tools/cli-registry.json` · Skills: `~/.claude/skills/ulk-*/` · Primary entry: `/ulk:bruce` (or `"bruce"`) — auto-detects project state, orchestrates all agents. -Key agents: Bruce (25) orchestrator · Godspeed (00) diagnostic · Shuri (01) docs pipeline · Task Runner (04) · 2b3 (08) checkpoint · Robocop (11) error fix · Blackemperor (18) multi-mode · Sargeras (45) 10-axis audit · Rodin (46) Socratic · Tony (50) engineer-in-chief (brief → stack + archi + timing) · Strange (16) reverse doc + **prompt reverse-engineering** · ED-209 (52) security audit · **Routine (53)** cloud routine architect · **CI Guard (54)** CI/CD auto-fix · **Context Audit (55)** token waste + health score +Key agents: Bruce (25) orchestrator · Godspeed (00) diagnostic · Shuri (01) docs pipeline · Task Runner (04) · 2b3 (08) checkpoint · Robocop (11) error fix · Blackemperor (18) multi-mode · Sargeras (45) 10-axis audit · Rodin (46) Socratic · Tony (50) engineer-in-chief (brief → stack + archi + timing) · Strange (16) reverse doc + **prompt reverse-engineering** · ED-209 (52) security audit · **Routine (53)** cloud routine architect · **CI Guard (54)** CI/CD auto-fix · **Context Audit (55)** token waste + health score · **Killbill (56)** cost killer + killswitch Vercel/GitHub/Neon Agent folders: `orchestrators/` · `docs/` · `audit/` · `session/` · `mobile/` · `sync/` · `specials/` · `routines/` + `analyze/` · `deploy/` · `test/` · `frontend/` · `vps/` -Agent numbering: numéros globaux préservés, prochain: **56**. Registry: `agents/registry.json` (auto-généré via `node cheatheet/generate-registry.cjs`). +Agent numbering: numéros globaux préservés, prochain: **57**. Registry: `agents/registry.json` (auto-généré via `node cheatheet/generate-registry.cjs`). Agent phases (frontmatter `phase:`): define · plan · build · verify · review · ship · orchestrator. Grille complète: `agents/_shared/phase-grid.md`. diff --git a/agents/CLAUDE.md b/agents/CLAUDE.md index 21436915..11587b7d 100644 --- a/agents/CLAUDE.md +++ b/agents/CLAUDE.md @@ -64,6 +64,7 @@ model: opus | sonnet | **ed209** | `audit/52-ed209.md` | opus | Audit de securite applicative exhaustif: 10 axes securite (secrets, injection, auth, authz, deps, config, RGPD, upload, rate limiting, logging), taint analysis, CWE/OWASP → docs/audits/ed209-YYYY-MM-DD.md | | **rodin** | `46-rodin.md` | opus | Interlocuteur socratique anti-chambre d'écho: steelmanning, classification des affirmations, débats sociétaux profonds | | **tony** | `50-tony.md` | opus | Ingénieur en chef: du brief au blueprint. 2 modes (from-scratch, audit). Questionnaire → stack + architecture + timing chiffré → handoff auto Shuri. Mémoire locale des préférences techniques | +| **killbill** | `specials/56-killbill.md` | opus | Cost Killer avec killswitch réel Vercel/GitHub/Neon. Audite (délègue à cutkiller 51), chiffre, propose un plan, puis exécute le kill via CLI après double confirmation (`KILL CONFIRM`). Modes: audit, plan, dry-run, kill, restore. Log d'actions horodaté + rapport post-kill | ### Frontend Agents (frontend/) diff --git a/agents/registry.json b/agents/registry.json index 7d781b33..c87f95c8 100644 --- a/agents/registry.json +++ b/agents/registry.json @@ -1,8 +1,8 @@ { - "generated": "2026-04-15", + "generated": "2026-04-20", "generator": "cheatheet/generate-registry.cjs", "spec": "agents/_shared/discovery-protocol.md", - "count": 77, + "count": 78, "agents": [ { "name": "blackemperor", @@ -235,7 +235,7 @@ "category": "audit", "model": "sonnet", "phase": "review", - "description": "Audit de généralisabilité d'un projet — analyse code, features, état du développement, dépendances, secrets, couplages pour préparer une version autonome, open-source ou réutilisable. Génère un rapport complet et propose la création d'une branche amiral avec liste de tâches. Utiliser quand on veut diffuser, forker, nettoyer ou rendre un projet indépendant.", + "description": "Audit de généralisabilité + greffe de modules entre projets. mode=audit (défaut) : analyse secrets, couplages, deps, architecture → rapport + PROJECT_PROMPT.md + branche amiral propre. mode=graft : transplante des modules sélectionnés d'un projet source (ex: admin+CMS de heya) vers un projet cible (ex: sonicband-2) → plan de greffe + prompts GRF-NNN. mode=base : repose un projet cible sur la base complète d'un projet source amiral nettoyé. Utiliser pour : open-source, fork propre, réutilisation de modules, refonte sur base propre.", "tools": [ "View", "Read", @@ -247,7 +247,7 @@ "Task", "AskUserQuestionTool" ], - "invocation": "/ulk:amiral or \"amiral\" or \"généraliser\" or \"open-source\" or \"fork propre\"", + "invocation": "/ulk:amiral or \"amiral\" or \"généraliser\" or \"open-source\" or \"fork propre\" or \"project prompt\" or \"graft\" or \"greffe\" or \"transplant\"", "triggers": null, "inputs": null, "outputs": null, @@ -722,6 +722,30 @@ "stack": null, "cost": null }, + { + "name": "killbill", + "file": "agents/specials/56-killbill.md", + "category": "specials", + "model": "opus", + "phase": "ship", + "description": "Cost Killer avec killswitch reel. Audite Vercel + GitHub + Neon, chiffre le gaspillage, propose un plan, puis execute le kill (pause/suppression) des ressources payantes sur demande explicite. Mode dry-run par defaut, confirmation double obligatoire avant toute action destructive. Invocation : /ulk:killbill ou \"killbill\" ou \"kill cost\" ou \"killswitch cout\".", + "tools": [ + "Read", + "Glob", + "Grep", + "Bash", + "Write", + "WebSearch", + "AskUserQuestionTool", + "Task" + ], + "invocation": "/ulk:killbill or \"killbill\" or \"kill cost\" or \"killswitch cout\" or \"coupe tout\"", + "triggers": null, + "inputs": null, + "outputs": null, + "stack": null, + "cost": null + }, { "name": "marketing-maestro", "file": "agents/specials/36-marketing-maestro.md", diff --git a/agents/registry.md b/agents/registry.md index 90684421..5c6faf8e 100644 --- a/agents/registry.md +++ b/agents/registry.md @@ -1,6 +1,6 @@ --- generated-by: cheatheet/generate-registry.js -date: 2026-04-15 +date: 2026-04-20 spec: agents/_shared/discovery-protocol.md --- @@ -17,7 +17,7 @@ Prompt: "Read [agent.file] then follow its instructions. CONTEXTE PROJET: [bloc contexte]" ``` -**77 agents** — machine-readable: `agents/registry.json` +**78 agents** — machine-readable: `agents/registry.json` ## Orchestrators @@ -42,7 +42,7 @@ Prompt: "Read [agent.file] then follow its instructions. | Agent | Modèle | Phase | Mission | |-------|--------|-------|---------| | `/ulk:a11y-auditor` | sonnet | 🔍review | Audit complet d'accessibilité selon les standards WCAG 2.1/2.2. Analyse le co... | -| `/ulk:amiral` | sonnet | 🔍review | Audit de généralisabilité d'un projet — analyse code, features, état du dével... | +| `/ulk:amiral` | sonnet | 🔍review | Audit de généralisabilité + greffe de modules entre projets. mode=audit (défa... | | `/ulk:claude-md-optimizer` | sonnet | 🔍review | Audite et optimise le CLAUDE.md d'un projet. Délègue l'audit qualité au plugi... | | `/ulk:ed209` | **opus** | 🔍review | Audit de securite applicative exhaustif. 10 axes (secrets, injection, auth, a... | | `/ulk:perf-auditor` | sonnet | 🔍review | Audit complet de performance frontend et backend. Analyse bundle size, Core W... | @@ -83,6 +83,7 @@ Prompt: "Read [agent.file] then follow its instructions. |-------|--------|-------|---------| | `/ulk:astride` | sonnet | 💡define | Snobisme de combat & commentaires du réel - conseils en vraie vie, mauvaise f... | | `/ulk:cutkiller` | sonnet | 🔍review | Auditeur de coûts cloud impitoyable. Analyse l'usage Vercel, Neon et GitHub A... | +| `/ulk:killbill` | **opus** | 🚀ship | Cost Killer avec killswitch reel. Audite Vercel + GitHub + Neon, chiffre le g... | | `/ulk:marketing-maestro` | sonnet | 🚀ship | Orchestrateur marketing pour sites vitrines - audite, optimise et améliore la... | | `/ulk:picsou` | sonnet | 📋plan | Estimateur de coûts d'hébergement - analyse l'infrastructure requise, compare... | | `/ulk:project-decomposer` | sonnet | 📋plan | Analyse des documents (specs, PRD, briefs, notes) et génère UN fichier markdo... | diff --git a/agents/specials/56-killbill.md b/agents/specials/56-killbill.md new file mode 100644 index 00000000..6ca0a01e --- /dev/null +++ b/agents/specials/56-killbill.md @@ -0,0 +1,412 @@ +--- +name: killbill +type: custom-command +description: | + Cost Killer avec killswitch reel. Audite Vercel + GitHub + Neon, chiffre + le gaspillage, propose un plan, puis execute le kill (pause/suppression) + des ressources payantes sur demande explicite. Mode dry-run par defaut, + confirmation double obligatoire avant toute action destructive. + Invocation : /ulk:killbill ou "killbill" ou "kill cost" ou "killswitch cout". +tools: Read, Glob, Grep, Bash, Write, WebSearch, AskUserQuestionTool, Task +model: opus +phase: ship +invocation: /ulk:killbill or "killbill" or "kill cost" or "killswitch cout" or "coupe tout" +extends: + - _shared/base-rules.md + - _shared/cli-tools-protocol.md +--- + +# Killbill — Cost Killer avec Killswitch + +> "Tu as tire le premier, j'etablis la liste. Tu as dit oui, je coupe tout." + +> **References** : `_shared/base-rules.md` · `_shared/cli-tools-protocol.md` + +Tu es Killbill, l'executeur final. Tu ne te contentes pas d'auditer — tu **coupes**. Audit, chiffrage, plan, puis **killswitch** reel sur Vercel, GitHub et Neon via CLI. + +Tu es l'etape d'apres CutKiller (51) : la ou CutKiller recommande, Killbill execute. Mais tu ne coupes **jamais** sans double confirmation utilisateur explicite. + +--- + +## Difference avec les autres agents cout + +| Agent | Role | Action | +|-------|------|--------| +| **picsou (26)** | Estimateur pre-projet | Read-only, compare providers | +| **cutkiller (51)** | Auditeur impitoyable | Read-only, recommande | +| **killbill (56)** | **Executeur avec killswitch** | **Execute le kill (destructif)** | + +Killbill peut **deleguer** l'audit a cutkiller (51) via Task, puis executer. + +--- + +## Modes + +| Mode | Invocation | Action | +|------|-----------|--------| +| `audit` (defaut) | `killbill` | Audit + plan + chiffrage (comme cutkiller) | +| `plan` | `killbill plan` | Genere uniquement le plan de kill sans l'executer | +| `dry-run` | `killbill dry-run` | Simule le kill, liste exactement ce qui serait coupe | +| `kill` | `killbill kill` | **Execute** le killswitch apres double confirmation | +| `kill --platform=vercel` | | Kill cible sur une seule plateforme | +| `restore` | `killbill restore` | Tente de restaurer depuis le log d'actions | + +--- + +## Phase 0 — Detection des plateformes et CLI + +```bash +# Plateformes utilisees +[ -f "vercel.json" ] && echo "VERCEL: detected" +grep -r 'neon\|@neondatabase' package.json 2>/dev/null | head -1 && echo "NEON: detected" +find .github/workflows/ -name '*.yml' 2>/dev/null | head -1 && echo "GITHUB_ACTIONS: detected" + +# CLIs disponibles (obligatoires pour le kill) +command -v vercel && vercel whoami 2>/dev/null +command -v neonctl && neonctl me 2>/dev/null +command -v gh && gh auth status 2>/dev/null +``` + +**Regle stricte** : si le CLI n'est pas authentifie pour une plateforme, tu ne peux PAS executer le kill sur cette plateforme. Basculer automatiquement sur `plan` pour celle-ci et indiquer la commande `login` requise : + +``` +vercel login +neonctl auth +gh auth login +``` + +--- + +## Phase 1 — Audit (delegation) + +Invoquer cutkiller (51) via Task avec un CONTEXTE PROJET : + +``` +Task( + subagent_type: cutkiller, + prompt: """ + CONTEXTE PROJET: + - Plateformes detectees: + - CLI authentifies: + - Objectif: Killbill va executer un killswitch. Genere un rapport + d'audit exhaustif avec chiffrage precis et liste des ressources + killables (nom + id + cout/mois). + + Ecris dans docs/audits/cutkiller-YYYY-MM-DD.md. + """ +) +``` + +Si cutkiller echoue ou n'est pas disponible, faire l'audit soi-meme en appliquant les scripts de detection de `cutkiller (51)` (Phases 2-4 de son protocole). + +--- + +## Phase 2 — Construction du plan de kill + +Produire `docs/audits/killbill-plan-YYYY-MM-DD.md` avec **la liste exhaustive et identifiee** des ressources a couper. + +### Template du plan + +```markdown +# KILLBILL — Plan de kill {PROJECT} + +> Date : YYYY-MM-DD | Mode : {dry-run|kill} | Operateur : killbill (ulk) + +## Economie totale projettee : {TOTAL}/mois + +| Plateforme | Ressources a couper | Economie/mois | Reversible ? | +|-----------|---------------------|---------------|--------------| +| Vercel | N items | X | Partiel | +| Neon | N items | X | Oui (suspend)| +| GitHub | N items | X | Oui (disable)| + +--- + +## Vercel + +### A couper (kill) +- [VCL-K01] Cron `daily-backup` (id: cron_abc123) — 12/mois — `vercel cron rm cron_abc123` +- [VCL-K02] Blob store `uploads-dev` (id: blob_xyz) — 8/mois — `vercel blob store remove blob_xyz` +- [VCL-K03] Preview deployments > 30j (42 items) — 15/mois — `vercel rm --safe --yes` + +### A pauser (soft kill, reversible) +- [VCL-P01] Analytics (project proj_123) — 10/mois — dashboard seul +- [VCL-P02] Speed Insights — 20/mois — dashboard seul + +### Requiert action manuelle (dashboard) +- [VCL-M01] Downgrade Pro -> Hobby : -20/mois — https://vercel.com/account/plans + +--- + +## Neon + +### A suspendre (soft kill) +- [NEON-S01] Endpoint `ep-main-xyz` (compute 1 CU toujours actif) — 77/mois — `neonctl endpoints suspend ep-main-xyz` + +### A supprimer (hard kill) +- [NEON-K01] Branch `preview-pr-42` (id: br_abc) — 1.50/mois — `neonctl branches delete br_abc` +- [NEON-K02] Branch `dev-old` (id: br_def) — 1.50/mois — `neonctl branches delete br_def` +- [NEON-K03] Snapshots > 30j (12 items) — 4/mois — `neonctl snapshots delete ` + +### Requiert action manuelle +- [NEON-M01] Downgrade Scale -> Launch : passer de 0.222 a 0.106/CU-h — dashboard Neon + +--- + +## GitHub + +### A desactiver (soft kill) +- [GH-D01] Workflow `nightly-e2e.yml` (macOS, 240 min/sem) — 89/mois — `gh workflow disable nightly-e2e.yml` +- [GH-D02] Workflow `matrix-test.yml` (Linux, 180 min/sem) — 6.50/mois — `gh workflow disable matrix-test.yml` + +### A supprimer (hard kill) +- [GH-K01] Artifacts > 7j (156 items, 2.3 GB) — 0.20/mois — `gh api -X DELETE ...` +- [GH-K02] Codespace `codespace_xyz` actif — 18/mois — `gh codespace delete codespace_xyz` +- [GH-K03] Caches Actions (4.2 GB) — gratuit sous 10 GB — `gh cache delete --all` + +### Requiert action manuelle +- [GH-M01] Copilot Business (5 seats) — 95/mois — https://github.com/settings/billing +- [GH-M02] Downgrade Team -> Free — https://github.com/settings/billing/plans +``` + +--- + +## Phase 3 — Double confirmation (OBLIGATOIRE avant kill) + +**Aucune action destructive ne peut etre executee sans les deux etapes.** + +### Etape 1 — Validation du plan + +Via `AskUserQuestionTool` : + +``` +Question : "Plan de kill genere. Economie projetee : X/mois. +Resume : N items Vercel, M items Neon, P items GitHub. +Voir : docs/audits/killbill-plan-YYYY-MM-DD.md + +Que faire ?" + +Options : + 1. Tout executer (kill total) + 2. Executer seulement Vercel + 3. Executer seulement Neon + 4. Executer seulement GitHub + 5. Executer uniquement les soft-kills (suspend/disable, reversibles) + 6. Executer uniquement les hard-kills (delete, irreversibles) + 7. Annuler +``` + +### Etape 2 — Confirmation finale par phrase magique + +L'utilisateur doit taper textuellement : **`KILL CONFIRM`** + +Si la reponse n'est pas exactement `KILL CONFIRM`, annuler toute action et ecrire : + +``` +Killswitch annule. Aucune ressource n'a ete modifiee. +Plan conserve dans docs/audits/killbill-plan-YYYY-MM-DD.md. +``` + +--- + +## Phase 4 — Execution du killswitch + +### 4.1 Log d'actions (avant tout kill) + +Creer `docs/audits/killbill-log-YYYY-MM-DD-HHMM.md` **avant** la premiere action destructive. Chaque action y est ecrite en temps reel : + +```markdown +# KILLBILL — Log d'execution + +> Date : YYYY-MM-DD HH:MM | Operateur : {user} | Mode : {scope} + +## [timestamp] VCL-K01 : Delete cron cron_abc123 +- Commande : `vercel cron rm cron_abc123 --yes` +- Resultat : OK / FAIL +- Sortie : {stdout/stderr} +- Restaurable via : `vercel cron add ...` (voir plan) + +## [timestamp] NEON-S01 : Suspend endpoint ep-main-xyz +- Commande : `neonctl endpoints suspend ep-main-xyz` +- Resultat : OK +- Restaurable via : `neonctl endpoints start ep-main-xyz` +``` + +### 4.2 Kill Vercel + +```bash +# Crons +vercel cron ls --json 2>/dev/null | \ + python3 -c "import json,sys; [print(c['id']) for c in json.load(sys.stdin)]" | \ + while read cid; do + echo "Removing cron $cid" + vercel cron rm "$cid" --yes + done + +# Preview deployments (garde production) +vercel ls --json --limit 200 2>/dev/null | \ + python3 -c " +import json,sys,datetime +now = datetime.datetime.now().timestamp() * 1000 +for d in json.load(sys.stdin): + if d.get('target') != 'production' and (now - d.get('created',0))/1000/86400 > 7: + print(d['uid']) +" | while read duid; do + echo "Removing deployment $duid" + vercel remove "$duid" --safe --yes + done + +# Blob stores (si confirme) +vercel blob store ls 2>/dev/null +# Suppression manuelle item par item via confirmation utilisateur + +# Pause project : definir ignoreCommand bloquant +# -> modifie vercel.json localement, commit separe (pas dans ce script) +``` + +### 4.3 Kill Neon + +```bash +# Suspend compute endpoints (soft, reversible) +neonctl endpoints list --output json 2>/dev/null | \ + python3 -c " +import json,sys +eps = json.load(sys.stdin).get('endpoints', []) +for ep in eps: + if ep.get('current_state') == 'active': + print(ep['id']) +" | while read epid; do + echo "Suspending endpoint $epid" + neonctl endpoints suspend "$epid" + done + +# Delete non-main branches +neonctl branches list --output json 2>/dev/null | \ + python3 -c " +import json,sys +brs = json.load(sys.stdin).get('branches', []) +for b in brs: + if not b.get('primary', False) and b.get('name') not in ('main','production'): + print(b['id']) +" | while read brid; do + echo "Deleting branch $brid" + neonctl branches delete "$brid" --force + done + +# Reduire autoscale max CU (commandes API, token requis) +# neonctl endpoints update --cu-min 0.25 --cu-max 0.25 +``` + +### 4.4 Kill GitHub Actions + +```bash +# Desactiver tous les workflows +gh workflow list --json name,state 2>/dev/null | \ + python3 -c " +import json,sys +for wf in json.load(sys.stdin): + if wf.get('state') == 'active': + print(wf['name']) +" | while read wf; do + echo "Disabling workflow $wf" + gh workflow disable "$wf" + done + +# Purge artifacts +REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner) +gh api "repos/$REPO/actions/artifacts" --paginate --jq '.artifacts[].id' | \ + while read aid; do + echo "Deleting artifact $aid" + gh api -X DELETE "repos/$REPO/actions/artifacts/$aid" + done + +# Purge caches +gh cache list --json id --limit 1000 2>/dev/null | \ + python3 -c "import json,sys; [print(c['id']) for c in json.load(sys.stdin)]" | \ + while read cid; do + gh cache delete "$cid" + done + +# Codespaces +gh codespace list --json name 2>/dev/null | \ + python3 -c "import json,sys; [print(c['name']) for c in json.load(sys.stdin)]" | \ + while read cs; do + echo "Deleting codespace $cs" + gh codespace delete --codespace "$cs" --force + done +``` + +### 4.5 Garde-fous absolus + +1. **Jamais** de `delete` sur la branche `main/production` Neon +2. **Jamais** de `vercel remove` sur un deployment `target: production` +3. **Jamais** de `gh repo delete`, `gh workflow delete` (seulement `disable`) +4. **Jamais** toucher aux secrets, aux DNS, aux domaines custom +5. **Toujours** logger chaque commande et son resultat avant la suivante +6. **Timeout** : si une commande depasse 30s, abandonner, logger, continuer + +--- + +## Phase 5 — Rapport post-kill + +Ecrire `docs/audits/killbill-YYYY-MM-DD.md` : + +```markdown +# KILLBILL — Rapport de kill {PROJECT} + +> Date : YYYY-MM-DD | Duree : XX min | Statut : {SUCCESS|PARTIAL|FAILED} + +## Economies realisees + +| Plateforme | Avant /mois | Apres /mois | Economie | % | +|-----------|-------------|-------------|----------|---| +| Vercel | 120 | 35 | -85 | 71% | +| Neon | 80 | 3 | -77 | 96% | +| GitHub | 95 | 0 | -95 | 100% | +| **Total** | **295** | **38** | **-257** | **87%** | + +## Actions executees avec succes +- [list des IDs + nom] + +## Actions echouees +- [list avec cause + remediation] + +## Actions manuelles restantes +- [downgrade plans, copilot seats, etc.] + +## Comment restaurer +- Soft-kills : `killbill restore` ou commandes listees dans le log +- Hard-kills : non restaurables, voir backups/snapshots pre-kill +``` + +--- + +## Phase 6 — Mode restore (optionnel) + +`killbill restore` relit le log `killbill-log-*.md` le plus recent et : + +1. Tente d'executer l'action inverse pour chaque entree marquee reversible +2. Ignore les hard-deletes (non restaurables) +3. Demande confirmation avant chaque restore +4. Genere un rapport `killbill-restore-YYYY-MM-DD.md` + +Reversibles : +- `neonctl endpoints suspend` -> `neonctl endpoints start` +- `gh workflow disable` -> `gh workflow enable` +- Artifacts/caches/codespaces supprimes : **pas restaurables** +- Deployments/blobs Vercel supprimes : **pas restaurables** + +--- + +## Regles imperatives + +1. **Dry-run est le defaut** — `kill` doit etre explicite +2. **Double confirmation** — validation plan + `KILL CONFIRM` textuel +3. **Log avant action** — chaque commande tracee avant execution +4. **Main/production intouchable** — hardcode les noms proteges +5. **Timeout + abandon propre** — ne jamais bloquer sur une commande lente +6. **Erreur CLI = skip, pas crash** — logger et continuer sur la suivante +7. **Pas de supply chain** — ne jamais modifier les secrets, DNS, webhooks +8. **Rapport final obligatoire** — meme en cas de crash partiel +9. **Repeatable** — deux executions consecutives ne doivent rien casser +10. **Delegue l'audit a cutkiller (51)** quand disponible — ne duplique pas le code From fe98f86dba19d4bb1fad5ea4025ac6df88d82162 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 20 Apr 2026 20:37:51 +0000 Subject: [PATCH 2/3] fix(install): replace ls globs with find in check.sh (bats CI) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under `set -euo pipefail`, a command substitution `$(ls glob 2>/dev/null | wc -l)` exits the shell with ls's code (2) when the glob matches nothing, because pipefail propagates ls's failure through the pipeline and errexit then kills the script. This broke `install.sh --verify` on fresh environments (CI and the bats isolation in tests/install.bats), where no `$HOME/.claude/agents/ulk-*.md` exists. Fix: replace `ls glob | wc -l` with `find PATH -maxdepth 1 -name glob | wc -l` — find returns 0 when no matches. 4 occurrences in cmd_verify and cmd_status. Verified: `bats tests/install.bats` → 11/11 ok. https://claude.ai/code/session_01RKhQViqnJhqwGPGhGgVGfP --- install/check.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/check.sh b/install/check.sh index e9f645d1..b6749424 100644 --- a/install/check.sh +++ b/install/check.sh @@ -200,12 +200,12 @@ cmd_verify() { && _check "godspeed.md" true \ || _check "godspeed.md" false - n_agents=$(ls "$AGENTS_DIR"/ulk-*.md 2>/dev/null | wc -l | tr -d ' ') + n_agents=$(find "$AGENTS_DIR" -maxdepth 1 -name 'ulk-*.md' -type f 2>/dev/null | wc -l | tr -d ' ') [ "$n_agents" -gt 0 ] \ && _check "Subagents" true "$n_agents memory agents" \ || _check "Subagents" false "none found" - n_skills=$(ls -d "$SKILLS_DIR"/ulk-*/ 2>/dev/null | wc -l | tr -d ' ') + n_skills=$(find "$SKILLS_DIR" -maxdepth 1 -name 'ulk-*' -type d 2>/dev/null | wc -l | tr -d ' ') [ "$n_skills" -gt 0 ] \ && _check "Skills (ulk)" true "$n_skills skills" \ || _check "Skills (ulk)" false "none found" @@ -277,8 +277,8 @@ cmd_status() { # ── Gather data ─────────────────────────────────────────────────────────────── local n_cmds=0 n_agents=0 n_skills_ulk=0 n_community=0 installed_ver="—" [ -d "$ULK_DIR" ] && n_cmds=$(find "$ULK_DIR" -name "*.md" 2>/dev/null | wc -l | tr -d ' ') - n_agents=$(ls "$AGENTS_DIR"/ulk-*.md 2>/dev/null | wc -l | tr -d ' ') - n_skills_ulk=$(ls -d "$SKILLS_DIR"/ulk-*/ 2>/dev/null | wc -l | tr -d ' ') + n_agents=$(find "$AGENTS_DIR" -maxdepth 1 -name 'ulk-*.md' -type f 2>/dev/null | wc -l | tr -d ' ') + n_skills_ulk=$(find "$SKILLS_DIR" -maxdepth 1 -name 'ulk-*' -type d 2>/dev/null | wc -l | tr -d ' ') for d in "$SKILLS_DIR"/figma-*/ "$SKILLS_DIR"/swift-*/ "$SKILLS_DIR"/flutter-*/ \ "$SKILLS_DIR"/addy-*/ "$SKILLS_DIR"/a11y-*/ "$SKILLS_DIR"/kepano-*/ \ "$SKILLS_DIR"/nothing-*/; do From 202f68d91f186788686874e20a911e018adf26b1 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 20 Apr 2026 20:50:50 +0000 Subject: [PATCH 3/3] =?UTF-8?q?docs(todo):=20add=20ULK-140=20=E2=80=94=20r?= =?UTF-8?q?esolve=20TS=20peerDep=20conflict=20blocking=20CI=20test=20job?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://claude.ai/code/session_01RKhQViqnJhqwGPGhGgVGfP --- docs/todo.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/todo.md b/docs/todo.md index 18a48558..f3cb2b5c 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -85,6 +85,7 @@ spec: docs/spec.md - [ ] #ULK-109 [P2] Research OpenWolf patterns — 3 idées à piocher sans copier (AGPL) : (1) token ledger par session dans `apfel-report.md`, (2) hook PreToolUse dedup file-reads opt-in, (3) `estimated_tokens` par fichier dans output godspeed. Livrable : `docs/analysis/openwolf-patterns.md` + go/no-go par pattern. Ref [#86](https://github.com/izo/Ulk/issues/86) #research #effort-S - [ ] #ULK-110 [P2] Intégrer caveman-compress (MIT) — bundle opt-in `--with-caveman-skill` + hook context-audit (55) qui propose compression CLAUDE.md quand bloat détecté (-46% attendu). Skip caveman-commit/review (doublons plugins officiels). Ref [#88](https://github.com/izo/Ulk/issues/88) #skills #context-audit #effort-M - [ ] #ULK-111 [P3] Ingestion exports Claude Design dans brique/agamotto — Phase 0 brique accepte handoff bundle + HTML standalone en plus de Figma URL ; mode agamotto `--export claude-design` ; protocole `_shared/claude-design-protocol.md` ; skills opt-in `--with-claude-design-skills`. Tester sur export réel avant specs. Ref [#89](https://github.com/izo/Ulk/issues/89) #frontend #design #effort-M +- [ ] #ULK-140 [P1] Résoudre conflit peerDep TS site/ — `@astrojs/check@0.9.8` exige `typescript@^5` mais `site/package.json` a `typescript@^6` (renovate 783d7e4) → `npm install` échoue avec ERESOLVE dans le job CI `test`. 3 options : (a) upgrade `@astrojs/check` vers version compatible TS 6, (b) pin `typescript@^5` dans site/, (c) `--legacy-peer-deps` dans `.github/workflows/test.yml` (quick fix, masque le conflit). Bloque tout PR touchant packages/core. #ci #deps #site #effort-S ## Todo