fix(watch): reconcile Markdown-family links on update - #3655
oleksii-tumanov wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Extends Markdown link reconciliation in _reconcile_markdown_links to cover all MARKDOWN_MENTION_SUFFIXES (.mdx, .qmd, .skill) rather than only .md. Skips sources whose extraction returned an error, so a failed parse no longer claims ownership of—and prunes—persisted authored links; those edges survive until a successful re-parse or actual link removal.
Worth a look
- Deleted markdown sources are treated like parse failures and can keep stale authored links —
graphify/watch.py:607· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 1023 functions depend on the 830 functions this change touches.
Health — this change adds coupling hotspots:
- new:
_rebuild_code()— 131 callers, 54 callees - new:
dispatch_command()— 2 callers, 125 callees - new:
watch()— 5 callers, 7 callees - new:
_reconcile_graph_html()— 6 callers, 5 callees - new:
_reconcile_existing_graph()— 1 callers, 8 callees - new:
_reconcile_markdown_links()— 1 callers, 7 callees - new:
test_poisoned_manifest_is_healed()— 0 callers, 6 callees
Verification — 1023 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: 849 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
8 of 286 test file(s) selected (3%) via static blast radius.
tests/test_elixir_import_resolution.py— impacttests/test_external_stub_endpoints.py— impacttests/test_extract.py— impact, changed-testtests/test_labeling.py— impacttests/test_markdown_code_spans.py— impacttests/test_terraform_modules.py— impacttests/test_watch.py— impact, changed-testtests/test_watch_manifest_location.py— impact
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Formal verification
Could not verify: Could not verify \_reconcile\_markdown\_links.
The verifier did not have enough to check \_reconcile\_markdown\_links, 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: no capturable inputs from the test suite; property tier: parameter `project_root` is annotated `Path` — outside the synthesizable primitive/collection set
· 7 more finding(s) on lines outside this diff (see the check run).
Summary
extract_markdown:.md,.mdx,.qmd, and.skillBefore and after
Before: full updates skipped link reconciliation for
.mdx,.qmd, and.skill. Removed links could remain in the graph, and new links could keep a raw file target instead of an existing semantic representative. A failed reconciliation parse could also look like a real link removal.After: all four supported Markdown-family sources add, repoint, and prune authored links through the same reconciliation path. Error-bearing parses do not claim edge ownership, so a retry can reconcile safely.
Result
The regression matrix covers full-rebuild addition and removal, incremental semantic-target repointing across two rebuilds, and failure preservation followed by successful retry and genuine removal for all four suffixes.
Testing
pytest tests/test_watch.py tests/test_extract.py -q -k 'markdown_reconcile or markdown_dispatch_matches_resolution_suffixes'(30 passed)pytest tests/ -q --tb=short(5,778 passed, 14 skipped)ruff check .(passed)python -m tools.skillgen --check(passed)python -m tools.skillgen --audit-coverage(passed)python -m tools.skillgen --schema-singleton(passed)python -m tools.skillgen --monolith-roundtrip(passed)python -m tools.skillgen --always-on-roundtrip(passed)graphify update .(passed)Fixes #3654