Phase 4-1: Hook hardening (sed bug, portability, dynamic fields)

phase-hierarchy-4-1-hook-hardening Phase

Goal: Fix three QA findings from PR #64 that affect hook correctness and portability across all hooks in claude-custom.
Owner: Dev agent
Repo: forgejo_admin/claude-custom
Depends on: Phase 4 (PR #64 merged)

Problem

QA review of check-phase-template.sh (PR #64) found three issues. Two are cross-cutting (affect all hooks), one is specific to the new hook.

Fix

  • sed ampersand backreference bug (cross-cutting): All hooks using sed 's/</ to decode HTML entities have a latent bug — & in sed replacement is a backreference to the matched pattern. If content contains certain & patterns, the decode step corrupts data. Fix: escape the ampersand in sed replacements or switch to a safer decode method. Affects: check-issue-template.sh, check-note-template.sh, check-phase-template.sh, and any other hook doing HTML entity decoding.
  • GNU grep \| portability (cross-cutting): Hooks use grep 'pattern\|pattern' which is GNU grep syntax, not POSIX. Should use grep -E 'pattern|pattern' for portability. Low risk on Arch but bad practice.
  • Hardcoded field list in check-phase-template.sh: The hook hardcodes Goal/Owner/Repo/Depends on checks rather than extracting them dynamically from template-phase. Unlike check-issue-template.sh which can extract ### headings from the markdown template, phase templates use HTML <strong> tags which are harder to parse. Consider extracting required fields from the template's Hook Enforcement section, or document the tradeoff with a comment.
  • plan-2026-03-07-note-hierarchy-conventions — parent plan, Phase 4
  • QA findings on PR #64 (claude-custom)
  • template-phase — Hook Enforcement section lists what to validate