Skip to content

Fix needs_update flag dot/no-dot mismatch in skill runbooks - #2782

Open
ayushcodes10 wants to merge 1 commit into
Graphify-Labs:v8from
ayushcodes10:fix-2671-needs-update-dot-mismatch
Open

Fix needs_update flag dot/no-dot mismatch in skill runbooks#2782
ayushcodes10 wants to merge 1 commit into
Graphify-Labs:v8from
ayushcodes10:fix-2671-needs-update-dot-mismatch

Conversation

@ayushcodes10

Copy link
Copy Markdown

skill.md's cleanup step targeted graphify-out/.needs_update (with a
leading dot), but every actual writer/reader of the flag uses the name
WITHOUT a dot: watch.py's needs_update path, and cli.py's
out_path("needs_update") check. The cleanup command never matched the
real file, and any staleness check written against the documented
(dotted) name would silently never fire.

This fixes the one purely mechanical bug in #2671 -- the dot/no-dot
naming mismatch. The issue's larger proposal (adding a staleness-check
paragraph to the fast-path text, propagated across skill*.md variants)
is a separate maintainer call about wording/scope and isn't included
here.

Fix the three source fragments (core.md, and the two monolith bodies
aider.md/devin.md) and regenerate all 16 skill*.md variants plus their
expected/ snapshots via skillgen. Add a sanctioned-diff predicate in
gen.py's monolith-roundtrip guard so the deliberate one-line change to
the two monolith bodies passes review instead of reading as
unreviewed drift.

Verified end-to-end: with the old (dotted) command, rm -f graphify-out/.needs_update does not remove a real
graphify-out/needs_update file (the form watch.py actually writes);
with the fix it does. All four skillgen validators (--check,
--audit-coverage, --schema-singleton, --monolith-roundtrip,
--always-on-roundtrip) pass, and the full test suite (4314 tests)
passes.

Fixes #2671.

skill.md's cleanup step targeted graphify-out/.needs_update (with a
leading dot), but every actual writer/reader of the flag uses the name
WITHOUT a dot: watch.py's needs_update path, and cli.py's
out_path("needs_update") check. The cleanup command never matched the
real file, and any staleness check written against the documented
(dotted) name would silently never fire.

Fix the three source fragments (core.md, and the two monolith bodies
aider.md/devin.md) and regenerate all 16 skill*.md variants plus their
expected/ snapshots via skillgen. Add a sanctioned-diff predicate in
gen.py's monolith-roundtrip guard so the deliberate one-line change to
the two monolith bodies passes review instead of reading as
unreviewed drift.

Fixes Graphify-Labs#2671.
@ayushcodes10

Copy link
Copy Markdown
Author

@safishamsi this PR's CI run is waiting on approval (first-time contributor gate) — could you approve the workflow run when you get a chance? Happy to address any review feedback in the meantime.

@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 appears to revert a set of previously unreleased 0.9.44 changes back into a 0.9.43 (unreleased) state. In the CHANGELOG it removes the 0.9.44 section (covering hook .graphifyrc node-limit baking, CLAUDE.md config-dir handling, JS/TS shadowing fixes, gitignore-tracked-file handling, doctest/Catch2 recovery, the affected absolute-seed root resolution, lazy require edges, and OCaml external-call fixes) and marks 0.9.43 as unreleased. It also removes YouTube badges from the README and reverts the affected/resolve_seed/format_affected code that derived a repo root from the graph location back to using Path.cwd(), dropping the root parameter. The touched symbols span a large number of tests (languages, extract, detect, hooks, install) and skill/tooling files, indicating the revert extends across test fixtures and skill manifests as well as the core detect/extract/affected/CLI modules.

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

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 4563 functions depend on the 3398 functions this change touches.

Health — this change adds coupling hotspots:

  • new: extract() — 454 callers, 41 callees
  • new: _rebuild_code() — 95 callers, 51 callees
  • new: detect() — 93 callers, 14 callees
  • new: _extract_generic() — 18 callers, 23 callees
  • new: save_manifest() — 34 callers, 11 callees
  • new: extract_files_direct() — 17 callers, 20 callees
  • new: extract_xaml() — 19 callers, 17 callees
  • new: extract_corpus_parallel() — 26 callers, 10 callees
  • …and 76 more

Verification — 4563 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: 4480 function(s) in the blast radius were not formally verified this run

Formal verification

Could not verify: Could not verify \_as\_repo\_relative.

The verifier did not have enough to check \_as\_repo\_relative, 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: parameter `root` is annotated `Path | None` — outside the synthesizable primitive/collection set

No difference found (not proven): No behavior difference found in format\_affected (not a proof).

The verifier ran both versions of format\_affected 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.

Could not verify: Could not verify resolve\_seed.

The verifier did not have enough to check resolve\_seed, 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: parameter `root` is annotated `Path | None` — outside the synthesizable primitive/collection set

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)

Could not verify: Could not verify detect.

The verifier did not have enough to check detect, 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: parameter `root` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify ignored\_predicate.

The verifier did not have enough to check ignored\_predicate, 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: parameter `root` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify extract\_cpp.

The verifier did not have enough to check extract\_cpp, 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: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify \_extract\_generic.

The verifier did not have enough to check \_extract\_generic, 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: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify \_require\_imports\_js.

The verifier did not have enough to check \_require\_imports\_js, 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 200 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly AttributeError — names the real obstacle, not a sampling gap)

Could not verify: Could not verify extract\_ocaml.

The verifier did not have enough to check extract\_ocaml, 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: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify install.

The verifier did not have enough to check install, 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: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify \_install\_hook.

The verifier did not have enough to check \_install\_hook, 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: parameter `hooks_dir` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify status.

The verifier did not have enough to check status, 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: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set

Could not verify: Could not verify install.

The verifier did not have enough to check install, 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)

· 84 more finding(s) on lines outside this diff (see the check run).

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

Labels

None yet

Projects

None yet

1 participant