Commit Graph
64 Commits
Author SHA1 Message Date
bastien 3dad33e475 fix(settings): deny the npm global-install aliases
The deny list matched `npm install -g` only; `npm i -g` and the
`--global` spellings went through.
2026-09-30 14:26:56 +02:00
bastien 45ae0d1217 feat(effort): session default high, env-var warning, live effort in statusline 2026-09-28 18:52:36 +02:00
bastien ddea411491 chore(config): superpowers citers by bare name, routing map, docs, settings
Every superpowers-prefixed skill call in ship-feature, init-project, tour,
deploy, audit-delta, plugin-advisor and lib/analyze-before-plan now names
the vendored skill directly. finishing-a-development-branch is described
as the upstream skill this config does not vendor (gitflow finish is the
integration path). CLAUDE.global.md Skill routing maps the four
non-vendored skills the vendored text still references. settings.json
loses the plugin key and its marketplace block; README, USAGE,
plugin-advisor and the profile skill describe superpowers as vendored
skills, always on, zero plugin cost. CHANGELOG entry with a known
residual.
2026-09-28 14:54:53 +02:00
bastien 4c86d6dc70 chore(config): security-guidance Stop review off, plugins off, routing and docs
settings.json: ENABLE_STOP_REVIEW=0 (the plugin's own switch: no more
Opus call on every turn that changes code, 0 findings in 6 days, 1
recorded false positive; the regex layer and the commit/push agentic
review stay on), brightdata-plugin@synced false (keyless-useless, its MCP
skill would hijack WebFetch/WebSearch), frontend-design official plugin
entry gone (uninstalled: byte-identical to the managed copy).

CLAUDE.global.md routes Ship/PR to ship-feature (gstack ship takes
origin/HEAD = main as base), drops ship/context-save from the gstack-off
list and 21st-ui-review from the design review line (trio is max-only).
deploy's table no longer points at land-and-deploy/setup-deploy.
plugin-advisor.md describes security-guidance's real mechanics. CHANGELOG
Unreleased entry with a Known residual section.
2026-09-28 11:49:01 +02:00
bastien 27f201d4aa feat(guardrails): refusal ends the attempt; doctrine-citers census; make test suite=
Root causes of the 2026-09-24 errors turned into mechanisms (BDR-100). hard_deny 'Routing around a guardrail': a refused command is never rerun through a wrapper, alias, heredoc, Makefile target, env file, other shell or other agent; the same clause in 14 agents and in the doctrine's sub-agent rule. make test suite=<file> runs one suite hermetically so the denied env-prefix form is never needed by hand. lib/tests/doctrine-citers.test.sh: every CLAUDE.md "Section" / § Label citation across skills, agents, lib, rules and hooks must resolve to a heading or bold label (flip-tested); its first run fixed rest-api-node.md. Doctrine 'After code changes' step 4: a changed rule, heading, label or threshold → grep every citer in the same commit.
2026-09-24 20:58:25 +02:00
bastien 128e40616b chore(config): feedbackDrafts off; ignore the app-managed skills/synced mirror
settings.json: the user's hand-edit (feedbackDrafts: off) committed as is. .gitignore: skills/synced/ and its .bucket-* marker are Claude Code's mirror of the claude.ai synced skills (UUID bucket, manifest.json, Anthropic stock skills incl. 117 ISO xsd schemas), rewritten at each sync — same treatment as the graphify and impeccable machine-owned copies (BDR-028, LRN-154).
2026-09-24 13:36:02 +02:00
bastien 68c9df354b feat(gitflow): remove the origin copy of a branch once its merge is verified
`gitflow_delete` now ends with `_gitflow_delete_remote`: after the local
copy is gone, the remote tip is read with `ls-remote --exit-code`, checked
against develop/main with the same ancestor test, and only then removed
with `push origin --delete`. Same contract as the pushes (BDR-095): best
effort, warn never fail. No origin, `GITFLOW_NO_PUSH=1` or
`gitflow.autopush false` skip it; an unreachable origin or a remote tip
holding commits the bases lack keeps the remote branch, loudly. A base is
never targeted, by construction and by an explicit guard.

The static deny on hand `git push --delete` stays: it matches the Bash
tool's command string, the lib is the sanctioned path. Prose (hard_deny,
environment), doctrine, gitflow SKILL (table, op, warning row),
SETTINGS.md and CHANGELOG updated. T24: 9 checks (finish removes the
copy, bases untouched, unmerged remote tip kept, never pushed silent,
unreachable origin loud, autopush opt-out). 161/163, the 2 failures are
the pre-existing T16a (gitleaks absent on this host).
2026-09-24 11:50:16 +02:00
bastien 32d8f981df feat(gitflow): delete a branch only after a verified merge, main/develop undeletable
Since BDR-095 `start` sets an auto-pushed upstream, so `git branch -d`
checked "merged into origin/<branch>" (always true, the post-commit hook
keeps it in sync) instead of "merged into develop". T22a proves it: an
unmerged feature with its upstream in sync is deleted by `-d` alone.

- `gitflow_delete` is the single delete path (finish + CLI `delete`):
  refuses main/develop (rc 6) and any branch that is not an ancestor of
  develop or main (rc 5, `gitflow_merged_into_base`, fail closed when
  neither base exists), then `-d` as a second layer. CLI `merged`, `hooks`.
- Fourth generated hook `reference-transaction`: in the `prepared` call,
  a deletion of refs/heads/main or refs/heads/develop exits 1, whatever
  issued it (branch -d/-D, update-ref -d, rename, script, sub-agent).
  `git config gitflow.protect false` opts a foreign clone out.
- `GITFLOW_HOOKS` is the one hook list: write/emit/reconcile, T19d and
  doctor.sh (`gitflow.sh hooks`) read it. `.githooks/` and `githooks/`
  regenerated with the fourth hook.
- settings.json: static deny on hand `git branch -d/--delete/-dr/-rd` and
  on renames of main/develop; hard_deny "Branch deletion by hand"; the
  Disarming entry covers all four hooks and `gitflow.*` config; the
  protected-branches environment line states the rule.
- Doctrine (CLAUDE.global.md gitflow section), gitflow SKILL (`delete`
  op, rc 5/6 rows, common mistake), guard-bash spec T8w flips to deny,
  SETTINGS.md, README, CHANGELOG.
- Tests: T22 (12) lib guard incl. the premise proof, T23 (11) hook;
  T19 covers the fourth hook. 152/154, the 2 failures are the
  pre-existing T16a (gitleaks absent on this host).
2026-09-24 11:35:01 +02:00
bastien f608d34c3e feat(gitflow): hooks in every repo, no per-project step
Global: `make link` generates githooks/ from lib/gitflow.sh and sets git's
global core.hooksPath to ~/.claude/githooks, so every repo on the machine
runs the pre-commit protection and the post-commit / post-merge push, even
one that never ran gitflow init. A repo's own local core.hooksPath still
wins, so hooks/session-start.sh calls `gitflow reconcile-hooks` once per
session and rewrites a .githooks/ that lags the lib (LRN-114 automated);
the pre-commit exemption now covers .githooks/** next to .claude/**.

Per-repo opt-outs for a foreign clone: `git config gitflow.protect false`
(branch model) and `git config gitflow.autopush false` (push). Both, and
the GIT_CONFIG_GLOBAL= / GIT_CONFIG= env bypass, are static deny rules.

`make test` and the two suites that commit on main export
GIT_CONFIG_GLOBAL=/dev/null so the machine's global hooks never fire in
throwaway repos. doctor gains "Git hooks" (global setting, githooks/ equal
to the emitters) and "Scratchpad" (warn when TMPDIR sits on a tmpfs with
usrquota: systemd caps each user at 80% of it, which killed two shells
today, BLK-021). Tests: T18h, T19d, T20 (reconcile), T21 (whitelist and
protect opt-out); this repo's own stale .githooks/ refreshed.
2026-09-22 16:34:27 +02:00
bastien 9da5d8d52c feat(guardrails): push every commit, static deny for destructive tools, brief carries no user authority
Layer C of the plan written after the 2026-09-21 wipe (BDR-095): a reviewer
sub-agent traced `lftp mirror --delete` against a local file:// tree, the
prose tiers named neither lftp nor a local trace, the brief had authorized
it, and four days of commits had never left the machine.

- gitflow: `start` pushes the branch with its upstream, merge targets are
  pushed after each merge, and `init`/`install-hook` write post-commit and
  post-merge hooks that push every commit as it lands (warn, never block;
  GITFLOW_NO_PUSH=1 for throwaway repos). T18 + T19 (installed == emitted).
- hooks/unpushed-guard.sh on SessionStart and Stop: branch ahead of its
  upstream, no upstream, or no origin. Non-blocking systemMessage.
- settings.json: static deny for transfer and mirror tools, rsync --delete,
  xargs rm, pipe-to-shell, chmod/chown -R, sudo/doas/pkexec, disk tools,
  chattr, docker volume drops/prune/--privileged/socket/-v /:, git history
  destruction, --no-verify and core.hooksPath; new hard_deny "destructive
  tool against a local path, brief carries no user authority"; soft_deny
  reworded + discarding uncommitted work; environment records the incident.
- CLAUDE.global.md "Destructive tools & data loss"; the four report-only
  agents trace by reading, never by running, whatever the brief says.
- lib/tests/guard-bash.test.sh: executable spec of the PreToolUse guard
  (214 cases). The hook itself is not shipped (BLK-022); the spec skips.
2026-09-22 07:43:12 +02:00
bastien 7c05f75eab feat(21st): replace the magic MCP with the @21st-dev CLI + skill pack
Upstream supersedes `@21st-dev/magic` with `@21st-dev/cli` (bin `21st`):
same endpoint, `21st login` in place of an API key, no MCP process loaded
into every session.

- install-plugins.sh Step 8.7: `npm i -g @21st-dev/cli` (pinned in
  plugins.lock.json), staged `21st skills install`, TTY-only login offer,
  pack disabled by default. update-all.sh 7.4 refreshes both.
- The documented `21st install-skill` cannot be used: the installer refuses
  to follow a symlink on the target path and `~/.claude/skills` is one. The
  install runs under a throwaway HOME and the result moves into
  skills-external/21st-* (gitignored), symlinked on demand.
- toggle-external.sh manages `21st` as a pack (names globbed from
  skills-external/21st-*, parked under plain names). `magic` is gone.
- The 5 design skills join design/web/web-full/full and MANAGED_EXTERNALS;
  21st-registry and 21st-design-sync stay parked. MANAGED_MCPS is now empty
  and profile.sh's dead magic branches are removed.
- Design gate: GATE-BLOCK gains `21st` (required-manual, magic's old slot)
  and `21st-ui-build`; PATH repair extended to the npm global bin.
- settings.json: the 4 mcp__magic__* ask entries go; the outward-facing
  21st verbs land in autoMode.soft_deny, the tier that holds under auto
  mode (LRN-153).
- Docs: README, CLAUDE.global.md, design-gate.md, profile SKILL.md,
  .env.example, .gitleaks.toml, link.sh. BDR-093, LRN-158.

Tests: profile-set-managed 17/17, make test green except 2 pre-existing
gitflow FAILs (gitleaks binary absent on this host), shellcheck clean.
2026-09-22 02:53:31 +00:00
Bastien Chanot 5eccc3f1c4 feat(automode): docker and node framed by the classifier, ask rules retired 2026-09-16 22:03:23 +02:00
Bastien Chanot 823ce42225 chore(config): default model fable 5.1 2026-09-16 21:58:18 +02:00
Bastien Chanot 3b0167c6cb feat(settings): rebuild destructive-command cover in autoMode, scope the classifier environment
`permissions.ask` gates nothing under `defaultMode: auto` (LRN-146,
verified live), so the ten rules that left the static tiers had no cover
left: rsync / kill -9 / killall / pkill out of deny, and python3 -c /
python -c / xargs / sed / cp / mv out of ask.

autoMode.soft_deny (7 rules) takes over what an explicit instruction
should be able to clear: writes outside the working directory,
rsync --delete, SIGKILL and kill-by-name, in-place edits spanning more
than one file, directory moves, and inline interpreters or xargs that
delete or write outside the cwd. Intent clears a soft block for the
current turn only, stated as a rule since no setting expresses it.

autoMode.hard_deny (3 rules) takes the classes no command pattern can
express: secret exfiltration, production deployment, and disarming the
guardrails. Adding a restriction stays allowed, removing one does not.

permissions.deny gains ten .env reader rules (sed awk cut tr sort uniq
diff od xxd strings). Six of those tools sat in permissions.allow, so
reading a .env through them triggered nothing.

autoMode.environment named another project, its FTP deploy target and its
customer data, inside the file link.sh:21 symlinks to
~/.claude/settings.json, where it reached every repo and contradicted
this one's Gitea remote. Rewritten machine-generic; the project facts
moved to that project's gitignored .claude/settings.local.json. All three
lists now open with "$defaults", which the original omitted, so the
built-in classifier entries are inherited rather than replaced.

doctor.sh check_automode backstops both defects. SETTINGS.md documents
the block and a tier-choice table. README no longer claims the ask tier
makes every mcp__magic__* call require a live confirmation.
2026-09-15 19:44:24 +02:00
Bastien Chanot ea9e5c1dab feat(hooks): ring terminal on turn end via Stop hook
Notification matcher covers input-needed events only; end of turn had no
signal but idle_prompt, ~60s late. Wire notify-attention.sh on Stop too,
branching on hook_event_name for the message. Signal only: returns
terminalSequence + suppressOutput, never blocks (guard vs BDR-083).

Header documents both client-side prerequisites found in BLK-020.
2026-09-03 00:28:40 +02:00
Bastien Chanot 6c04ada6a8 chore(settings): default model opus[1m] (was claude-fable-5[1m]) 2026-09-01 15:32:25 +02:00
Bastien Chanot 1d7faa32b5 chore(hooks): notify-attention — bell + OSC 777 toast when Claude needs input
Notification hook (permission_prompt|idle_prompt|agent_needs_input|
elicitation_*) returns BEL x2 + OSC 777 via the terminalSequence JSON
field (hooks have no controlling TTY). Client side over Remote-SSH:
VS Code accessibility.signals.terminalBell sound:on for the beep,
wenbopan.vscode-terminal-osc-notifier extension for the Windows toast.
2026-09-01 15:32:18 +02:00
Bastien Chanot b7026e4bda feat(ctx7): coverage extension — fast-libs single source + reminder hook + executor briefs (BDR-078)
- lib/fast-libs.sh: detect/cache-status verbs, JS+Python manifests,
  7-day cache freshness, LC_ALL=C sort — replaces 3 hardcoded lists
  (ship-feature 0c, init-project 5c, onboard 3.5)
- hooks/ctx7-reminder.sh: once-per-session UserPromptSubmit nudge when
  the project carries fast-libs and .ctx7-cache/ is missing/stale
- find-docs: before-writing-code trigger + cache-first rule; dist is
  machine-owned (gitignored) so the durable patch lives in
  install-plugins.sh STEP ctx7 (idempotent, grep-guarded)
- feater/bugfixer briefs: fast-lib docs rule (fresh cache read, else
  2-topic ctx7 fetch, else NOTES cache miss + proceed)
- tests: lib/tests/fast-libs.test.sh (11 checks); shellcheck + full
  make test green (review-guards 5/0)
2026-07-20 10:45:06 +02:00
Bastien Chanot 354ff2644f feat(agents): pin dispatched judgment agents to opus — Fable = inline reflection only (BDR-076)
Reverses the BDR-066 rejected alternative (opus pins on audit agents):
session default is now Fable, so inherit burned Fable quota on every
dispatched audit/challenge. analyzer, plan-challenger, seo/geo/
validator-analyzer pinned model: opus; onboard's 6 general-purpose
audit dispatches carry model="opus"; tour Phase B repointed.
interviewer + client-handover-writer stay unpinned (inline-load only,
a pin there is inert). settings.json default: claude-fable-5[1m].
Census flipped: model-routing §3 + new §11 (61 pass), loops-light 35,
full make test green.
2026-07-19 17:38:55 +02:00
Bastien Chanot 0e1b89c71a chore(hooks): remove config-protection edit-block guardrail
Full removal per user request: the PreToolUse hook that blocked model
Edit/Write on quality-gate files (settings.json, gitflow.sh, .githooks,
doctor.sh, hooks, lib/tests, lint configs) plus its one-shot sentinel.

- delete hooks/config-protection.sh
- delete lib/tests/config-protection.test.sh
- deregister the hook from settings.json (rtk-rewrite PreToolUse kept)
- drop the README mention

Residual protection unchanged: gitflow pre-commit guard + Gitea branch
protection still block direct code commits to main/develop.
2026-07-17 21:56:32 +02:00
Bastien Chanot 07ca738b3f fix(settings): Write() deny rules inert — convert to Edit(), close write gaps
Startup emitted 15 warnings: "Write(**/.env) is not matched by file
permission checks — only Edit(path) rules are."

