feat(hooks): push-block precision, degradation visibility, unpushed-work detection, config ask-gate (U1/U9/U2/U4 — PR1) - #45
Merged
Conversation
… degradation (U1) pre-push-main-blocker.sh compared main/master as a substring anywhere in the push command, so branch names like feature/main-cleanup or domain-master-list were wrongly denied (a live, reproduced false positive). Rewrite the check to compare the actual destination-branch token for equality instead, and extract tool_name/command via a jq-free, field-scoped sed idiom (generalized from branch-pr-discipline.sh's, ported to sed -E for BSD/GNU portability - the literal BRE alternation form silently extracts nothing on BSD/macOS sed). Dropping jq entirely for this hook also closes the prior gap where a missing jq skipped it altogether, including the bare/implicit push-while-on-main case permissions.deny has no literal branch name to pattern-match against. session-start-loader.sh now checks for jq before anything else and, when absent, emits a [HOOK DEGRADATION] context block naming exactly what's degraded (secret detection + file locks, dangerous-command warnings, pre-commit reminders) instead of failing open silently - permissions.deny and the branch-block are both unaffected regardless. docs/hooks.md gains a consolidated Degradation visibility subsection; MIGRATION.md documents the new session-start output. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
session-start-loader.sh now branches on SOURCE: a "compact" or "resume" session start appends a [POST-COMPACTION RE-ORIENTATION] block reminding the session to check the native task list, re-read any active plan artifact, and re-read files before editing them rather than trusting what compaction (or a fresh resume) may have dropped or never carried over. debugging-protocol.md's Stale Context Check gains three matching lines: apply the same re-orientation discipline at the plan level, externalize long plans to a file before starting so there is something durable to re-read, and delegate bulk exploration to workers instead of accumulating it in the orchestrator's own context. Extends the U1 MIGRATION.md entry (same new-SessionStart-output category) rather than adding a second one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
stop-validator.sh only warned about uncommitted files. It now also warns
about unpushed commits, remote-aware: if `git remote` is empty the whole
check is skipped (a naive "commits not on any remote" count would warn on
every commit in every local-only repo, which is noise, not a reminder).
With a remote configured: count commits ahead of the configured upstream
via `git rev-list --count @{upstream}..HEAD` when an upstream tracking
branch exists, or commits unreachable from any remote-tracking ref via
`git rev-list --count HEAD --not --remotes` when it doesn't (with `git push
-u` guidance instead). Warns only when the count is greater than zero.
docs/hooks.md's Built-in Hooks row and Session Management capability list
both mention the new check.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pre-tool-use-validator.sh now asks (not silently proceeds) before a direct Write/Edit to .claude/settings.json, any file under .claude/rules/, or the root CLAUDE.md - the paths /tailor proposes changes to rather than writing directly. Removes the now-contradicting comment claiming these paths are deliberately unprotected/user-configurable. Extends the six secret-shape checks (refactored into a shared detect_secret function to avoid duplicating them) to also scan Bash commands that redirect or heredoc content into a file, closing the blind spot where a heredoc'd .env write bypassed Write/Edit-only detection entirely. Along the way, fixed two bugs surfaced while building this (both pre-existing, not introduced by this change): - A local variable named BASH_COMMAND collided with bash's own special variable of that name (always reflects "the command about to execute"), silently getting clobbered on the next statement rather than holding the extracted value - renamed to TOOL_COMMAND. - The private-key pattern's leading dashes were parsed as grep options on BSD/macOS grep instead of a pattern, so that check silently never matched on those systems; added -e to all six patterns. tailor/SKILL.md gains one line noting the propose-only contract is now hook-backed; docs/hooks.md gets a table-row update, a new Config-Write Ask-Gate section, and an honest limitation note (Trivy CI remains the actual backstop). New MIGRATION.md entry for the new ask prompts. Known gap (flagged, not fixed here - out of this unit's file list): the Bash-command scan only fires in practice if pre-tool-use-validator.sh is also registered under the PreToolUse "Bash" matcher in settings.json, which today only wires it to Write/Edit/MultiEdit/NotebookEdit. The harness cases exercise the script directly and pass regardless, but the capability is inert against real Bash tool calls until that wiring is added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r for Bash (PR1 follow-through) Orchestrator landing fixes for the hooks lane: - 00-baseline.sh: session-start-loader's jq-absent case now expects the [HOOK DEGRADATION] announcement U1 deliberately introduced (the old silent-exit pin is superseded; the other four hooks keep it). - 10-hooks-lane.sh: the clean-and-pushed stop-validator fixture gets its own bare remote — sharing one across unrelated-history fixtures let the second setup silently fail non-fast-forward, making the case order-dependent (deterministically red on landing). - settings.json: register pre-tool-use-validator under the Bash matcher so U4's redirect/heredoc secret scan actually fires for Bash tool calls; smoke-verified plain commands stay silent-allowed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 tasks
dralgorhythm
added a commit
that referenced
this pull request
Jul 24, 2026
…ix (U16/O14 — PR8) (#47) * feat(loop): correction capture — log, retro promotion, stop nudge (U16/O14) Implements research option O14 (artifacts/research_ai_coding_frustrations.md Part 3) — the standing correction-capture loop so mid-session corrections stop getting silently repeated instead of retained. - core-directives.md: new "Correction Capture" subsection — a user correction that contradicts standing rules/skills/instructions gets appended as one line to scratchpad/corrections.log; ordinary task instructions are not logged. - land-the-plane/SKILL.md: Handoff section gains a Retro step — map each non-empty log entry to the strongest enforcement rung it can support (rule/skill/hook/CI, same discipline as postmortem's Prevention step), promote via a small PR or filed issue, then remove the processed line. - stop-validator.sh: compact, position-independent reminder block — when scratchpad/corrections.log is non-empty, name the pending count and point at the retro step. Silent when absent or zero-byte. Kept minimal per the note that PR #45 also touches this file. - New scripts/hook-tests.d/40-self-improvement.sh: hermetic harness cases for the 2-line, absent, and zero-byte log states. - CHANGELOG.md (Unreleased/Added) and MIGRATION.md entries. rules-lines budget: 419 -> 423 lines (budget 500; core-directives.md only touched rule file, +4 lines). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(loop): auto-memory vs rules guidance + re-audit cadence (U16/O14) Completes O14 (artifacts/research_ai_coding_frustrations.md Part 3 / "The standing iteration loop") alongside the prior mechanics commit. - docs/customization.md: new "Session Learning: Auto-Memory vs. Repo Rules" section — Claude Code's per-user auto-memory is for personal preferences and machine quirks (ride the platform feature, don't rebuild it); team-shared, reviewed, CI-checked guidance belongs in .claude/rules//.claude/skills//.claude/hooks/, and corrections.log promotions land there, never only in memory. Cross-links core-directives.md's Correction Capture convention. - CONTRIBUTING.md: new "Standing self-improvement loop" section extending the eval-first/retirement policies with the full capture -> escalate -> verify -> re-audit cycle, including re-running the failure-taxonomy coverage audit from artifacts/research_ai_coding_frustrations.md at each model-generation bump. - CHANGELOG.md (Unreleased/Added) entry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(hooks): BSD sed fallback in branch-pr-discipline + docs row (landing follow-through) - sed -E in the no-jq command extraction: the BRE alternation form silently never matched on BSD/macOS sed, so every warning this hook gives was inert whenever jq was absent (task #26; same bug class the U1 rewrite fixed in the push blocker). Hermetic regression cases pin the fallback via GIT_DIR/GIT_WORK_TREE fixtures. - docs/hooks.md stop-validator row now mentions the corrections-log reminder (flagged by the U16 builder as outside its file list). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR1 hooks lane from
plan_framework_hardening.md: U1 (push-block precision + jq-free fallback + visible degradation), U9 (post-compaction re-orientation), U2 (remote-aware unpushed-work detection), U4 (config-write ask-gate + Bash secret-write scan), plus one orchestrator landing commit.What changed
sed -Eextraction (fixing a BSD/macOS BRE alternation portability bug in the copied idiom); trailing-token branch equality — pushing a branch namedfeature/main-cleanupis no longer denied (this exact false positive fired live on the orchestrator twice mid-session, including once while composing this very PR); jq-free fallback denies bare/implicit pushes on the default branch viagit rev-parse;[HOOK DEGRADATION]announcement at session start when jq is missing..claude/settings.json,.claude/rules/*,CLAUDE.md(tailor's promise now hook-backed); stale opposite-claiming comment removed; six secret patterns now also scan Bash redirect/heredoc writes. Two pre-existing bugs fixed in passing: aBASH_COMMANDspecial-variable collision, and a leading-dash grep bug that silenced the private-key pattern on macOS.Provenance
mainby the orchestrator; independent gate re-run on the lane tip.test-hooks.shALL GREEN (no skips — lane + baseline cases),check-invariants.shALL GREEN (23 checks), CI-equivalent shellcheck clean.Risk tier
medium — behavior-visible hook changes (new ask prompts, new session-start context, validator on every Bash call). MIGRATION.md entries included for U1/U9 and U4. Blast radius bounded: all changes fail open per doctrine; the
permissions.denybackstop is untouched.Test plan
branch-pr-discipline.shcarries the same BSD sed bug (out of lane scope)🤖 Generated with Claude Code