From cd9a397140b4c1d148eb18c759e397a551259a51 Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Sun, 5 Jul 2026 15:31:57 +0200 Subject: [PATCH 1/3] =?UTF-8?q?chore(config):=20inputNeededNotifEnabled=3D?= =?UTF-8?q?true=20=E2=80=94=20adopt=20harness=20notification=20toggle,=20c?= =?UTF-8?q?ommitted=20layout=20unchanged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/settings.json b/settings.json index 3e9e71d..717a431 100644 --- a/settings.json +++ b/settings.json @@ -315,5 +315,6 @@ }, "effortLevel": "xhigh", "remoteControlAtStartup": true, - "skipAutoPermissionPrompt": true + "skipAutoPermissionPrompt": true, + "inputNeededNotifEnabled": true } From 7d566da77649749f942fbe33a40e50d1a640973f Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Sun, 5 Jul 2026 15:32:16 +0200 Subject: [PATCH 2/3] =?UTF-8?q?chore(memory):=20EVAL-016=20/deploy=20first?= =?UTF-8?q?=20real=20run=20+=20journal=20=E2=80=94=20tour=E2=86=92prod=20c?= =?UTF-8?q?losed,=20skill=20UX=20patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/memory/evals.md | 8 ++++++++ .claude/memory/journal.md | 1 + 2 files changed, 9 insertions(+) diff --git a/.claude/memory/evals.md b/.claude/memory/evals.md index 4eb7e26..22ea9ff 100644 --- a/.claude/memory/evals.md +++ b/.claude/memory/evals.md @@ -152,3 +152,11 @@ rules: - **method**: main session verified ON DISK, not from agent summary: TODO zero-diff vs develop ✓, no target `.claude/memory/` created ✓, per-iteration semgrep report files present ✓, TOUR.md committed ✓, zero scope creep (no .gitignore) ✓, main/develop untouched + branch unmerged ✓, 3-iteration bound held ✓. - **anomalies**: (1) scratch semgrep files untracked → tree dirty at end, would self-block next run — patched STEP 3.2 [[LRN-100]]; (2) SEC-2 API-BREAKING fix (new required header) unflagged — patched template BREAKING tag; (3) positive: it2 re-verify caught regression of agent's OWN fix (`compare_digest(str)` raises on non-ASCII → 500 not 403), fixed + functionally proven it3 — re-verify loop has real teeth. - **action**: keep (skill shipped). REFACTOR additions not re-run through 3rd full pass — re-test at first real use ([[LRN-100]]). + +## EVAL-016 — /deploy first REAL run (bchanot-cv): bootstrap→instantiate→hand-back→mark, full cycle OK + +- **Date**: 2026-07-05 +- **output**: bootstrap Path B (4-field interview → @delta-annotated PROCEDURE.md + seeded INCIDENTS, commit `5fe8b41` via deploy-commit.sh rc=0) → first deploy: base null → delta = full tree (26 files), `@delta:rebuild when=` matched → NEXT.sh 3 steps → GATE all → PENDING.json bridge → hand-back → user "Deployed OK" → MARK: STATE.json (`deployed_sha` = bridge target, NOT HEAD), local tag `deploy/2026-07-05`, oracle commit `395c77b`, bridge consumed, tree clean. +- **method**: real prod deploy (VPS). Independent live proof post-mark: curl bchanot.fr → 200 + nosniff + X-Frame-Options + CSP + HSTS + versionless server — tour SEC-2 fixed end-to-end, tour→prod loop closed. +- **anomalies**: (1) NOT exercised: cold cross-session resume + STEP 4 learn (0 incidents) — natural test at next deploy/failure. (2) UX gap, user feedback: compound `ssh host "cd … && …"` one-liners ≠ wanted session style (one command per line), and the checklist lived only on disk — skill patched same day (step=block grammar, shape rule, hand-back prints NEXT.sh inline; template + bchanot-cv runbook restyled). Re-dogfood at next deploy. +- **action**: keep. Two-moment contract works in-session; disk artifacts coherent throughout. diff --git a/.claude/memory/journal.md b/.claude/memory/journal.md index 97c41aa..7f13e56 100644 --- a/.claude/memory/journal.md +++ b/.claude/memory/journal.md @@ -329,3 +329,4 @@ rules: ## 2026-07-05 - Built /tour skill (grouped sweep clean+security+reconcile+doc, auto, 1..N projects, convergence loop bounded 3×) via writing-skills TDD + skill-creator guidance: RED 6 gaps → GREEN 6/6 closed disk-verified → REFACTOR 2 holes (scratch self-block, BREAKING tag). [[BDR-052]] [[LRN-099]] [[LRN-100]] [[EVAL-014]]. Merged feature/tour-skill → develop + release/1.0.0 on user GO. settings.json /model side-effect reverted (Opus 4.8 1M default restored, attribution backstop kept). +- /deploy first real run (bchanot-cv): bootstrap→mark full cycle, live-proven (full security-header stack live — tour→prod closed, tag deploy/2026-07-05). Skill patched post-run on user UX feedback: session-style NEXT.sh (one command per line) + hand-back prints the checklist inline ([[EVAL-016]]); template + generated runbook restyled. impeccable chain + Node 24 baseline shipped develop+RC, pushed. settings.json: +inputNeededNotifEnabled committed (layout unchanged). From 31443baa1b1a7f8c8457de288fe8dc3e3d78fbce Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Sun, 5 Jul 2026 15:33:38 +0200 Subject: [PATCH 3/3] feat(skills): /deploy NEXT.sh session style + inline hand-back print First-real-run UX feedback (EVAL-016): one command per line as typed in an interactive session (ssh opens the box, following lines run on it, local steps flagged), never folded ssh compounds; the hand-back prints the full checklist in the conversation (and every re-hand-back reprints it). Step defined as a block (header + command lines to next blank line), @delta governs the block. Template restyled to match. --- .claude/tasks/TODO.md | 14 ++++++++++++++ CHANGELOG.md | 4 ++++ skills/deploy/SKILL.md | 20 ++++++++++++++++++-- templates/deploy/PROCEDURE.md | 31 ++++++++++++++++++++----------- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/.claude/tasks/TODO.md b/.claude/tasks/TODO.md index 9e1fcdd..971cffa 100644 --- a/.claude/tasks/TODO.md +++ b/.claude/tasks/TODO.md @@ -1,5 +1,19 @@ # TODO +## 2026-07-05 — /deploy UX patch (feature/deploy-next-style) +Feedback user au 1er run réel (bchanot-cv, [[EVAL-016]]) : NEXT.sh une commande +par ligne (style session — ssh ouvre la box, la suite s'exécute dessus, local = +"(from your machine)") + hand-back AFFICHE la checklist inline (aussi aux +re-hand-back). Step = bloc (header + lignes jusqu'à ligne vide), @delta +gouverne le bloc entier. +- [x] skills/deploy/SKILL.md — grammaire bloc-étape + shape rule + print inline +- [x] templates/deploy/PROCEDURE.md — restylé session +- [x] bchanot-cv runbook restylé, committé, pushé (bd7f6e4, develop sync) +- [x] settings.json +inputNeededNotifEnabled (layout committé inchangé) +- [x] Capitalize EVAL-016 + journal +- [ ] Re-dogfood au prochain /deploy réel (edit de skill non re-testé par run — + dette Iron Law assumée, même statut que la note d'authoring du skill) + ## 2026-07-05 — impeccable install chain (feature/impeccable-install) Décision (user a délégué) : COMPLÉMENTAIRES → les deux. frontend-design garde la direction esthétique au build ; impeccable (pbakaus, 43.6k⭐, Apache-2.0, diff --git a/CHANGELOG.md b/CHANGELOG.md index 26693e5..e59f23a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). ## [Unreleased] +### Changed +- `/deploy` NEXT.sh reshaped on first-real-run feedback: runbook steps are **one command per line, interactive-session style** (an early step opens the ssh session; later lines run on the box; local steps say "from your machine") instead of folded `ssh host "cd … && …"` one-liners, and the **hand-back prints the full checklist inline** in the conversation (also on every re-hand-back) so the user never has to open `NEXT.sh` to know what to run. Step = comment header + command lines up to the next blank line; a `@delta:` directive governs the whole block. Template `templates/deploy/PROCEDURE.md` restyled to match. +- `settings.json`: `inputNeededNotifEnabled: true` adopted (harness notification toggle); committed layout otherwise unchanged. + ### Added - **impeccable** (pbakaus, Apache-2.0) wired into the toolchain as the design counterpart of semgrep: the `/impeccable` skill (23 verbs under one command: audit, polish, bolder, quieter…) plus the 45-rule deterministic anti-pattern detector (`npx impeccable detect`, exit 0/2, `--json`). Complementary to `frontend-design` (kept — aesthetic direction at build time); impeccable adds the deterministic audit floor and per-project design context (`/impeccable init`). CLI pinned in `plugins.lock.json` (3.2.0 — a silent rules update would change audit output on unchanged code); dist is machine-owned under `skills-external/impeccable/` (gitignored, ctx7 pattern), staged-installed by `install-plugins.sh` Step 8d, refreshed pin-honored by `update-all.sh`, symlinked by `link.sh`, listed in the design/web/web-full/full profiles and the design-work routing. Requires Node ≥ 24: the install baseline is bumped from 22 to 24 LTS (NodeSource `setup_24.x` / brew `node@24`), so `make plugin` upgrades a too-old host in place; the impeccable steps still skip gracefully if Node stays below 24. Not in the design gate's GATE-BLOCK list yet — promotion deliberate, after first dogfood. - `/tour` skill — grouped all-axes sweep over one or several projects: security (pinned-semgrep `security-auditor` agent + `/cso` posture when gstack is ON) → cleanup → re-verify → reconcile (report-only, never edits the target TODO/registries) → doc sync, looping until a full pass applies zero fixes (bounded at 3 iterations). Fixes land on a `chore/tour-` branch the skill never merges; each project gets an append-only `.claude/audits/TOUR.md` report with BREAKING tags on contract-changing security fixes. Built TDD (superpowers:writing-skills): baseline run showed silent TODO rewrites, autonomous registry writes, grep-as-security-pass, no persistent report, scope creep and an unbounded loop — each countered and verified on a seeded fixture. diff --git a/skills/deploy/SKILL.md b/skills/deploy/SKILL.md index 9e0d73b..fa67432 100644 --- a/skills/deploy/SKILL.md +++ b/skills/deploy/SKILL.md @@ -99,6 +99,14 @@ A directive sits on the comment line **above** the step it governs; patterns are matched against the delta file list. Un-annotated step = **fixed**, always emitted verbatim. +**A step is a block**: its `# n)` comment header plus every command line below +it, up to the next blank line. A directive governs the whole block. Steps are +written **one command per line, interactive-session style** — an early fixed +step opens the box (`ssh "$DEPLOY_HOST"`), the lines after it run *on* the box +as you would type them; a step that runs locally says `(from your machine)` in +its header. Never fold `ssh host "cd … && …"` compounds: the user copy-pastes +line by line. Each `# VERIFY:` sits at the end of the command line it gates. + | Directive | Meaning | Instantiation | |-----------|---------|---------------| | `# @delta: glob=:each` | per-file command | repeat the command once **per** matching delta file (file substituted in) | @@ -275,7 +283,9 @@ Set the base, compute the changed-file list, capture the target. prepend `# PRE-WARN: DEP-NNN ` above it. 3. Keep every `# VERIFY:` gate. Header the file: *"Run by hand, step by step. Never `bash NEXT.sh` unattended."* -4. Write `.claude/deploy/NEXT.sh`. +4. Preserve the runbook's shape: one command per line, session style (see the + `@delta:` grammar section) — instantiation never re-folds lines. +5. Write `.claude/deploy/NEXT.sh`. **[GATE] — present `NEXT.sh` → `all / edit / skip-all`.** - `all` → proceed. `edit` → revise the listed steps, re-present. @@ -288,9 +298,15 @@ Set the base, compute the changed-file list, capture the target. "started_at": "", "runbook_rev": "" } ``` -**Then HAND BACK** (AskUserQuestion): *"Run NEXT.sh step by step against prod. +**Then HAND BACK — the checklist lands in the conversation, not just on disk.** +Print the FULL final `NEXT.sh` content inline (fenced code block) so the user +sees exactly what to run without opening the file — the gate preview is not +enough (an `edit` round may have changed it; the hand-back shows the final +text). Then (AskUserQuestion): *"Run NEXT.sh step by step against prod. Report back: **Deployed OK** / **Failed at step X: ** / **Not yet**."* Then **stop** — control is the user's; `PENDING.json` on disk now marks the wait. +The same rule applies to every re-hand-back (STEP 4.3): regenerated `NEXT.sh` +⇒ reprinted in full. ## STEP 3 — RESUME / REACT diff --git a/templates/deploy/PROCEDURE.md b/templates/deploy/PROCEDURE.md index 71a83c8..61cc09d 100644 --- a/templates/deploy/PROCEDURE.md +++ b/templates/deploy/PROCEDURE.md @@ -4,22 +4,31 @@ # @config push_deploy_tags=false # NOTE grammar: glob=:each repeats the command per matching file (e.g. psql -f ); # glob=:list runs once + lists matching files as VERIFY items; when= is conditional. +# Style: one command per line, as typed in an interactive session — step 1 opens +# the ssh session, later steps run ON the box; local steps say "(from your machine)". -# 1) backup BEFORE any forward-only migration -ssh "$DEPLOY_HOST" 'pg_dump "$DB" > ~/backups/pre-deploy-$(date +%F-%H%M).sql' # VERIFY: dump size > 0 +# 1) connect + pull the desired branch (fixed) +ssh "$DEPLOY_HOST" +cd "$APP_DIR" +git pull # VERIFY: HEAD == target sha + +# 2) backup BEFORE any forward-only migration +pg_dump "$DB" > ~/backups/pre-deploy-$(date +%F-%H%M).sql # VERIFY: dump size > 0 # @delta:migrations glob=supabase/migrations/*.sql:list -# 2) apply NEW migrations (one command; skill lists the delta migrations to VERIFY) -ssh "$DEPLOY_HOST" 'supabase migration up' # VERIFY: "Applied" for each +# 3) apply NEW migrations (one command; the skill lists the delta migrations to VERIFY) +supabase migration up # VERIFY: "Applied" for each # @delta:rebuild when=docker-compose*.yml,Dockerfile,Dockerfile.* -# 3) rebuild + restart services (only if build inputs changed) -ssh "$DEPLOY_HOST" 'docker compose up -d --build' # VERIFY: docker compose ps healthy +# 4) rebuild + restart services (only if build inputs changed) +docker compose up -d --build # VERIFY: docker compose ps healthy # @delta:deps when=package.json,*lock*,requirements.txt,pyproject.toml -# 4) install deps (only if manifests changed) -ssh "$DEPLOY_HOST" 'cd app && npm ci' # VERIFY: exit 0 +# 5) install deps (only if manifests changed) +cd app +npm ci # VERIFY: exit 0 -# 5) reload cache + smoke test (fixed) -ssh "$DEPLOY_HOST" 'systemctl reload app' -curl -fsS https://$DEPLOY_HOST/health # VERIFY: HTTP 200 +# 6) reload + smoke test +systemctl reload app +# (from your machine) +curl -fsS https://$DEPLOY_HOST/health # VERIFY: HTTP 200