Skip to content

fix(markdown-format): hook lints out-of-tree files when CLAUDE_PROJECT_DIR is unset (add git-worktree fallback scoping) #972

Description

@kyle-sexton

This was generated by AI during triage (T8h conversion of a matured #657 sweep line).

Problem

The markdown-format PostToolUse hook lints .md files that are outside any repository (e.g. a loop lane's session scratchpad / temp dir) with repo-doc rules that don't apply to that content — most visibly MD041 (first-line-h1) and MD013 (line-length 80) firing on GitHub-comment bodies a lane composes as temp .md before gh issue comment --body-file. Pure advisory noise, emitted on every such write.

Root cause (verified on origin/main)

hook::read_file_path() in plugins/markdown-format/hooks/hook-utils.sh gates project-membership scoping on CLAUDE_PROJECT_DIR being SET:

if [[ -n "${CLAUDE_PROJECT_DIR:-}" ]]; then
  # …skip files not under CLAUDE_PROJECT_DIR…
fi
printf '%s' "$file"

When CLAUDE_PROJECT_DIR is unset — as in an autonomous /loop session whose cwd is the home dir, not a repo — the membership block is skipped entirely and the hook proceeds to lint the file wherever it lives. Confirmed live: a loop lane running with CLAUDE_PROJECT_DIR unset had the hook fire on every scratchpad comment-body .md write this session.

Fix direction

When CLAUDE_PROJECT_DIR is unset, fall back to git-working-tree membership instead of no scoping: skip the file when it is not under any git working tree (the hook already has hook::repo_root, which returns empty/hint when git rev-parse --show-toplevel fails). A scratchpad temp file is in no git tree → skipped; a repo .md edited in a session that happens to have CLAUDE_PROJECT_DIR unset is still linted.

Decision defaulted: git-working-tree fallback when CLAUDE_PROJECT_DIR is unset (skip files not under any git tree) — veto before merge. Alternative (simpler, maintainer-vetoable): skip the hook entirely when CLAUDE_PROJECT_DIR is unset — rejected as the default because it would also stop linting legitimate repo .md in an unset-env session.

Acceptance

  • With CLAUDE_PROJECT_DIR unset, a .md write to a path outside any git tree (temp/scratchpad) produces NO markdownlint findings.
  • With CLAUDE_PROJECT_DIR unset, a .md write to a path inside a git working tree is still linted.
  • Existing set-CLAUDE_PROJECT_DIR behavior unchanged. Regression case in markdown-format.test.sh.

Origin

Converted from the fleet-sweep #657 line (markdown-format comment-body-lint noise), first observed by the triage-decide lane 2026-07-22 and root-caused this cycle. Category: bug (hook scoping) · north-star plugin (markdown-format).

Work-class: C3 (bug-fix-shaped) — attended triage 2026-07-23, operator-ratified. 🤖

Metadata

Metadata

Assignees

Labels

agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions