Skip to content

fix(cli): clean build intermediates with pathlib instead of rm - #2797

Open
hudsonwa wants to merge 1 commit into
Graphify-Labs:v8from
hudsonwa:fix/cleanup-intermediates-pathlib
Open

fix(cli): clean build intermediates with pathlib instead of rm#2797
hudsonwa wants to merge 1 commit into
Graphify-Labs:v8from
hudsonwa:fix/cleanup-intermediates-pathlib

Conversation

@hudsonwa

Copy link
Copy Markdown
Contributor

Summary

Step 9 told the agent to rm / find -delete intermediates. On permission-gated hosts those verbs are denied, so .graphify_chunk_*.json survived and the next --update could merge stale chunks.

Cleanup now runs in Python (Path.unlink), same as the rest of the pipeline.

Related

Fixes #2790

Type

  • Bug fix
  • Feature
  • Docs

Changes

  • graphify/paths.py: cleanup_build_intermediates()
  • graphify clean [dir] CLI
  • skill.md Step 9 (and the mid-pipeline temp cleanup) call graphify clean graphify-out
  • Tests for named files, chunk glob, missing dir, no subdirectory descent

How to Test

uv run --frozen pytest tests/test_cleanup_intermediates.py -v

3 passed. Does not delete graph.json. Does not walk into subdirs.

Notes

Did not regenerate every skill-*.md host file in this PR — source of truth is skill.md (what most installs copy). Happy to run skillgen in a follow-up if you want the platform clones updated in the same change.

…ify-Labs#2790)

Permission-gated hosts deny `rm` and `find -delete`, so Step 9 left
stale .graphify_chunk_*.json files that the next --update would merge.
`graphify clean` unlinks the same files in Python.

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).

Formal verification. 1 change(s) tested, no difference found (not proven).


Graphify review — findings

This PR replaces the shell-based cleanup of Step 9 build intermediates (rm/find -delete) with a Python/pathlib implementation, motivated by permission-gated hosts that deny those shell verbs. It adds a cleanup_build_intermediates helper in paths.py, a new clean [dir] CLI subcommand (with help text and dispatch handling), updates skill.md to call graphify clean instead of the shell commands, and adds unit tests covering the new cleanup function. The surface area touches graphify/__main__.py (help output), graphify/cli.py (command dispatch), graphify/paths.py (new constant and function), graphify/skill.md (documentation), and a new tests/test_cleanup_intermediates.py.

No blocking issues surfaced. 5 lower-confidence candidates did not survive cross-model review.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1534 functions depend on the 116 functions this change touches.

Health — this change adds coupling hotspots:

  • new: extract() — 463 callers, 41 callees
  • new: _rebuild_code() — 95 callers, 51 callees
  • new: build_from_json() — 151 callers, 18 callees
  • new: build_merge() — 41 callers, 14 callees
  • new: save_manifest() — 34 callers, 11 callees
  • new: to_obsidian() — 29 callers, 12 callees
  • new: to_wiki() — 41 callers, 7 callees
  • new: to_json() — 44 callers, 6 callees
  • …and 38 more

Verification — 1534 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 1197 function(s) in the blast radius were not formally verified this run

Formal verification

Could not verify: Could not verify dispatch\_command.

The verifier did not have enough to check dispatch\_command, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: not verifiable: all 23 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly SystemExit — names the real obstacle, not a sampling gap)

No difference found (not proven): No behavior difference found in \_run\_cli (not a proof).

The verifier ran both versions of \_run\_cli on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.

Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.

Note: An input the sampler did not try could still differ.

· 1 grounded finding(s) anchored inline below; 45 more finding(s) on lines outside this diff (see the check run).

Comment thread graphify/cli.py
@@ -803,6 +803,19 @@ def _reenter_main() -> None:


def dispatch_command(cmd: str) -> None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Health regressiondispatch_command()

fans out to 118 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

@abhay-codes07

Copy link
Copy Markdown
Contributor

Heads up on the skillgen-check failure @hudsonwagraphify/skill.md is generated, so editing it directly shows up as drift. The source is tools/skillgen/fragments/core/core.md; move the two edits there and run python -m tools.skillgen (then --bless to refresh expected/) and that job should go green.

Worth knowing while you're in there: the same rm -f / find -delete pair lives in fragments/core/devin.md and fragments/core/aider.md, and Clean up after: rm -f ... is in fragments/references/shared/update.md too. Regenerating from the fragments picks up all 21 skills at once, so codex/windows/droid get fixed with the same change rather than staying on rm.

One thing to watch on the windows render: gen.py's POSIX->PowerShell translator is strict and raises on any bash line it doesn't recognise, so it's worth checking graphify/skill-windows.md after regenerating.

I'd been working on the same issue from the fragments side and have it passing all five validators — happy to hand that over or close mine in favour of your graphify clean approach, whichever the maintainers prefer. Your subcommand is the nicer call site; it just needs to be called from the fragments so every host gets it.

@hudsonwa

Copy link
Copy Markdown
Contributor Author

Thank you for this, and I'm sorry I walked across work you already had going.

I hadn't realised skill.md was generated. I'll move the skill edits into the fragments and regenerate, and leave graphify clean as the call site.

Please don't close #2801 on my account. If the maintainers prefer yours, I'll happily close this. Thank you for offering either way.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Step 9 cleanup shells out to rm / find -delete, which permission-gated hosts deny — stale .graphify_chunk_*.json survives into the next --update

2 participants