Design ignore-surface propagation (.graphifyignore etc.) #44

Closed
opened 2026-07-14 16:52:05 +00:00 by jared · 3 comments
Owner

Map: #31
Blocked by #40

Question

When a rule marks files temporary/delete-once-served, should it also propagate to .graphifyignore (keeping them out of the session-start knowledge graph) and the scanner's own skip lists? Define which ignore surfaces, and whether propagation is automatic or an op in the clean report.

Map: #31 Blocked by #40 ## Question When a rule marks files temporary/delete-once-served, should it also propagate to .graphifyignore (keeping them out of the session-start knowledge graph) and the scanner's own skip lists? Define which ignore surfaces, and whether propagation is automatic or an op in the clean report.
jared added the
wayfinder:grilling
label 2026-07-14 16:52:05 +00:00
jared self-assigned this 2026-07-14 17:39:56 +00:00
Author
Owner

CONSTRAINT from #43 (Decide deletion confirm-gates and temporary-tier durations): the ignore surface is an explicit list, NOT an inference from .gitignore. #43 established that gitignored != deletable (graphify-out/** is a tool working store: expensive/slow to rebuild, must never be walked or touched by hygiene) and gitignored != keepable (autoresearch//** raw rounds ARE delete targets once extracted). The #41 inventory's proposal to treat graphify-out/ and .dochygiene/ as 'temporary' is rejected. #43 also fixes an IGNORE posture distinct from lifetime: 'keep' — IGNORE means never walked (directory-rule walk-pruning per #40 implements it), 'keep' means walked and reported but never deleted. graphify-out/** and .dochygiene/** are the seed members of IGNORE.

CONSTRAINT from #43 (Decide deletion confirm-gates and temporary-tier durations): the ignore surface is an explicit list, NOT an inference from .gitignore. #43 established that gitignored != deletable (graphify-out/** is a tool working store: expensive/slow to rebuild, must never be walked or touched by hygiene) and gitignored != keepable (autoresearch/<run>/** raw rounds ARE delete targets once extracted). The #41 inventory's proposal to treat graphify-out/ and .dochygiene/ as 'temporary' is rejected. #43 also fixes an IGNORE posture distinct from lifetime: 'keep' — IGNORE means never walked (directory-rule walk-pruning per #40 implements it), 'keep' means walked and reported but never deleted. graphify-out/** and .dochygiene/** are the seed members of IGNORE.
Author
Owner

RESOLUTION: No ignore-surface propagation. os-doc-hygiene stays in its own lane — separation of concerns.

Decision: A lifecycle rule never writes into any other tool's ignore/config surface. The propagate_ignore field is dropped from the rulebook schema (it was reserved in #40 pending this ticket; the slot is now removed, not left empty).

Two surfaces were considered and both rejected, for different reasons:

  1. The scanner's own skip list (.dochygiene-ignore) — moot, not rejected on principle. #40 already made the rulebook itself the scanner's skip instruction: a directory-rule match prunes the walk and files beneath are never opened. Propagating into .dochygiene-ignore would have os-doc-hygiene writing a file to tell itself a fact it already holds, in a weaker dialect (.dochygiene-ignore is fnmatch — scripts/scanner.py:191-212; the rulebook is glob.translate gitignore-style). Two sources of truth for one fact, with no precedence rule to break a disagreement. .dochygiene-ignore therefore remains a hand-authored, human-only escape hatch, unmanaged by the rulebook.

  2. .graphifyignore — rejected on ownership. .graphifyignore is real (verified in installed graphifyy 0.8.31, graphify/detect.py:682-717; true gitignore dialect, per-directory, falls back to .gitignore where absent). But ADR-017 already assigns ownership of .graphifyignore to os-vault:onboard-project. Having os-doc-hygiene also append to it creates a cross-plugin ownership seam over a file with two writers and no arbiter. The payoff was thin anyway: delete-once-served files get deleted, so they leave the knowledge graph at the next rebuild without any propagation. Propagation would only have helped the narrow temporary-but-not-yet-served window.

memsearch is not a propagation target (fact, not judgement): it indexes its own ~/.memsearch/memory/ daily files, not project docs. It has no ignore-file surface for a 'this project doc is disposable' fact to reach. The only "ignore"/"skip" tokens in its runner are a Python errors="ignore" and a --skip-git-repo-check flag.

Consequences:

  • The glob-dialect mismatch question (rulebook glob.translate vs gitignore vs fnmatch) dissolves — no rule glob is ever translated into a foreign dialect, so there is nothing to translate.
  • #46 (spec + ADR set) must assemble the schema WITHOUT propagate_ignore. This supersedes that one field of #40's locked schema; the rest of #40 stands.
  • If disposable files polluting the knowledge graph later proves painful, the fix belongs to graphify or os-vault:onboard-project — not to a hygiene rule reaching across the seam.
