ruvnet / ruvnet/agentic-flow

hooks init generates settings.json with NO permissions.deny and --force overwrites existing rules; also wires PostToolUseFailure (not a hook event) and pre-command (which approves 'rm -fr /')

Open
#207 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
812
Forks
175
Avg merge
2m
Merged PRs (30d)
3

Description

Summary

hooks init generates a .claude/settings.json that omits permissions.deny entirely, wires a hook event that does not exist, and installs commands that are known not to work. With --force — the documented way to re-run it — an existing project's deny rules are replaced by a config that has none.

Version: agentic-flow 2.1.2, Node v22.23.0, macOS 15. Run in an empty directory.

What it generates

✅ Hooks initialized!
   📁 Created: .claude/settings.json
   📊 Created: .claude/statusline.mjs
permissions.allow = ["Bash(npx:*)", "Bash(agentic-flow:*)", "Bash(npm run:*)",
                     "mcp__agentic-flow", "mcp__claude-flow", "mcp__ruv-swarm"]
permissions.deny  = (absent)

hooks:
  PreToolUse          npx agentic-flow hooks pre-edit "$TOOL_INPUT_file_path"
  PreToolUse          npx agentic-flow hooks pre-command "$TOOL_INPUT_command"
  PostToolUse         npx agentic-flow hooks post-edit "$TOOL_INPUT_file_path" --success
  PostToolUseFailure  npx agentic-flow hooks post-edit "$TOOL_INPUT_file_path" --fail --error "$ERROR_MESSAGE"
  SessionStart        npx agentic-flow hooks intelligence stats
  SessionStart        npx agentic-flow workers status --active --json 2>/dev/null || true
  SessionEnd          npx agentic-flow workers cleanup --age 24 2>/dev/null || true
  UserPromptSubmit    npx agentic-flow hooks intelligence stats
  UserPromptSubmit    npx agentic-flow workers dispatch-prompt "$USER_PROMPT" --session "$SESSION_ID"

statusLine = node .claude/statusline.mjs

Concerns, in order of severity

1. No deny array, and --force overwrites. The generated file grants six allow entries including Bash(npx:*) and defines no denies. Re-running with --force in a project that has curated deny rules replaces them with a config that has none. Since --force is the documented way to re-initialise, the failure mode is a user re-running init and silently losing their guardrails. Suggested: merge rather than replace, or at minimum preserve permissions.deny and warn about what is being dropped.

2. PostToolUseFailure does not appear to be a hook event. It is not among the events a working project config uses (PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop, PreCompact, SubagentStart, …). If it never fires, only successes are recorded — and since post-edit is what feeds the "Routing accuracy" figure (#201), that number would sit at 100% by construction rather than by measurement.

3. $TOOL_INPUT_file_path / $TOOL_INPUT_command / $ERROR_MESSAGE. Hook data arrives as JSON on stdin (tool_input.file_path). If those variables are not populated in the hook environment, pre-edit "" and post-edit "" run against an empty path and record nothing — silently, since both exit 0.

4. It installs commands with known defects. pre-command on every Bash call is the one I would flag hardest: it blocks rm -rf / but approves rm -fr /, rm -rf ~, find / -delete and a fork bomb (#197). Wiring it as a PreToolUse hook gives the appearance of a safety gate over whatever real permission rules the user had — which item 1 has just removed. Also installed: hooks intelligence stats twice per interaction (reports Patterns: 0 regardless — #204), workers dispatch-prompt on every prompt and workers cleanup at session end (workers are never actually spawned — #182).

5. statusLine: node .claude/statusline.mjs is a bare relative path with no ${CLAUDE_PROJECT_DIR}, so it depends on the working directory, and breaks on any project path containing a space.

Suggested fix

  • Preserve permissions.deny on --force, or refuse to overwrite a file containing one without an explicit second flag.
  • Drop PostToolUseFailure, or document which host provides it.
  • Resolve the statusline path against ${CLAUDE_PROJECT_DIR} and quote it.
  • Consider generating only the hooks that currently function — post-edit and post-command both record correctly in my testing; most of the rest do not.

Related

  • #197 — pre-command approves rm -fr /, rm -rf ~, find / -delete, fork bomb.
  • #201 — "Routing accuracy" counts post-edit calls, not routes.
  • #204 — intelligence stats reports Patterns: 0 beside a populated store.
  • #182 — workers are never spawned; dispatch-prompt and cleanup are wired here regardless.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the hooks init entry point and inspect how it generates .claude/settings.json and .claude/statusline.mjs. Reproduce initialization and --force in a project with existing deny rules, then verify hook event names, stdin data handling, and statusline path behavior. Done means supported hooks work, existing deny rules are preserved, and generated paths remain valid.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
cli, security, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.