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.
The session-start line-count guard warned 'density pass requis' every session since
job1 without the 275 target (BDR-031) or even the 280 threshold ever being met —
CLAUDE.md sits at 305 (319→305 at job1, never re-inflated). A gate that never goes
green is noise. BDR-062 supersedes BDR-031's 275 TARGET only (principle kept, append-
only): 305 assumed final, guard warns past a 320 margin so real regressions still
surface. Review A6 (verifier-amended MINEUR).
Env-var-only seam (§3.2), zero logic change (diff is one added
condition): the version-check `git fetch` at :215 now skips when
SESSION_START_OFFLINE is set (non-empty), leaving _remote_ver empty
(same as any other offline/fetch-failure path already handled) instead
of hitting the network.
Unlocks (BACKLOG, not built here): a HOME-injected truth-table + smoke
test for session-start.sh (J4-14), without every run paying a network
round-trip or depending on origin/main being reachable.
Verified: bash -n clean, shellcheck clean (pre-existing SC1091 info
only, unrelated). Behavioral: SESSION_START_OFFLINE=1 runs in ~15ms
(no fetch) vs ~740ms unset (fetch attempted) — identical banner output
either way (v4.0.0 == CONFIG_VERSION, no update line in both). Full
`make test` exit 0.
- ALWAYS_ON derived from settings.json:enabledPlugins (true entries)
minus toggle-owned names — the hardcoded pair under-reported newly
enabled plugins (pr-review-toolkit enabled yet invisible). LRN-005.
- Display 'graphify' (the CLI/skill name); graphifyy stays the pipx
package name everywhere it IS the package.
- Overflow split = greedy width-fill: the fixed 3-name cut overflowed
line 1 and printed an empty line 2 with 3 long names.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zA3Qh2Q1QpcGXzXxKeDHR
git show origin/master:version.txt fatal-ed since the gitflow migration
(2026-06-29): the 'update available' banner could never fire while a
synchronous git fetch was still paid every session for a discarded result.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zA3Qh2Q1QpcGXzXxKeDHR
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>
- detect_plan() auto-detects Max/Pro/Free from ~/.claude.json
- session-start budget adapts to plan (Max=20k, Pro=11k, Free=5k)
- token counting now uses only ACTIVE plugins, not installed binaries
- statusline shows plan label + session duration instead of start time
- plugin-advisor: complexity assessment (0-100%) drives tool selection
- plugin-advisor: auto-activation with confirmation (PHASE 4)
- ruflo OFF by default, GSD v2 preferred for multi-session
- init-project: ctx7 pre-fetch + graphify scaffold + graphify full
- ship-feature: ctx7 cache check before implementation
- frontend-design disabled in installer (doublon with ui-ux-pro-max)
- python3 -c moved from deny to ask (unblocks graphify)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>