Commit Graph
22 Commits
Author SHA1 Message Date
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 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 2cebecbb91 feat(gstack): share the Playwright bump, report the browser cache
Extract gstack_bump_playwright_if_unsupported from install-plugins.sh into
lib/gstack-playwright.sh and call it from update-all.sh too. A submodule
update no longer leaves the OS-support bump unapplied until the next
`make plugin` — that was BDR-029's open caveat.

The update helper never touches the submodule working tree: on failure it
prints git's own message and points at `make plugin`, and returns non-zero
so the existing `else warn` arm still handles it.

Add a read-only `Playwright browsers` section to doctor.sh: cache size,
which registered install requires each revision, and counts of unreferenced
directories and broken links. No pruning is written — Playwright's own
`install` already unions the required set across every registered install,
and all three installs here are live (rev 1228 for gstack + gsd-pi 1.61,
rev 1243 for gsd-pi 1.63).

Carries two latent-bug fixes from the moved code: the ostag capture exited
1 on every non-Ubuntu host and aborted the caller under inherited errexit,
and the bun calls had no timeout.
2026-09-15 14:57:31 +02:00
Bastien Chanot e9a38a0268 fix(memory): test covers CLAUDE.global.md guard entry; doctor asserts exact global symlink target 2026-07-14 16:19:29 +02:00
Bastien Chanot c20ad4763a feat(memory): guards, doctor stats and doc-commit exclusions follow CLAUDE.global.md 2026-07-14 03:55:25 +02:00
Bastien Chanot c4bee6aad3 chore(seo-data): install/make/doctor wiring + gitleaks allowlist for token store 2026-07-10 02:10:31 +02:00
Bastien ChanotandClaude Opus 4.8 6778b9fadd fix(doctor): kill 3 false-warns — cargo/RTK, dir-symlink children, token denominator
A doctor that cries false is a doctor you ignore (LRN-047). Three stale
checks fixed:
- cargo "(RTK unavailable)" -> honest optional info: RTK ships prebuilt
  (detect_rtk finds ~/.cargo/bin|~/.local/bin), cargo only builds it from
  source.
- check_symlink passes files reached via dir-level symlinks. hooks/,
  skills/, agents/, lib/, templates/ are directory symlinks, so a child
  like hooks/session-start.sh is a real file under $REPO, not a symlink
  itself. Now: PASS iff the canonical path lands in $REPO; a stray real
  copy still warns as drift.
- gstack check counts the 34 per-skill symlinks into skills-external/gstack/
  instead of a mythical skills/gstack link (link.sh deliberately removes
  that one -> "run link.sh" could never satisfy the old check).
- token budget vs the 200k default context window, not a bogus 11k
  "session budget" -- the old denominator was a category error producing a
  false "92% CRITICAL". Measured footprint ~11.4k post-audit (LRN-088) ->
  ~5% of context.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpphkdTosUzokBDNG7PToS
2026-07-03 13:57:59 +02:00
Bastien ChanotandClaude Fable 5 ca8df16885 fix(doctor): kill 3 permanent false sentinels (LRN-047 class)
- EXPECTED_DENY hardcoded 100 vs 99 real → derive from committed
  settings.json (HEAD): auto-tracks legit deny edits, still flags
  live-vs-committed divergence.
- EXPECTED_SKILLS required gstack 'health' (OFF by default, profile-
  managed): false warn on a default install with a wrong remedy —
  link.sh cannot restore gstack skills. Dropped; 'status' kept (repo-
  owned personal skill, git ls-files proven).
- disable-model-invocation check required a key BDR-019 stripped
  repo-wide (2026-06-09) → warned on every owned skill since.
  Inverted into a BDR-019 regression watch.
- pass message derives the skill list from the array (LRN-005 class:
  no hardcoded display drift).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zA3Qh2Q1QpcGXzXxKeDHR
2026-07-02 14:07:40 +02:00
Bastien ChanotandClaude Opus 4.8 2194b11329 fix(install): install jq prerequisite (active hooks require it)
jq is used 18+ times in always-on hooks (statusline.sh, rtk-rewrite.sh)
but was never installed by any script — it only worked because dev
machines happened to have it; a bare machine breaks at hook-run time.
Add it to Step 1 (same inline pattern as the other prereqs) and to
doctor.sh at fail level.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UyNYwD4UccVw9ZCFZyJX55
2026-06-23 14:09:55 +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 Opus 4.6 23449dfc82 fix(scripts): add gstack infra symlinks to install, update, and doctor
The gstack/bin/ and gstack/browse/dist/ symlinks (added in link.sh) were
missing from install-plugins.sh and update-all.sh, meaning fresh installs
and updates wouldn't create them. Also adds doctor.sh health checks.

- install-plugins.sh: create symlinks after gstack ./setup
- update-all.sh: refresh symlinks after gstack submodule update
- doctor.sh: verify both symlinks exist in consistency section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 07:25:03 +02:00
Bastien ChanotandClaude Opus 4.6 6b55a3aaf6 fix(doctor): update stale skill/agent refs, scope disable-model-invocation check
- 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>
2026-05-25 21:34:42 +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
bastienandClaude Opus 4.7 94b79d2ebb fix(doctor): guard gstack find against set -euo pipefail
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>
2026-05-03 23:00:11 +02:00
bastienandClaude 71955ea7b3 fix(shell): resolve all shellcheck warnings across scripts
- SC2088: replace ~ with $HOME in quoted strings (doctor.sh)
- SC2010/SC2012: replace ls|grep with compgen -G globs (detect-plugins.sh)
- SC2034: remove unused PKG and RED variables (install-plugins.sh, update-all.sh)
- SC2015: convert A&&B||C to proper if/then/else (update-all.sh, install-plugins.sh, session-start.sh)
- SC1090: add shellcheck source directive (statusline.sh)
- SC2129: group redirects into single block (install-plugins.sh)

0 warnings remaining (3 SC1091 info-level expected).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-16 01:08:23 +02:00
bastienandClaude Opus 4.6 50db70cbf2 chore: remove ruflo and frontend-design — full cleanup
Both plugins removed from all config, scripts, and documentation:
- ruflo: uninstalled globally (npm), removed from install/update/doctor/session-start/detect/lock/advisor
- frontend-design: removed from install/session-start/detect/advisor (was already commented out)
- plugin-advisor.md: compatibility matrix, decision table, conditional rules, recommended sets all updated
- README.md/USAGE.md: all references cleaned, token cost estimates recalculated
- install-plugins.sh: steps renumbered (10→9 steps)
- CHANGELOG.md: kept as historical record

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 23:54:52 +02:00
bastienandClaude Opus 4.6 35ea5c1a49 audit fixes: RTK hook, settings unification, graphifyy, statusline
- Add RTK PreToolUse hook (rtk-rewrite.sh) and fix missing config
- Unify settings.json: merge hooks, marketplaces, model into project file
  so link.sh symlink is the single source of truth
- Add statusline: model, folder, git branch, context % progress bar
- Add graphifyy support: detect, install (pipx), lock, doctor, session-start
- Clarify ctx7/ruflo as standalone CLI (not MCP servers)
- Fix install-plugins.sh step numbering (duplicate step 6)
- Add version check in session-start (local vs origin/master)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 13:28:30 +02:00
bchanot 4c9ad86ee4 suppressed mcp ctx7 and ruflo 2026-04-09 19:06:34 +02:00
bchanot 854a0af92a changed context7 to cli 2026-04-09 14:31:24 +02:00
bchanot f55a2b3fdf final version seems 2026-04-08 13:46:45 +02:00
bastien f8811fab37 opus version correction 2026-04-03 18:08:21 +02:00