fix(report): wrap labels in code spans so identifiers don't trip markdown linters (#3147) - #3267
Conversation
…down linters (Graphify-Labs#3147) Four sites in GRAPH_REPORT.md emitted node/community/hyperedge labels as bare text while every other section (God Nodes, Ambiguous Edges, Import Cycles, the isolated-node list) already wraps labels in backticks. A corpus with snake_case identifiers produced raw intraword underscores outside any code span, which markdown linters flag as unbalanced emphasis on the exact identifier text a reader needs to look the node up. Wrapped labels at the four remaining sites to match the file's existing convention: the Community Hubs list, both the hyperedge label/id and its per-node list, the Community heading, and the Communities node list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
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. No changes could be formally verified in this run.
Graphify review — findings
Wraps the four report sites that emitted bare labels — community hub list items, hyperedge labels and their member nodes, community headings, and per-community node lists — in backtick code spans, matching the other label sites so snake_case identifiers no longer produce intraword underscores that markdown linters flag as unbalanced emphasis. Adds tests covering each site plus the hyperedge id fallback when a hyperedge has no label.
No blocking issues surfaced. 2 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 344 functions depend on the 38 functions this change touches.
Health — this change adds coupling hotspots:
- new:
_rebuild_code()— 113 callers, 50 callees - new:
generate()— 37 callers, 7 callees - new:
dispatch_command()— 2 callers, 123 callees - new:
run_pipeline()— 8 callers, 13 callees - new:
make_inputs()— 14 callers, 5 callees - new:
watch()— 5 callers, 7 callees - new:
load_learning_for_report()— 4 callers, 3 callees - new:
test_report_shows_avg_confidence_for_inferred()— 0 callers, 7 callees - …and 2 more — each is listed as a finding
Verification — 344 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: 179 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify generate.
The verifier did not have enough to check generate, 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 ValueError — names the real obstacle, not a sampling gap)
· 10 more finding(s) on lines outside this diff (see the check run).
What
graphify/report.pyemits node/community/hyperedge labels as bare text atfour sites in
GRAPH_REPORT.md, even though every other section in the samefile (God Nodes, Ambiguous Edges, Import Cycles, the isolated-node list)
already wraps labels in backticks. When a corpus has snake_case identifiers
(
_scan_redirects,my_var_name), the generated report contains rawintraword underscores outside any code span. Markdown linters flag those as
unbalanced emphasis — on the exact identifier text a reader needs in order to
look the node up. This is visible today in the repo's own tracked worked
example,
worked/httpx/GRAPH_REPORT.md:Closes #3147.
The fix
Wrapped labels in backticks at the four remaining sites, matching the
God-Nodes/Ambiguous-Edges precedent already in the file:
in its member list (wrapped per-item and joined, not one span around the
whole comma-joined string).
### Community N - "label") — the label, nestedinside the existing quotes.
Nodes (N): ...) — each label wrappedindividually before joining.
Nothing else changed — no refactor, no touching of the sites that already
wrap.
Judgment calls
legal and render as code; the alternative the issue raises is
backslash-escaping the underscore instead. I went with backticks because
it's the convention already used everywhere else in this file, and
backslash-escaping would be a second, inconsistent escaping style. I
grepped the codebase (including
wiki.pyand the Obsidian/HTML exporters)for anything that parses
### Community ...back out of the generatedreport — nothing does.
tests/test_report_gap_thresholds.pyonly regexesthe
"### Community "prefix to count sections, which is unaffected bywhat follows it. Happy to switch to escaping if a maintainer prefers it for
heading readability.
bold (
**\label`**) rather than replacing bold with code — this is also needed for the id-fallback case (h.get('label', h.get('id', ''))`), sincehyperedge ids are frequently snake_case themselves. The node list is
wrapped per-label and then joined, not wrapped as a single span around the
whole string, so linters don't see one giant token.
this file (God Nodes, Ambiguous Edges, isolated nodes) escape an embedded
backtick either, so this fix doesn't invent new escaping machinery for that
case — it matches the existing house style and has the same limitation.
worked/httpx/GRAPH_REPORT.md. This tracked example still shows theold, unwrapped output. I checked
.github/workflows/and found no job thatregenerates or diffs the
worked/examples (theskillgen-checkjob onlyvalidates generated skill files under
graphify/;release-graph.ymlbuilds a fresh self-graph, not the
worked/fixtures). So I left ituntouched rather than regenerating an artifact nothing checks.
Verification
Wrote the regression tests first and confirmed they failed against a pristine
origin/v8checkout (33362d9):(One of the six was an existing test,
test_report_hubs_are_plain_text_by_default,whose assertion had to be updated in place — it pinned the exact pre-fix
unwrapped hub-label string.)
After applying the fix, the same file is green:
Scoped suite:
Full suite, fix branch vs. a pristine
origin/v8checkout (Windows machine;pre-existing failures are symlink-privilege, cp1252-console and missing
optional-dependency tests unrelated to this change):
diffof the twoFAILEDline sets (sorted) is empty — the same 17 testsfail on both, byte-for-byte. Zero introduced, zero fixed. The 5-test gap in
the passed count is exactly the 5 new tests this PR adds.
Lint: