Skip to content

[Bug]: Skill detect()/detect_incremental() calls ignore the persisted --no-gitignore and --exclude settings (.graphify_build.json) #4240

Closed

Description

@soulmachine

Pre-flight checks

  • I have checked the Troubleshooting section in the README

What happened?

#1886, #2027 and #1971 made --exclude and --no-gitignore persist in graphify-out/.graphify_build.json. graphify update, --watch and the hook read them back (_read_build_excludes / _read_build_gitignore in watch.py).

The skill pipeline does not. skill.md Step 2 calls detect(Path('INPUT_PATH')), and references/update.md calls detect_incremental(Path('INPUT_PATH')). Both use the defaults: gitignore=True and no extra_excludes. I checked this on v8 at 6478eb7.

So when a corpus was built with --no-gitignore, a skill-driven --update:

Expected: the skill honors the same persisted options as the CLI.

Our case: an Obsidian knowledge base whose wiki/ folder is deliberately git-ignored (not versioned) but belongs in the graph. The README says --no-gitignore is the way to do this, and it works for the CLI.

Steps to reproduce

mkdir -p /tmp/gfy-repro/notes /tmp/gfy-repro/docs && cd /tmp/gfy-repro && git init -q
printf 'notes/\n' > .gitignore
echo '# A note' > notes/a.md; echo '# B doc' > docs/b.md; echo '# Skip me' > docs/skip.md
python -I - <<'EOF'   # the graphifyy 0.9.80 environment
from pathlib import Path
from graphify.watch import _write_build_config, _read_build_gitignore, _read_build_excludes
from graphify.detect import detect, detect_incremental, save_manifest
root, out = Path('.'), Path('graphify-out')
# What `graphify extract . --no-gitignore --exclude docs/skip.md` persists:
_write_build_config(out, excludes=['docs/skip.md'], gitignore=False)
print('persisted:', (out / '.graphify_build.json').read_text())
rel = lambda fs: sorted(str(Path(f).resolve().relative_to(Path.cwd().resolve())) for f in fs)
# CLI update/watch/hook path (watch.py) honors the persisted options:
cli = detect(root, gitignore=_read_build_gitignore(out), extra_excludes=_read_build_excludes(out) or None)
print('CLI-path detect():       ', rel(f for v in cli['files'].values() for f in v))
save_manifest(cli['files'], root=str(root.resolve()))
# Skill path, verbatim from skill.md Step 2 / references/update.md:
sk = detect(Path('.'))
print('skill detect():          ', rel(f for v in sk['files'].values() for f in v))
inc = detect_incremental(Path('.'))
print('skill detect_incremental: new =', rel(f for v in inc['new_files'].values() for f in v),
      '| excluded_files =', rel(inc['excluded_files']), '| deleted_files =', inc['deleted_files'])
EOF

Error output or graph output

persisted: {"excludes": ["docs/skip.md"], "gitignore": false}
CLI-path detect():        ['docs/b.md', 'notes/a.md']
skill detect():           ['docs/b.md', 'docs/skip.md']
skill detect_incremental: new = ['docs/skip.md'] | excluded_files = ['notes/a.md'] | deleted_files = []

The skill path drops notes/a.md (git-ignored, but opted in) and re-includes docs/skip.md (excluded).

Graphify version

0.9.80

Operating System

macOS

Python Version

3.13

Installation Method

uv tool install (recommended)

Additional context

Two possible fixes:

  1. In skill.md Step 2 and references/update.md, for every platform copy, read the persisted options and pass them:
    from graphify.watch import _read_build_gitignore, _read_build_excludes
    out = Path('graphify-out')
    detect(Path('INPUT_PATH'), gitignore=_read_build_gitignore(out),
           extra_excludes=_read_build_excludes(out) or None)
  2. Make detect() and detect_incremental() fall back to the persisted values when the caller passes nothing, for example with gitignore: bool | None = None. That fixes every caller in one place, including third-party scripts that follow the runbook.

Option 2 looks safer, because the skill has many platform copies of these calls.

Activity

  1. github-actions commented on Oct 8, 2026

    @github-actions

    Thanks for opening this issue, @soulmachine. A maintainer will take a look soon.

    If you would like to discuss it in real time, come say hi on our Discord server. For longer-form questions and ideas there is also GitHub Discussions.

    To help us triage, please make sure the report includes what you expected, what actually happened, and the steps (and a small sample) to reproduce it.

  2. added a commit that references this issue on Oct 9, 2026
    68e0e9b
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