RESOLUTION: No ignore-surface propagation. os-doc-hygiene stays in its own lane — separation of concerns. **Decision:** A lifecycle rule never writes into any other tool's ignore/config surface. The `propagate_ignore` field is **dropped from the rulebook schema** (it was reserved in #40 pending this ticket; the slot is now removed, not left empty). **Two surfaces were considered and both rejected, for different reasons:** 1. **The scanner's own skip list (`.dochygiene-ignore`) — moot, not rejected on principle.** #40 already made the rulebook *itself* the scanner's skip instruction: a directory-rule match prunes the walk and files beneath are never opened. Propagating into `.dochygiene-ignore` would have os-doc-hygiene writing a file to tell itself a fact it already holds, in a weaker dialect (`.dochygiene-ignore` is fnmatch — `scripts/scanner.py:191-212`; the rulebook is `glob.translate` gitignore-style). Two sources of truth for one fact, with no precedence rule to break a disagreement. `.dochygiene-ignore` therefore remains a **hand-authored, human-only escape hatch**, unmanaged by the rulebook. 2. **`.graphifyignore` — rejected on ownership.** `.graphifyignore` is real (verified in installed `graphifyy` 0.8.31, `graphify/detect.py:682-717`; true gitignore dialect, per-directory, falls back to `.gitignore` where absent). But **ADR-017 already assigns ownership of `.graphifyignore` to `os-vault:onboard-project`**. Having os-doc-hygiene also append to it creates a cross-plugin ownership seam over a file with two writers and no arbiter. The payoff was thin anyway: `delete-once-served` files get **deleted**, so they leave the knowledge graph at the next rebuild without any propagation. Propagation would only have helped the narrow `temporary`-but-not-yet-served window. **memsearch is not a propagation target** (fact, not judgement): it indexes its own `~/.memsearch/memory/` daily files, not project docs. It has no ignore-file surface for a 'this project doc is disposable' fact to reach. The only "ignore"/"skip" tokens in its runner are a Python `errors="ignore"` and a `--skip-git-repo-check` flag. **Consequences:** - The glob-dialect mismatch question (rulebook `glob.translate` vs gitignore vs fnmatch) **dissolves** — no rule glob is ever translated into a foreign dialect, so there is nothing to translate. - **#46 (spec + ADR set) must assemble the schema WITHOUT `propagate_ignore`.** This supersedes that one field of #40's locked schema; the rest of #40 stands. - If disposable files polluting the knowledge graph later proves painful, the fix belongs to graphify or `os-vault:onboard-project` — not to a hygiene rule reaching across the seam.
jared closed this issue 2026-07-14 18:14:12 +00:00
Author
Owner

Correction to the resolution above — provenance fix (decision unchanged, rationale strengthened).

The comment above said "ADR-017 already assigns ownership of .graphifyignore to os-vault:onboard-project." That overstated a second-hand summary; I had not read the ADR. Having now read docs/adr/0017-project-graph-onboarding-assesses-the-repo-and-writes-graphifyignore-before-extracting.md, the accurate statement is:

  • ADR-017 does not frame this as exclusive ownership. It establishes that os-vault:onboard-project is the current writer of .graphifyignore, generating it per-project (never from a static template) and confirming the proposed ignore list with the user before writing.
  • Crucially, ADR-017 explicitly rejects the alternative "Auto-write without user confirmation", on the grounds that borderline directories (migrations, seeds, fixtures, sample data) require human judgment and mechanical exclusion would silently drop legitimate content.

So the real reason propagation is refused is stronger than the one I first recorded: an os-doc-hygiene rule appending to .graphifyignore automatically would reinstate precisely the alternative an Accepted ADR already rejected — and would add a second writer to a file with no arbiter between them. Separation of concerns (the user's stated reason) stands on its own regardless.

Unrelated discrepancy found while verifying, logged for #46's ADR set: ADR-017's Context asserts "graphify does NOT honor .gitignore". The installed graphifyy 0.8.31 source (graphify/detect.py:707-711) shows this is no longer strictly true — graphify prefers .graphifyignore but falls back to .gitignore per-directory where no .graphifyignore exists. This does not change ADR-017's decision (a per-project, human-confirmed ignore list is still the right cost lever), but the stated premise is now stale and should be noted rather than propagated as fact.

**Correction to the resolution above — provenance fix (decision unchanged, rationale strengthened).** The comment above said *"ADR-017 already assigns ownership of `.graphifyignore` to `os-vault:onboard-project`."* That overstated a second-hand summary; I had not read the ADR. Having now read `docs/adr/0017-project-graph-onboarding-assesses-the-repo-and-writes-graphifyignore-before-extracting.md`, the accurate statement is: - ADR-017 does **not** frame this as exclusive ownership. It establishes that `os-vault:onboard-project` is the **current writer** of `.graphifyignore`, generating it **per-project** (never from a static template) and **confirming the proposed ignore list with the user** before writing. - Crucially, ADR-017 **explicitly rejects the alternative "Auto-write without user confirmation"**, on the grounds that borderline directories (migrations, seeds, fixtures, sample data) require human judgment and mechanical exclusion would silently drop legitimate content. So the real reason propagation is refused is **stronger** than the one I first recorded: an os-doc-hygiene rule appending to `.graphifyignore` automatically would reinstate precisely the alternative an Accepted ADR already rejected — and would add a second writer to a file with no arbiter between them. Separation of concerns (the user's stated reason) stands on its own regardless. **Unrelated discrepancy found while verifying, logged for #46's ADR set:** ADR-017's Context asserts *"graphify does NOT honor `.gitignore`"*. The installed `graphifyy` 0.8.31 source (`graphify/detect.py:707-711`) shows this is no longer strictly true — graphify prefers `.graphifyignore` but **falls back to `.gitignore` per-directory where no `.graphifyignore` exists**. This does not change ADR-017's decision (a per-project, human-confirmed ignore list is still the right cost lever), but the stated premise is now stale and should be noted rather than propagated as fact.
Sign in to join this conversation.
No description provided.