Skip to content

hcf--v2.1.0

Latest

Choose a tag to compare

@markshust markshust released this 26 Jul 18:36
deebff9

Primarily a bug-fix release. The two additions exist because fixing the bug
properly required a discovery implementation you can actually run and inspect.

Fixed

  • Hooks silently failing to run (#4). Hook discovery was described in HOOKS.md as prose steps for the model to follow, so every session improvised its own bash enumeration. One such script hit a parse error partway through (for f in $LOC/*.md 2>/dev/null — redirections aren't allowed in a for word list), its partial output was consumed as a complete enumeration, and every hook resolved empty. Nothing surfaced, because the empty-hook rule mandates silence — a crashed discovery and a legitimately empty one were indistinguishable. Discovery is now a shipped script (hooks/discover-hooks.sh) that both skills run at all 8 call sites.
  • The frontmatter example in our own docs didn't parse. HOOKS.md and README.md both document enrollment with a trailing comment on every value (phase: post-plan # enrolls this agent…). That form yielded an unknown phase and a non-numeric order, so anyone copy-pasting the documented example got an agent that never ran.
  • Agent files with CRLF line endings were silently skipped, since ---\r doesn't match the frontmatter delimiter.
  • The local-overrides-plugin merge now keys on the frontmatter name, as HOOKS.md always specified, rather than on the filename.
  • A discovery failure can no longer be mistaken for an empty hook. The empty-hook fast path is now defined as exit 0 with empty stdout; every other non-zero exit is an error reported loudly. HOOKS.md's silent fallback to "local agents only" is also gone — quietly dropping the plugin's own bundled agents was itself a failure mode.

Added

  • A command you can run yourself. $(claude plugin path hcf)/hooks/discover-hooks.sh prints what is enrolled at every hook; --hook=<name> for one, --json for tooling. This is the fastest answer to "why didn't my agent fire?" — a question that previously had no answer at all, since the improvised script no longer existed by the time you asked.
  • Drift detection. --fingerprint captures the resolved enrollment across all 8 hooks; plan-create stores it with the plan and plan-orchestrate re-checks it on every hook call. If agent files change midway through a run, HCF halts and names what changed rather than silently finishing against a different pipeline than the plan was reviewed against. Agent body content is deliberately not covered — editing an agent's prose is not drift.
  • Test suite (./tests/run-tests.sh) — 97 tests, no dependencies beyond bash/awk/sed/sort/grep, runs on bash 3.2 (stock macOS).

Changed

  • An invalid phase or mode now aborts (exit 3) instead of being warned past. Previously an unknown phase was ignored with a warning, which meant the agent ran nowhere — the same silent non-execution as the bug above, one level down. Validation is global, so the error surfaces at the first hook of a run rather than hours later at commit time. This can affect existing projects: an agent file with a typo'd phase runs today (minus that agent) and will now halt planning until it is fixed. The error names the file, the bad value, and both remedies — correct the value, or remove the phase key entirely to unenroll the agent. Only plan-create and plan-orchestrate call the script; /project-update and every other skill stay runnable.
  • HOOKS.md's Discovery Routine now documents what the script does rather than instructing the reader to enumerate agent files by hand.