Skip to content

hook-guard: repo-level staleness keeps emitting the MANDATORY nudge after recent commits #3718

Description

@Luoxin

Problem

_run_hook_guard (cli.py) decides staleness per target file: os.stat(fp).st_mtime > gmtime. When the graph predates a batch of recent commits but the file being read hasn't changed since the build, the guard still emits the strict wording:

MANDATORY: graphify-out/graph.json exists. You MUST run `graphify query` ...

Real session: graph built ≤ 2026-09-08; ~21 commits landed in browser-extension/viewer/ after that date (new modules, deleted modules). Every Read in that area got the MANDATORY nudge, so the agent paid graphify query calls on a snapshot that had never seen those modules — queries returned nothing useful and the agent had to fall back to Read/Grep anyway. The stale wording exists (_READ_NUDGE_STALE) but only fires on per-file mtime.

Proposal

When the project is a git repo, also compare repo-level freshness:

head = int(subprocess.run(["git", "log", "-1", "--format=%ct"], ...).stdout or 0)
repo_stale = head > int(gmtime)

If repo_stale, emit the softened wording — e.g.:

graphify-out/graph.json may predate recent commits (last build , latest commit ). For recently changed areas prefer Read/Grep directly; graphify update refreshes the graph.

Fails open as today if git is missing or errors.

Why

The current design already accepts "stale → soften" (#1840b); it just can't see staleness that lives between files, at the commit layer. New/deleted modules are exactly where the graph is most confidently wrong.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions