CR-2026-03-25: Hooks Enhancement — Implementation

Pre-Change Checklist

Prerequisites

  • Backup strategy documented (SessionStart hook creates daily backups)

  • Rollback procedure documented below

  • Validation script created and tested

  • Test suite created with 5 test cases

  • D2 diagram created with animation

  • Current hooks.json captured (Phase 1)

Current State

Metric Pre-Change Value

Total hook events configured

4 (PreToolUse, PostToolUse, UserPromptSubmit, SessionStart)

PostToolUse Edit hooks

1 (shellcheck for .sh files)

AsciiDoc validation

None

Backup location

~/.claude/backups/

Implementation Procedure

Phase 1: Capture Current State

# Create timestamped backup
cp ~/.claude/hooks.json ~/.claude/backups/hooks.json.$(date +%Y%m%d-%H%M%S).bak

# Verify backup
ls -la ~/.claude/backups/hooks.json.*.bak | tail -1

# Capture current hook count
jq '.PostToolUse | length' ~/.claude/hooks.json

Expected output: 1 (existing shellcheck hook)

Phase 2: Install Validation Script

The validation script has been pre-created at ~/.claude/hooks/validate-asciidoc-attrs.sh.

# Verify script exists and is executable
ls -la ~/.claude/hooks/validate-asciidoc-attrs.sh

# Run test suite
~/.claude/hooks/test-validate-asciidoc-attrs.sh

Expected: All 5 tests pass

Phase 3: Update hooks.json

Add AsciiDoc attribute validator to existing PostToolUse Edit hooks array.

Before (existing shellcheck only):

"PostToolUse": [
  {
    "matcher": "Edit",
    "hooks": [
      {
        "type": "command",
        "command": "FILE_PATH=$(echo \"$ARGUMENTS\" | grep -o '\"file_path\":\"[^\"]*\"' | cut -d'\"' -f4); if [ -n \"$FILE_PATH\" ]; then case \"$FILE_PATH\" in *.sh|*.bash|*.zsh) if command -v shellcheck >/dev/null 2>&1; then shellcheck \"$FILE_PATH\" 2>&1 | head -10 || echo \"ShellCheck: no issues\"; else echo \"ShellCheck: not installed\"; fi ;; *) echo \"Validation: skipped (not a shell script)\" ;; esac; fi",
        "timeout": 10
      }
    ]
  }
]

After (shellcheck + adoc validator):

"PostToolUse": [
  {
    "matcher": "Edit",
    "hooks": [
      {
        "type": "command",
        "command": "FILE_PATH=$(echo \"$ARGUMENTS\" | grep -o '\"file_path\":\"[^\"]*\"' | cut -d'\"' -f4); if [ -n \"$FILE_PATH\" ]; then case \"$FILE_PATH\" in *.sh|*.bash|*.zsh) if command -v shellcheck >/dev/null 2>&1; then shellcheck \"$FILE_PATH\" 2>&1 | head -10 || echo \"ShellCheck: no issues\"; else echo \"ShellCheck: not installed\"; fi ;; *) echo \"Validation: skipped (not a shell script)\" ;; esac; fi",
        "timeout": 10
      },
      {
        "type": "command",
        "command": "~/.claude/hooks/validate-asciidoc-attrs.sh",
        "timeout": 5
      }
    ]
  }
]

Phase 4: Verify Configuration

# Validate JSON syntax
jq . ~/.claude/hooks.json > /dev/null && echo "JSON valid"

# Count PostToolUse Edit hooks
jq '.PostToolUse[0].hooks | length' ~/.claude/hooks.json

Expected: 2 (shellcheck + adoc validator)

Phase 5: Functional Testing

Test Action Expected Result

Test 1

Edit a .adoc file with valid attributes

No warning displayed

Test 2

Edit a .adoc file with {nonexistent-attr}

"WARNING: Undefined AsciiDoc attributes: {nonexistent-attr}"

Test 3

Edit a .md or .txt file

No validation (skipped)

Test 4

Edit a .sh file with shellcheck issues

ShellCheck warnings displayed (existing behavior)

Post-Change Validation

State Comparison

Metric Pre-Change Post-Change

Total hook events

4

4 (unchanged)

PostToolUse Edit hooks

1

2

AsciiDoc validation

None

Active

Edit operation time (typical)

~100ms

~1.1s (validation adds ~1s)

Monitoring Checklist

  • No hook timeout errors in Claude Code output

  • Edit operations complete normally

  • Valid .adoc files show no warnings

  • Invalid .adoc files show appropriate warnings

  • ShellCheck still works for .sh files

Scope Management

In Scope

  • PostToolUse hook for Edit tool on .adoc files

  • Attribute validation against antora.yml

  • Warning output for undefined attributes

  • Built-in attribute whitelist

Out of Scope (Future CRs)

  • xref validation (requires parsing, different approach)

  • Real-time antora.yml caching

  • Integration with Antora build process

  • MCP server for attribute lookup

Amendment Process

If scope changes are required during implementation:

  1. Document the proposed change in this CR under "Amendments" section

  2. Assess impact on timeline, risk, and benefits

  3. Approve minor changes (self-approval for low-risk)

  4. Escalate major changes to new CR

Amendments

No amendments at this time.

Lessons Learned

To be completed post-implementation.

Questions to Answer

  • Did the hook catch any real issues during normal workflow?

  • Was the 5s timeout sufficient?

  • Any unexpected false positives?

  • Should this approach extend to other validation types?

Appendix A: Validation Script

Full source: ~/.claude/hooks/validate-asciidoc-attrs.sh

Table 1. Script Summary
Feature Implementation

File type check

[[ ! "$FILE_PATH" =~ \.adoc$ ]] → skip

Attribute extraction

grep -oE '\{[a-zA-Z][a-zA-Z0-9_-]*\}'

antora.yml discovery

Walk up directory tree, fallback to git root

Built-in whitelist

80+ standard AsciiDoc attributes

Output

WARNING message with attribute list

Appendix B: Test Suite

Full source: ~/.claude/hooks/test-validate-asciidoc-attrs.sh

Test Case Input Expected

Non-.adoc file

readme.md

Skip (PASS)

Valid attributes

File with {defined-attr}

No warning (PASS)

Invalid attributes

File with {undefined-attr}

WARNING displayed (PASS)

No attributes

Plain .adoc file

No warning (PASS)

Built-in attributes

File with {nbsp}, {toc}

No warning (PASS)