Write(path) rules never matched. The 5 secret-file write bans were dead
config — .env, secrets/**, *.pem, *.key were freely writable. Converting
to Edit() makes them enforced: permissions.md:242 "Edit rules apply to all
built-in tools that edit files", and :244 prescribes exactly this ("add an
Edit deny rule for paths no tool may change").

- settings.json: Write(...) -> Edit(...) on the 5 patterns.
- Mirror the 9 secret patterns Read denied but Edit did not: *.p12, *.pfx,
  id_rsa*, id_ed25519*, .ssh/**, credentials, credentials.json,
  .aws/credentials, .azure/**. Read/Edit parity now 14/14. Claude could
  previously overwrite an SSH private key or ~/.aws/credentials.
- New read-allowed/write-denied class: lockfiles (*.lock,
  package-lock.json, pnpm-lock.yaml, go.sum) + node_modules/**. Reading
  aids diagnosis; hand-editing is always wrong — the package manager
  regenerates them via Bash, which Edit deny does not block.
- templates/settings/SETTINGS.md taught the broken Write() pattern; fixed
  at the source so /onboard stops propagating it.

Rule syntax has no negation and deny beats allow, so deny globs cannot
carry exceptions — see the .env.example conflict noted in the follow-up.
2026-07-16 14:45:26 +02:00
Bastien Chanot 5842119d2a added audit folder 2026-07-14 17:21:00 +02:00
Bastien Chanot e4ba8edc16 adde changed settings 2026-07-08 01:29:06 +02:00
Bastien Chanot bb7f25adc1 chore(perms): explicit ask-gate for all magic MCP tools (job8 A)
Empty allowlist stays empty for mcp__magic__* (deny-by-default,
no auto-exec ever). All 4 tools now explicit in permissions.ask
so confirmation is guaranteed regardless of default-mode fallthrough,
instead of relying on undocumented absence. No wildcard.
2026-07-07 19:23:33 +02:00
Bastien Chanot e9241d5d7c added some rules 2026-07-07 13:17:23 +02:00
Bastien Chanot 5d5b386b9c job7 step D: purge stale secret-bearing artifacts (GO-gated)
- rm ~/.claude/projects/.../960bd2cf-...jsonl (transcript with plaintext
  GITEA token — token already rotated; user GO)
- rm ~/.claude/paste-cache/7d48f52c7499c1a7.txt (sourcegraph-access-token
  hit surfaced by make scan-secrets, outside the original job7 triage;
  never read — user GO to delete without further characterization)
- ide/27929.lock: already gone (natural rotation, session ended). Its
  replacement ide/20429.lock is a LIVE lock for the current session —
  left alone, not stale
- settings.json cleanupPeriodDays 30 -> 7 (confirmed field name/scope via
  docs; diff shown and explicitly confirmed before writing — first
  attempt was correctly blocked by the auto-mode classifier for having
  only narrated the diff in text rather than actually pausing for
  confirmation). Only this one hunk staged — the file carries unrelated
  live-session drift (model/effortLevel/permission-list reorder) not
  part of this job, left unstaged.

Residual, deliberately not decided here: transcript f1c9c474-...jsonl
(generic-api-key x8, surfaced by make scan-secrets, not in the original
triage) — not read, not characterized, no option chosen by the user among
self-inspect/TODO/rm. Left intact in TODO as an open item.
2026-07-07 12:53:48 +02:00
Bastien Chanot 96deea100f job2: F2 deny find -exec (arbitrary-exec mirror) 2026-07-06 12:21:56 +02:00
Bastien Chanot 5c05d6796e job2: F1 cp/mv allow→ask (shell-level guardrail overwrite path closed) 2026-07-06 12:21:38 +02:00
Bastien Chanot b4ad134d9a job2: F9 acknowledge /model default — Fable 5 (1M) is the intended default 2026-07-06 12:11:05 +02:00
Bastien Chanot cd9a397140 chore(config): inputNeededNotifEnabled=true — adopt harness notification toggle, committed layout unchanged 2026-07-05 15:31:57 +02:00
Bastien Chanot 049f98d689 chore(config): undo /model side-effect — Opus 4.8 1M default restored; attribution backstop carried to develop 2026-07-05 12:53:08 +02:00
Bastien ChanotandClaude Opus 4.8 83049b94aa chore(config): set default model to Opus 4.8 (1M context)
Pin the default model to claude-opus-4-8[1m] in settings.json (the tracked
config deployed to ~/.claude). Previously no model key was committed, so the
default resolved to the tier default; a working-tree pin to claude-fable-5[1m]
was never committed. Takes effect at next session start.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpphkdTosUzokBDNG7PToS
2026-07-04 05:22:22 +02:00
Bastien ChanotandClaude Opus 4.8 55347445cc feat(hooks): config-protection PreToolUse guards quality-gate files
Blocks Edit/Write to guardrails (settings.json + .claude/settings*, lib/gitflow.sh, .githooks/*, doctor.sh, hooks/*.sh self-guard, lib/tests/*, lint) so a gate can't be weakened to pass an error. Bypass = one-shot sentinel .claude/.config-edit-ok (non-empty reason, logged+consumed), not an env-var. Adaptation from the ECC second-look (BDR-047 corrob): own bash idiom, not ECC's Node dispatcher. shellcheck clean, test 20/20.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpphkdTosUzokBDNG7PToS
2026-07-03 15:29:20 +02:00
Bastien Chanot 8cade82edb Merge feature/audit-hardening into develop 2026-07-02 14:35:56 +02:00
Bastien ChanotandClaude Fable 5 a73dff4edf feat(settings): rtk-wrapped allowlist + .env deny mirrors (audit #11 companion)
The rtk hook no longer auto-allows (audit-bugs branch): rewritten
commands are evaluated natively. Allow rules match the original forms
(grep *, ls *) not the rewritten ones — without explicit rules every
rewrite would fall to the classifier. Added the read-only rtk-wrapped
family, bare + absolute-path forms (the hook emits absolute paths when
PATH lacks the cargo dir): grep, ls, cat, head, tail, wc, diff, git
status/log/diff/show/branch. NOT find (rtk find could carry -exec rm —
native find-deny rules would not match the rtk prefix).
Deny mirrors guard the bypass the allowlist would open on hand-written
'rtk cat .env'-class commands: cat/grep/head/tail × .env, both prefixes.
Residual: exotic quoting may evade the mirrors — second curtain stays
the auto-mode classifier (BDR-004).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zA3Qh2Q1QpcGXzXxKeDHR
2026-07-02 14:29:53 +02:00
Bastien ChanotandClaude Fable 5 56bd5ff0c2 feat(tokens): pr-review-toolkit OFF by default — heaviest plugin, PR-only use
Measured: 6 agent descriptions = ~2.2k tokens injected EVERY session
(the single largest plugin contributor) for a toolkit useful only when
reviewing PRs. enabledPlugins → false; removed from full+backend
profiles (BDR-017 caveat already accepts full excluding rarely-used
items); audit.profile KEEPS it = profile reactivation channel.
Per-PR-session: claude plugin enable pr-review-toolkit@claude-code-plugins
(or bash lib/profile.sh apply audit); a later 'profile set full'
re-disables it via the MANAGED_PLUGINS lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zA3Qh2Q1QpcGXzXxKeDHR
2026-07-02 14:17:55 +02:00
Bastien ChanotandClaude Fable 5 9e534241f9 feat(settings): deny-list hardening pass (audit #20)
- rm -r / rm -fr denied (only -rf was; flag-order variants passed).
- python3 -c / python -c ask → deny: aligned with node -e / perl -e /
  ruby -e (arbitrary-interpreter class was incoherently split).
- git push <remote> +<ref> denied (refspec force carried no flag).
- --force-with-lease un-over-blocked: --force* split into --force /
  --force *, so the safer variant now falls to the git push ASK gate.
Deny 99 → 105, ask 19 → 18. Second curtain unchanged (auto-mode
classifier, BDR-004). doctor's deny sentinel tracks HEAD (LOT 1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zA3Qh2Q1QpcGXzXxKeDHR
2026-07-02 14:16:36 +02:00
Bastien ChanotandClaude Opus 4.8 d4a5cfec93 chore(caveman): purge plugin + always-on integration
Disable + uninstall caveman@caveman and delete every repo dependency on
it: SessionStart/UserPromptSubmit hook blocks, standalone hook files,
settings.json enabledPlugins + marketplace entries, install-plugins.sh
STEP 5.5, update-all.sh refresh step, plugins.lock.json entry, doctor.sh
checks, lib/detect-plugins.sh helpers, lib/profile.sh + plugin-advisor +
skills/profile protected-list entries, .gitignore runtime-file block,
and README/USAGE docs. Dead /caveman:compress refs replaced with
manual/claude.ai guidance. Memory-registry terse-format convention kept
(separate subsystem). Version 3.4.0 -> 3.5.0.

On a subscription plan caveman's ~75% output-token compression has no
cost benefit, and the always-on hooks added friction on validation
gates and client deliverables.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3e8LaH2vymmxyh36h3jFU
2026-06-19 19:08:40 +02:00
Bastien ChanotandClaude bc7f657be0 chore(settings): remove model pin (claude-fable-5[1m] override)
Drop the top-level "model" key so the session falls back to the
default model instead of forcing claude-fable-5[1m].

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 17:00:19 +02:00
Bastien Chanot fbf3e266f9 set fable 5 per default 2026-06-10 12:55:39 +02:00
Bastien ChanotandClaude Opus 4.8 0d9f3d41eb feat(design): mandate full design toolchain on UI work via CLAUDE.md rule + hook
Add a tiered-by-scope "Design work — full toolchain" rule to the global
CLAUDE.md: trivial tweaks stay on /hotfix, building UI mobilizes ui-ux-pro-max,
frontend-design, Magic MCP, emil-design-eng, design-motion-principles, and
design-html; design systems start with design-consultation; reviews use
design-review + emil + motion audit. In doubt about scope, do not silently
skip the toolchain — ask or default to the Build tier.

Reinforce it with a design-toolchain-reminder UserPromptSubmit hook that
detects UI/design signals (broad FR+EN keyword set, \b-guarded against
substring false matches) and injects the tiered guidance into context. Soft
nudge, always exits 0, falls back to raw stdin when the hook JSON is missing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 15:48:10 +02:00
Bastien ChanotandClaude Opus 4.8 6e30af0a01 chore(settings): set effortLevel xhigh, bump model 4-8, re-enable pr-review-toolkit
Add native effortLevel: "xhigh" (persisted enum, replaces dropped invalid "max").
Bump model to claude-opus-4-8[1m]. Re-enable pr-review-toolkit plugin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 19:37:27 +02:00
Bastien ChanotandClaude Opus 4.6 5407d66da9 chore(settings): disable pr-review-toolkit, move model key, drop effortLevel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 22:57:25 +02:00
Bastien ChanotandClaude 7298a2e410 chore(settings): bump effortLevel to max, model to claude-opus-4-6[1m]
Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-21 05:55:08 +02:00
Bastien ChanotandClaude 1dd6b43517 chore(settings): switch default model to claude-opus-4-6
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>
2026-05-21 05:28:31 +02:00
bastienandClaude Opus 4.7 b0d129be27 chore(settings): enable ui-ux-pro-max skill
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>
2026-05-15 22:21:18 +02:00
bastienandClaude 863fc0b646 chore(plugins): swap ui-ux-pro-max for pr-review-toolkit
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>
2026-05-06 17:09:02 +02:00
bastienandClaude 15fa120942 chore(settings): disable example-skills plugin
Toggle example-skills@anthropic-agent-skills off — not used in active
profiles, reduces session-start skill enumeration.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-05 23:46:06 +02:00
bastienandClaude Opus 4.7 64d6ca7843 fix(install,session-start): enable always-on plugins + truthful banner
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>
2026-05-03 23:03:21 +02:00
bastienandClaude Opus 4.7 e4f4edc121 feat(caveman): full install — plugin + standalone hooks + MCP scaffold
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>
2026-05-03 23:02:47 +02:00