- Replace readme → doc in EXPECTED_SKILLS (readme skill was replaced by doc)
- Replace readme-updater → doc-syncer in EXPECTED_AGENTS
- Skip external/symlinked skills in disable-model-invocation check —
external skills (frontend-design, emil-design-eng, darwin-skill, find-skills)
and gstack skills (symlinked SKILL.md) are not owned by this repo
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
frontend-design (Anthropic's anti-AI-slop skill) was installed but not
referenced in the plugin-advisor decision table, recommended sets, or
conditional rules — nor in the design-gate detection logic.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Source: anthropic-agent-skills plugin cache → skills-external/frontend-design/
Auto-install via install-plugins.sh step 8b, auto-update via update-all.sh
step 7.1, symlinked by link.sh (refactored to loop over EXTERNAL_SKILLS).
Added to profiles: design, web, web-full, full.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Windows/cross-platform statusline hook for caveman mode indicator.
Reads .caveman-active flag with symlink and size guards to prevent
injection via crafted flag files.
Co-Authored-By: Claude <noreply@anthropic.com>
Major SKILL.md rewrite:
- Fast path: skip extraction when graph exists and user asks a question
- Gemini backend replaces Kimi as default external LLM
- All file I/O uses ensure_ascii=False + encoding="utf-8"
- Monorepo support via per-subfolder extraction + merge
- Obsidian/HTML export via CLI instead of inline Python
- Node ID format includes parent dir to prevent ghost duplicates
- file_type gains "concept" as valid value
- Subagent chunk paths must be absolute
- --help flag prints usage and stops
- Large corpus gate raised from 200 to 500 files
Bumps gstack submodule to 026751e.
Co-Authored-By: Claude <noreply@anthropic.com>
Query-first approach: run graphify query/path/explain for focused
questions, read GRAPH_REPORT.md only for broad architecture review.
Also fixes checkpoint→context-save routing line in CLAUDE.md.
Co-Authored-By: Claude <noreply@anthropic.com>
Session entries from two bugfix sessions:
- BLK-004: orphan /ship-feature wrapper post-refactor (resolved)
- BLK-005: profile checkpoint→context-save rename (resolved)
- BLK-006: profile.sh symlink false-negative via logical cd (resolved)
- LRN-021: sweep ~/.claude/commands/ after orchestrator migrations
- LRN-022: audit profiles against gstack skill list after submodule bump
- LRN-023: cd -P mandatory for scripts invoked via symlink
Co-Authored-By: Claude <noreply@anthropic.com>
Previously unset — Claude Code was defaulting to Opus 4.7 (1M) based on
plan capability + picker history. Pin the default to Opus 4.6 so future
sessions start on 4.6 without going through the /model picker.
1M context tier is plan-routed (Claude Max) so no explicit suffix needed
in the persisted ID — backup `.claude.json` files in this account show
the same bare form (`"model": "claude-opus-4-7"`) while runtime usage
logs as `claude-opus-4-7[1m]`.
Co-Authored-By: Claude <noreply@anthropic.com>
Drop the `PLAN` (Max/Pro) segment — user wants runtime context, not
account-tier info. Add prefixes for clarity:
- `profile: <name>` reads `<repo>/.active-profile` (already wired in
the previous commit).
- `effort: <level>` reads `.effortLevel` from `<repo>/settings.json`
via jq — picks up `/effort` changes automatically since settings.json
is the source-of-truth (symlinked into `~/.claude/settings.json`).
Sample output:
Opus 4.7 | claude (master) | profile: full | effort: xhigh | ███░░ 42% | 3m
`lib/detect-plugins.sh` is left untouched — still used by
hooks/session-start.sh, doctor.sh, update-all.sh, install-plugins.sh.
Co-Authored-By: Claude <noreply@anthropic.com>
`bash lib/profile.sh current` is 12s+ — far too slow to call from the
statusline hook (runs on every keystroke). Add a one-line cache file at
`<repo>/.active-profile`, written by `cmd_apply` and `cmd_reset`. The
statusline reads the file directly with a single `head -n1`, no
sub-shell into `profile.sh`.
Behavior:
- `bash lib/profile.sh set <name>` (which ends in `cmd_apply`) and
`bash lib/profile.sh apply <name>` both write `<name>` to
`<repo>/.active-profile`.
- `bash lib/profile.sh reset` writes the literal `none`.
- Statusline inserts the cached profile name between the plan segment
and the context-bar segment, e.g.
`Opus 4.7 | claude (master) | Max | full | ████░░░░░░ 42% | 3m`.
- Missing or empty cache → statusline shows `?`.
Cache file is gitignored — it tracks runtime state, not source.
Co-Authored-By: Claude <noreply@anthropic.com>
`lib/profile.sh:43` set `REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"`.
Default `cd` preserves symlinks (logical pathname), so when the script is
invoked via the `~/.claude/lib/profile.sh` symlink, `$REPO` resolves to
`/home/bchanot-ubuntu/.claude` instead of the real repo path. `$SKILLS_DIR`
still works because `~/.claude/skills` is itself a symlink to the repo's
`skills/`. But `$DISABLED_DIR` ends up at `~/.claude/skills-disabled` (a real
sibling directory containing only stale npx-skill symlinks) while the actual
disabled gstack skills sit at `<repo>/skills-disabled`.
Symptom: `bash "$HOME/.claude/lib/profile.sh" current` returns
`none (all gstack skills enabled — no profile set)` even when a profile is
applied — because `find $DISABLED_DIR -name 'gstack__*'` returns 0.
Adding `-P` to `cd` forces physical-path resolution so `$REPO` always points
to the real repo regardless of how the script was invoked. `cmd_current`
now correctly reports `full (100% match, 14 gstack skills disabled)`.
Co-Authored-By: Claude <noreply@anthropic.com>
gstack upstream renamed the `checkpoint` skill to `context-save`
(it was shadowed by Claude Code's native /checkpoint rewind alias).
`/profile set full|dev|backend|web|web-full` was emitting
`⚠ missing: checkpoint — try: bash link.sh`, but link.sh only
materializes symlinks for skills that exist upstream — it cannot
resurrect a renamed skill, so the suggested next step was a dead
end.
Replace `checkpoint` → `context-save` in all 5 affected profiles
so the warning goes away and the new skill is enabled when the
profile is applied.
CLAUDE.md routing rule (line 193) also updated locally but left
uncommitted because the file carries an unrelated in-progress
graphify section rewrite.
Co-Authored-By: Claude <noreply@anthropic.com>
BDR-017: `full` profile = web-full + plan + dev superset for end-to-end
MVP via /init-project. Alternatives rejected: extend web-full (different
semantic), profile-of-profiles (not supported), keep 3 apply-chained.
LRN-020: sentinel/identifier collision pattern — `cmd_current`'s "full
(no profile set)" literal collided with new profile name. Renamed to
"none". Rule: sentinels must be outside the entity namespace.
Co-Authored-By: Claude <noreply@anthropic.com>
Superset of web-full + dev + audit + plan tools — covers brainstorm →
design → architecture review → scaffold → implement → ship → audit
pipeline needed by /init-project to produce a real MVP in one session.
Also renames cmd_current "no-profile" sentinel from "full" to "none"
to avoid collision with the new profile name.
Co-Authored-By: Claude <noreply@anthropic.com>
BDR-016: doc-syncer makes README AUTO+unconditional (no skip at
validation gate, only yes/edit) and DEPLOY.md prod-only with a
14-section VPS-deploy template. Mixed dev/prod DEPLOY.md flagged as
drift; dev quick-start lives only in README.
LRN-019: deployable-project doc split by audience — README = dev +
features, DEPLOY = ops + SRE. 14-section template mirrors real
VPS-deploy shape (topology, env, provisioning, two-layer firewall,
Docker tuning, persistence, backups, TLS, observability, hardening,
rollback, runbook). Drop sections that don't apply.
journal: 2026-05-15 heading covering the /commit-change run.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Toggle ui-ux-pro-max@ui-ux-pro-max-skill false → true so design-review,
design-consultation, and feat/hotfix design gate can route through it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
README.md creation becomes AUTO and unconditional — strikes through any
"no README" opt-out in CLAUDE.md. Enriched template: Stack, Quick start
(dev), Verifying a change, Build & deploy sections, all rendered from
real project data (manifest, .env.example, scripts).
DEPLOY.md becomes prod-only, expanded into a 14-section VPS-deploy
structure (topology, env, provisioning, two-layer firewall, Docker
tuning, first-time setup, routine deploys, persistence, backups, TLS,
observability, hardening, rollback, runbook). Dev quick-start lives in
README only — mixed dev/prod DEPLOY.md is flagged as drift.
AUTO MODE: missing README surfaced as SIGNIFICANT in STEP A4 with
rendered draft for one-shot end-of-session approval. Validation gate
(STEP 8) now distinguishes AUTO patches / HUMAN items / CREATE items,
and README CREATE has no "no" — only yes/edit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Avg score 58.0 → 78.2 across status, refactor, plugin-check,
skills-perso, commit-change. See .claude/audits/DARWIN-SKILL-2026-05-12.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Skills covered: close, graphify, harden, profile, prune-memory.
Used by /darwin-skill dim 8 effect testing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First end-to-end run of /prune-memory on real .claude/memory/ surfaced
a broken verify script:
Old: `prefix=$(basename "$f" .md | tr a-z A-Z | cut -c1-3)` derived
the prefix from the filename's first 3 letters → produced DEC / LEA /
BLO. Actual prefixes are BDR / LRN / BLK. The grep then matched zero
entries, no MISSING/ORPHAN was ever reported, and the script printed
its "OK if blank" footer regardless of real state. False clean signal.
Fixed: hard-mapped filename → prefix via `declare -A PREFIX_MAP`.
Verified against current registries — 14 BDR + 16 LRN + 2 BLK + 1 EVAL
entries all index-consistent, no false negatives.
Added EVAL prefix to the map (evals.md was missing from the loop in
v1). Footer line clarified to `(blank above = OK)`. `wc -l` excludes
`.original.md` backups from the output.
Note: caveat in skill body said "v1 ships without baseline TDD test —
STEP 2 approval gate is the safety net". First real test caught a
verify bug that bypassed STEP 2 entirely. Lesson: STEP 4 is its own
safety net and needs its own test.
Co-Authored-By: Claude <noreply@anthropic.com>
/prune-memory first run flagged body↔Index drift on BDR-011:
- Index row (since 2026-05-11): `superseded by BDR-013`
- Body line 201 (since 2026-05-07): `Status: accepted`
BDR-013 explicitly supersedes BDR-011's 4-chapter doc structure with
6-chapter restructure (scores+NAP promoted). Body now consistent with
Index.
Co-Authored-By: Claude <noreply@anthropic.com>
Two issues fixed across personal skills:
1. Five skills had frontmatter > 1024 chars (spec limit per agentskills.io):
- client-handover: 1920 → 924
- doc: 1390 → 734
- seo: 1378 → 885
- geo: 1189 → 734
- validate: 1050 → 742
All now compliant.
2. Three orchestrators had workflow-summary descriptions that create
"shortcut" risk per writing-skills CSO (Claude may follow the
description instead of reading the full skill body, skipping steps):
- ship-feature: "design → plan → implement (TDD) → review → finish"
→ "Use when shipping a feature end-to-end — needs… (9-step pipeline)"
- init-project: "interview → design → scaffold → implement (TDD)"
→ "Use when initializing a brand-new project from scratch — needs…"
- onboard: "detect archetype, install claude-config, run full audit…"
→ "Use when bringing an existing repo into the framework — needs…"
Descriptions now follow "Use when [triggers]…" pattern. Workflow detail
preserved in skill body where it belongs. Triggers consolidated and
trimmed of duplicates.
Co-Authored-By: Claude <noreply@anthropic.com>
Old rule `li input[type="checkbox"] + *` absolutely-positioned the first
element sibling after the checkbox (typically <a>, <code>, <strong>),
yanking links and code spans out of flow and overlapping adjacent
content in the rendered PDF.
Replace with a targeted rule that styles the native disabled checkbox
inline (small green box) and leaves siblings untouched. Pandoc GFM emits
`<li><input disabled type="checkbox"> text…</li>` with no wrapper class,
so we target `li > input[type="checkbox"]` directly.
Co-Authored-By: Claude <noreply@anthropic.com>
NAP table now includes a "Description courte" / "Short description" field
(1-2 sentences, lifted from hero/meta description, pasted identically
across Google Business, Bing Places, Apple Maps, directories). Same field
client was already typing 10 different ways across platforms — now it's
the single source of truth.
BrightLocal Free Tools page was retired in 2026 (service now paid-only).
Replaced with Moz Local Citation Checker (free 60s audit across 50+
directories, no credit card). Both FR and EN versions updated.
Co-Authored-By: Claude <noreply@anthropic.com>
Restructure deliverable from 4 to 6 chapters:
- §2 (new): score table promoted from technical annex to top of doc for
immediate visual proof of impact (tested with local-business clients —
converts "what did I pay for?" doubt within 30 seconds).
- §4 (new): NAP table promoted from §7 annex so client reads identity
values (name, address, phone, hours, categories, short description)
BEFORE attacking §5 todo list. Prevents 10-different-description drift
across external platforms that degrades Google's NAP-consistency signal.
- §5 (todo) and §6 (tech details) renumbered; §7/§8 annexes still optional.
Pandoc bumped to gfm+gfm_auto_identifiers so internal anchor links like
[§4](nap) resolve in the rendered HTML/PDF.
Co-Authored-By: Claude <noreply@anthropic.com>
Two distinct render bugs producing overlapping text on multi-page PDFs:
1. Bare-URL duplication. The print stylesheet injects `(href)` after every
external link via `a[href^="http"]::after`. When pandoc/marked
auto-links a bare URL or renders `[X](X)`, the visible text already
equals the href, so the pseudo-element produces "URL (URL)" and the
trailing duplicate wraps onto the next line, colliding with the
following block (e.g. "https://pagespeed.web.dev/ (https://...)" then
"• Ouvrir, taper l'URL...").
Fix: post-process the body HTML in handover-to-pdf.sh; tag every
`<a href="X">X</a>` (text == href, ignoring trailing slash + case)
with `class="bare-url"`, and exclude `a.bare-url::after` from the
URL-injection rule. Named links still get `(URL)` for print legibility.
Belt-and-braces: add `white-space: nowrap` and `break-inside: avoid`
on the remaining `::after` so future long URLs cannot wrap across
page boundaries either.
2. List item splitting across page boundary. `li` had only
`orphans/widows: 3` and no `break-inside`, so a long item could put
its bullet on page N and its text on page N+1, overlapping unrelated
content. Heading-to-first-block adjacency was also unprotected, so
"heading at bottom of page A / intro paragraph or first bullet at top
of page B" could produce visual overlap during reflow.
Fix: add `li { page-break-inside: avoid; break-inside: avoid; }` and
`h{1..4} + p|ul|ol { break-before: avoid; }` so list items stay
intact and intros stay glued to their heading.
Verified end-to-end: rendered sample md with bare URL + named link +
heading-followed-by-list straddling a page break; pdftotext shows each
URL once, no orphaned bullets, no `::after` warning from weasyprint.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three bugs surfaced on the LIVRAISON.pdf test render:
1. **MD→HTML conversion** — host had no pandoc, no python-markdown, fell
back to `npx marked < "$src"`. marked CLI 16.x ignores stdin and
dumps its own cli.js source. Resulting PDF body = marked's binary
source (`#!/usr/bin/env node`, `Marked CLI`, copyright). Fix:
`npx --yes marked --gfm -i "$src"` (file path via -i, not stdin).
2. **Cover background** — original cream `#F5F0EB` + 8mm green stripe
was washed out. Iterated to white-pure bg with subtle radial
sage/forest tints, black-deep title, green-forest accents
(eyebrow, meta labels, footer, border). Solid green-dark tried
first then rejected (too heavy for long client-facing doc).
3. **Default logo** — SVG `logo-horizontal.svg` rendered cream-toned,
blended into bg. Switched LOGO_URL default to
`https://zenquality.fr/assets/logo-horizontal-1024.png`.
Also added test-artifact gitignore rules for LIVRAISON.* / HANDOVER.*
project-local renders.
Verified: regenerated LIVRAISON.pdf → 164 KB, 19 pages, full content
rendered, white cover with black title + green-forest accents +
visible PNG logo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
End-to-end pipeline that hardens the project, commits, pauses for
deploy, validates the live site, then generates a non-technical client
deliverable (LIVRAISON.md / HANDOVER.md):
1. /seo (SEO+GEO) and /harden run in parallel with auto-fix loops
until each scores >=17/20.
2. /commit-change + push if changes were made.
3. Pause to tell the user what to deploy and wait for confirmation.
4. /validate against the live site.
5. Per-audit gate >=17/20 — stop and analyze if any below.
6. Write client doc with before/after score table + owner-maintenance
checklist.
Reads git history + .claude/memory/ registries for context. For
local-business projects, appends a manual NAP-consistency platform
checklist (Google Business, Pages Jaunes, Yelp, Facebook, Instagram,
TikTok, Apple Maps, Bing Places, TripAdvisor). Optional build/deploy
chapter on prompt.
Adds skills/client-handover/SKILL.md (slash-command entrypoint),
skills/client-handover/checklists/seo-geo-manual.md (NAP checklist),
agents/client-handover-writer.md (orchestrator agent).
Co-Authored-By: Claude <noreply@anthropic.com>
Pattern: toggle scripts for tools with separate install + symlink steps
must check 3 states (disabled-dir, enabled-dir, source-only), not 2.
Source-only branch creates symlink in place rather than failing. Error
messages name the path checked, not just the abstract tool name, so
callers can diagnose install vs symlink state without rereading the
script. Symmetric pairs (enable/disable) must both cover the same
lifecycle states — missing state in one half = silent dead end.
Co-Authored-By: Claude <noreply@anthropic.com>
`enable <tool>` for npx/external skills (darwin-skill, find-skills,
emil-design-eng) only handled two states: symlink in skills-disabled/
(move) and symlink in skills/ (already enabled). Missed the state
right after `make plugin` where the source dir exists at
~/.agents/skills/<tool> but no symlink has been created yet — first
run errored "not installed — run: make plugin" misleadingly.
Add a third branch: when the resolved source dir exists, create the
symlink in place. Resolve source path per tool (skills-external for
emil-design-eng, ~/.agents/skills for darwin-skill/find-skills). Error
message now names the path checked so the caller can verify install
vs symlink state without rereading the script.
Co-Authored-By: Claude <noreply@anthropic.com>
Auto-discover what the project actually has instead of a fixed doc list:
root files (incl. DEPLOY.md, SECURITY.md, ARCHITECTURE.md, ROADMAP.md),
docs/**, and .claude/{tasks,audits,memory}/.
Detect stack (Node/Python/Rust/Go/Ruby/PHP/Dart/.NET) and deploy
complexity (NONE/TRIVIAL/NON_TRIVIAL) to drive doc-needs:
- Propose DEPLOY.md only when non-trivial (Docker, fly.toml, k8s,
multi-stage CI).
- Propose inlining/removing DEPLOY.md when deploy is trivial.
- Enforce README presence with typical GitHub layout.
Add CREATE/REMOVE proposal categories to the validation gate. Update
auto-mode to map deploy artifacts to DEPLOY.md and decisions.md
architectural changes back to CLAUDE.md/README.
Sync skills/doc/SKILL.md description + triggers to match.
Co-Authored-By: Claude <noreply@anthropic.com>
Disable ui-ux-pro-max (off-profile for current work) and enable
pr-review-toolkit so /review and the toolkit subagents are available.
Co-Authored-By: Claude <noreply@anthropic.com>
Matcher was Glob|Grep — those tool inputs have no `command` field, so
the hint never fired. Switch to Bash matcher and gate on the actual
command substring (grep, rg, ripgrep, find, fd, ack, ag) so the
graphify hint only injects when Claude is about to scan raw files.
Co-Authored-By: Claude <noreply@anthropic.com>
Tell Claude to read graphify-out/GRAPH_REPORT.md before answering
architecture questions, prefer graphify query/path/explain over grep
for cross-module questions, and run graphify update . after code edits.
Co-Authored-By: Claude <noreply@anthropic.com>
- GitHub URL clone support (single + multi-repo merge)
- uv tool detection ahead of pipx shebang
- Optional Kimi K2.6 backend via MOONSHOT_API_KEY
- Discrete confidence rubric (0.55/0.65/0.75/0.85/0.95) replaces continuous range
- Aggregated community view for graphs >5000 nodes
- Manifest persistence after --update so next run diffs against current state
- Video file support, rationale-as-attribute (not separate node)
Co-Authored-By: Claude <noreply@anthropic.com>
Append BDR-009 entry + Index update in decisions.md, plus 2026-05-05
heading in journal.md covering the 4-commit batch.
Catches Index up to BDR-008 (was missing 007/008 entries despite
already-written sections).
Co-Authored-By: Claude <noreply@anthropic.com>
/caveman:compress writes a human-readable backup as <file>.original.md
before overwriting. Backups are recoverable via git history (the
pre-compression state lives in the previous commit), so committing
them duplicates content and bloats the repo.
Globbing on *.original.md catches all compressed registries plus
CLAUDE.original.md.
Co-Authored-By: Claude <noreply@anthropic.com>
Add "Format — registries ALWAYS caveman" rule alongside existing
English-only rule. All writes to .claude/memory/*.md (decisions,
learnings, blockers, journal, evals) must drop articles/filler/hedging
while preserving technical terms, IDs, dates, and code blocks exact.
Rationale: registries load every session start — caveman cuts ~40%
input tokens with zero loss of substance. Applies to direct writes and
skill-driven CAPITALIZE steps (close, ship-feature, feat, bugfix,
hotfix, commit-change). Existing entries: compress on demand via
/caveman:compress <file>.
Self-applied: CLAUDE.md prose itself compressed in same pass.
Co-Authored-By: Claude <noreply@anthropic.com>
Toggle example-skills@anthropic-agent-skills off — not used in active
profiles, reduces session-start skill enumeration.
Co-Authored-By: Claude <noreply@anthropic.com>
- BDR-007: Skill profiles partition gstack by usage (v1, skill-only).
Decision to ship lib/profile.sh + symlink-based toggle for skills,
with plugin/MCP entries advisory in v1. Rationale: the existing
toggle-external.sh enable|disable gstack is too coarse — it
disables checkpoint/ship/learn alongside design skills. Profiles
hide the irrelevant skills without uninstalling the gstack repo.
Alternatives rejected: forking SKILL.md to strip the gstack
preamble (re-fork on every upgrade — preamble already degrades
gracefully via `|| true`); per-skill toggle via claude plugin
enable/disable (gstack skills are not marketplace plugins);
removing symlinks (lossy if user has local edits).
- BDR-008: Profile system v2 — extend to plugins + MCPs + CLIs.
Reverses the "advisory only" stance from BDR-007 alternative #4.
User feedback: pure-skill toggling left ui-ux-pro-max/magic always
loaded regardless of profile, so passive token cost didn't drop
enough on profile switch. Solution: real claude plugin enable/
disable for an explicit MANAGED_PLUGINS allowlist (3 entries) +
PROTECTED_PLUGINS denylist for always-on (caveman, security-
guidance, superpowers). MCP magic delegated to toggle-external.sh.
Other MCPs stay advisory because each needs specific config. Adds
4 new profiles: web, seo, web-full, backend.
- Journal: 2026-05-04 entry summarizing the v1 ship, then a follow-up
block for the v2 extension (new profiles, plugin auto-toggle, tie-
breaker for `current`).
- TODO.md: marked done — v1 (Skill profiles) section and v2 (Profile
system v2 — extension plugins/MCPs/CLIs) section, both with their
full subtask lists.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ship lib/profile.sh + 9 profiles in lib/profiles/. A profile is a
plain-text file listing items + types (gstack | personal | external |
plugin@<marketplace> | mcp | cli). `profile set <name>` enables the
listed items and disables the rest:
- gstack/personal/external skills: symlink toggle skills/ ↔
skills-disabled/ (gstack__<name> prefix to avoid collisions; no
prefix for personal/external).
- plugins typed `plugin@<marketplace>`: actually toggled via
`claude plugin enable|disable <name>@<marketplace>`. Allowlist:
MANAGED_PLUGINS = ui-ux-pro-max, plugin-dev, pr-review-toolkit.
Denylist: PROTECTED_PLUGINS = caveman, security-guidance,
superpowers (always-on, never disabled even if absent from a
profile).
- mcp magic: delegated to lib/toggle-external.sh which already
handles the MAGIC_API_KEY env lookup. Other MCPs stay advisory.
- cli (rtk, gsd, ctx7, graphify): status-only, never auto-installed.
Profiles shipped:
web public website work — frontend + content + light dev
seo SEO + GEO + W3C audit (search/AI indexability + a11y)
web-full production website end-to-end (web ∪ seo ∪ qa-only/canary)
backend backend / API / system dev — no design, no SEO
design visual QA, design systems, mockups, polish
dev daily code work — features, fixes, refactor, ship
qa site testing, perf, canary, validation
audit comprehensive audit — security + SEO + perf + health
minimal strip all gstack skills (quiet session)
Commands:
profile list / show <name> / current / apply <name> / set <name> /
reset / diff <a> <b>
`current` heuristic returns "full" when nothing is disabled, otherwise
picks the profile with the highest available-ratio (counts both
"enabled" and "installed" — the latter for CLIs). Tiebreaker: larger
profile total wins, so web-full beats web at a 100% tie.
`reset` re-enables every gstack skill but does NOT touch plugins —
the user re-enables a managed plugin manually or via `apply <profile>`.
This is documented in the trailing info line.
Integration:
- skills/profile/SKILL.md — `/profile` slash command, lists profiles,
documents the per-type mechanism, points at lib/profile.sh.
- agents/plugin-advisor.md — DETECT phase calls `profile current`,
OUTPUT adds a PROFILE line, and TOGGLING EXTERNAL TOOLS gains a
"Skill profiles" section with a signal → profile recommendation
table.
- lib/toggle-external.sh — header pointer to profile.sh for fine-
grained activation (toggle-external still owns whole-gstack and
magic-MCP toggles).
- Makefile — `make profile cmd="set <name>"`, profile-list,
profile-current, profile-reset.
Tested end-to-end: `set web` enables ui-ux-pro-max + magic; `set seo`
disables ui-ux-pro-max; `set minimal` disables ui-ux-pro-max but
spares always-on plugins; `reset` restores all 64 skills; shellcheck
clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- BDR-006: Caveman as 4th always-on plugin (output compression, sym
with rtk's input compression). Full install rationale, alternatives
rejected, caveats around path normalization + gitignore.
- LRN-005: claude plugin install does NOT enable — explicit
claude plugin enable required for ALWAYS-ON plugins. Pattern: read
enabledPlugins, never hardcode plugin names in status displays.
- LRN-006: caveman-shrink (and any MCP middleware proxy) needs an
upstream wrapper. Bare registration fails health checks. Pattern:
register under derived names (proxy-upstream), don't auto-register.
- Journal: 2026-05-03 entry summarizing the session.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two interlocked bugs masking each other:
1. install-plugins.sh installed but never enabled marketplace plugins.
`claude plugin install` only writes to ~/.claude/plugins/cache; without
a separate `claude plugin enable` the plugin sits dormant in the
user's enabledPlugins map. security-guidance and superpowers shipped
as ALWAYS-ON in CLAUDE.md/README/installer banner but in practice
landed disabled on every fresh install.
2. session-start.sh hardcoded the literal "security-guidance rtk
superpowers" in the ✅ ON row, so the misleading banner agreed with
the misleading documentation. The bug stayed invisible.
Fixes:
- install-plugins.sh now calls enable_plugin (added in the caveman
commit) for security-guidance and superpowers immediately after
install. Idempotent: skips if already in enabledPlugins.
- session-start.sh builds the ALWAYS-ON row dynamically from RTK
binary detection + plugin_enabled() lookups against
settings.json. Plugins that are not enabled are omitted, so the
banner reflects reality. Wider strings split across two lines like
the toggle row.
- settings.json: ship security-guidance and superpowers in
enabledPlugins so this user's machine matches the contract until
install-plugins.sh runs again.
Out of scope (separate bug, not addressed here): the marketplace-aware
detect_security_guidance / detect_plugin_dev cache scans miss plugins
nested under cache/<marketplace>/<plugin>/<version>/. They aren't on
the always-on path so the symptom is hidden — left for a follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires JuliusBrussee/caveman into the always-on tier alongside
security-guidance and superpowers. Caveman compresses Claude's output
tokens (~75%) by speaking like a caveman while keeping technical
substance. Three layers:
1. Plugin (caveman@caveman, marketplace JuliusBrussee/caveman)
— adds /caveman, /caveman-commit, /caveman-review, /caveman-stats,
/caveman-help, /cavecrew, /compress + 3 cavecrew agents +
SessionStart/UserPromptSubmit hooks from the plugin path.
2. Standalone hooks (statusline + stats badge) deployed by
caveman's own hooks/install.sh into ~/.claude/hooks/. Paths in
settings.json normalized to ~/.claude/hooks/... so this user's
home dir doesn't leak across machines.
3. caveman-shrink MCP proxy — NOT auto-registered. The bare proxy
fails health checks because it requires an upstream MCP server
to wrap. install-plugins.sh STEP 5.5 prints a snippet showing how
to register a wrapped entry (e.g. caveman-shrink-fs) when the user
decides which upstream to compress.
New helper enable_plugin() for explicit always-on activation —
'claude plugin install' only copies into cache, doesn't write
enabledPlugins. Idempotent via Python json check.
doctor.sh adds detect_caveman / detect_caveman_hooks / detect_caveman_shrink
checks plus a 300t passive-cost adder. update-all.sh refreshes hook
files via the upstream installer's --force mode.
.gitignore covers caveman runtime files materialized into hooks/
because ~/.claude/hooks is symlinked to this repo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doctor.sh exited at the gstack-skills-count step on machines where
~/.claude/skills/gstack does not contain a skills/ subdirectory (e.g.
when the gstack submodule layout puts skills directly at root). Under
set -o pipefail, find's non-zero exit propagated through wc | tr,
killing the script before it reached the prerequisites/plugins/budget
sections.
Wrap the find in a brace group with `|| true` so the pipe stays
zero-exit and downstream sections run.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BDR-005: motion as default animation library; plugin-advisor stays
read-only (orchestrators own install).
LRN-004: framer-motion was rebranded `motion` in Nov 2024 — single
package for React/Svelte/vanilla, separate `motion-v` for Vue. React
Native still needs react-native-reanimated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BDR-004 documents the decision to adopt auto permission mode as default
with classifier safety net, alternatives, and feature-gate caveats.
LRN-003 captures the gotcha that Claude Code's disable* settings use
the literal sentinel string "disable" rather than a boolean — required
context for any future permission-mode change.
Journal entry added for 2026-04-27.
Co-Authored-By: Claude <noreply@anthropic.com>
Switch defaultMode from "default" to "auto" so Claude Code uses the
classifier-driven auto mode instead of prompting on each tool call.
Drop disableAutoMode: "disable" which would otherwise reject the new
defaultMode at startup.
Auto mode requires Claude Code v2.1.83+, a Max/Team/Enterprise/API
plan, a compatible Sonnet 4.6 / Opus 4.6 / Opus 4.7 model, and the
Anthropic API provider. If any prerequisite is missing, Claude Code
reports auto mode as unavailable on session start.
Co-Authored-By: Claude <noreply@anthropic.com>
Move remoteControlAtStartup to the bottom of the file (next to other
top-level user preferences) and add effortLevel: xhigh as the default
reasoning effort.
Co-Authored-By: Claude <noreply@anthropic.com>
Tracking moved to .claude/tasks/TODO.md per project convention.
The 3 listed skills (SEO, code-clean, doc) were already shipped.
Co-Authored-By: Claude <noreply@anthropic.com>
Apply the English-only rule (BDR/CLAUDE.md § Memory registries)
retroactively to the 9 entries written before the rule was in place:
- decisions.md: BDR-001, BDR-002, BDR-003 + index titles
- learnings.md: LRN-001, LRN-002 body prose (LRN-002 was already
half-English from the CAPITALIZE pass; now fully normalized)
- blockers.md: BLK-001, BLK-002 + BLK-002 index row
- journal.md: 2026-04-23 entry rewritten, + one bullet added noting
the retrofit itself
- evals.md: EVAL-001 + index row
Content-preserving translation — same claims, same IDs, same dates,
same file structure. YAML headers and schema sections untouched
(they were already English).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Registries are re-read at every session start; consistency pays back
each time. Adding a single rule in CLAUDE.md § Memory registries
(authoritative) + a short reminder at the end of each CAPITALIZE
block (ship-feature, bugfix, hotfix, feat, commit-change, close).
Rationale: (1) model re-reads the registries more efficiently in a
single language, (2) lower token cost for English (model's primary
training language), (3) easier cross-project reuse. Interactive gates
may still mirror the user's language — only the written entry is
constrained.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First real CAPITALIZE phase (commit-changer Phase 4) — extract reusable
knowledge from the .claude/ restructure batch (commits 892de28..6ec06c8):
- BDR-003: gitignore wildcard + negations pattern (decision with why/alts)
- LRN-002: moving report-file paths requires grepping bash READS,
not just WRITES — rule learned from 2 dispatchers being
silently broken until a verify-gate caught them
- BLK-002: rmdir blocked in sandbox even on empty dirs — resolved via
git rm + rename auto-detect (no rmdir needed in practice)
- journal: 2026-04-23 entry extended with verify-gate outcomes and
commit batch reference
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
One-shot bash migration block for repos onboarded before this layout:
creates .claude/{tasks,memory,audits}, moves tasks/*.md + AUDIT_* +
orphan root audits (SEO/GEO/HARDEN/VALIDATE/BUGS-FOUND) to the new
homes, seeds memory registries from templates, patches .gitignore to
un-ignore shared dirs, and ships a post-migration sanity check.
Uses mv throughout (no rm) so the migration stays reversible via
git checkout . until the commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Before: SEO.md, GEO.md, HARDEN.md, VALIDATE.md, BUGS-FOUND.md landed
at project root. After: all five go to .claude/audits/. Covers both
dispatcher write paths and the dispatcher bash commands that parse
each report (test -s, grep score, wc) — otherwise the dispatcher
would look for the file at the old location.
- skills/seo,geo,harden,validate,code-clean — write paths + console
summaries ("Report: .claude/audits/X.md")
- skills/harden,validate — bash parsing commands (test/grep/wc) aligned
- agents/seo-analyzer,validator-analyzer,code-cleaner — agent-side refs
- agents/validator-analyzer frontmatter description updated
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous rule (.claude/) ignored everything under .claude/, making
the new governance files invisible to git. Switches to a wildcard
pattern with explicit negations: tasks/memory/audits/settings.json
become trackable; settings.local.json and agent-memory/ stay
per-machine. Commits existing .claude/settings.json which now falls
under the tracked scope.
Verified with git check-ignore:
- .claude/memory/decisions.md → exit 1 (not ignored) ✓
- .claude/tasks/TODO.md → exit 1 (not ignored) ✓
- .claude/settings.local.json → exit 0 (ignored) ✓
- .claude/agent-memory/ → exit 0 (ignored) ✓
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Table in Pattern C (onboard) referenced tasks/ in steps 2, 7, 9 and
the post-onboard cat command. Aligns with the new governance layout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Manual fallback for the 3-question ritual (what was decided / learned
/ blocked) when none of the completion skills ran. Pre-fills BDR/LRN/
BLK candidates from git log + conversation context, presents for
validation, appends approved entries to .claude/memory/ registries
plus a timeline line in journal.md. Always writes the journal line
even if all 3 questions are skipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Registries only get filled if something actively writes to them.
Without integration, the 3-question ritual is aspirational text.
Adds a CAPITALIZE step at the end of every completion skill so work
milestones automatically propose BDR/LRN/BLK entries from context.
- ship-feature STEP 9 — decision/learning/blocker candidates per feature
- bugfix STEP 7 — always propose BLK with root cause; LRN if pattern reusable
- hotfix STEP 5 — default skip; only prompt when non-obvious lesson surfaces
- feat STEP 6 — propose BDR for design choice, LRN for pattern
- commit-change Phase 4 — analyze the commit batch, propose grouped entries
Every variant also appends a one-liner to .claude/memory/journal.md under
today's date heading.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>