Link-Katalog: authored/alternative-to/addresses, entity→entity-Lineage, Lint-Befund redundant_see_also (4.7.0, #43 #49)
Files changed: - CHANGES.md - VERSION - instructions/link-taxonomy.md - kb/concepts/COLLECTION.md - kb/entities/COLLECTION.md - kb/entities/people/Andrej Karpathy.md - kb/entities/people/Vannevar Bush.md - tools/chemenu/evals/scorecard.py - tools/chemenu/links.py - tools/chemenu/lint_core.py - tools/chemenu/tests/test_lint.py
This commit is contained in:
@@ -181,6 +181,26 @@ def run_lint(kb_dir: Path) -> dict:
|
||||
malformed_edges: list[dict] = []
|
||||
unlabelled_edges: list[dict] = []
|
||||
unauthorised_labels: list[dict] = []
|
||||
redundant_see_also: list[dict] = []
|
||||
|
||||
# Every specific thing any page asserts about any pair, collected before the
|
||||
# loop below because the reverse direction of an edge is not known while
|
||||
# standing on the page that carries it.
|
||||
#
|
||||
# What it is for: `see-also` is the catalogue's declared last resort - it
|
||||
# asserts that nothing better fit. When the *other* page already says
|
||||
# something specific about the same pair (`Wine GE depends-on Wine` opposite
|
||||
# `Wine see-also Wine GE`), the weak edge adds nothing a reader did not
|
||||
# have: direction is authored but the inbound view is rendered, so the
|
||||
# labelled edge already shows on both pages. Measured once on this corpus,
|
||||
# that was 57 of 180 `see-also` edges - the largest single class, and none
|
||||
# of it a vocabulary gap.
|
||||
typed_edges: dict[tuple[str, str], str] = {}
|
||||
for source_title, source_page in pages.items():
|
||||
for edge in links.edges(source_page.frontmatter, "related"):
|
||||
if edge.is_labelled and edge.label != links.SEE_ALSO:
|
||||
typed_edges[(source_title, edge.target)] = edge.label
|
||||
|
||||
for title, page in sorted(pages.items()):
|
||||
type_path = page.frontmatter.get("type")
|
||||
if not type_path:
|
||||
@@ -211,6 +231,16 @@ def run_lint(kb_dir: Path) -> dict:
|
||||
if not edge.is_labelled:
|
||||
unlabelled_edges.append({"page": title, "target": edge.target})
|
||||
continue
|
||||
if edge.label == links.SEE_ALSO:
|
||||
reverse_label = typed_edges.get((edge.target, title))
|
||||
if reverse_label is not None:
|
||||
redundant_see_also.append(
|
||||
{
|
||||
"page": title,
|
||||
"target": edge.target,
|
||||
"reverse_label": reverse_label,
|
||||
}
|
||||
)
|
||||
target_page = pages.get(edge.target)
|
||||
if source_collection is None or target_page is None:
|
||||
continue
|
||||
@@ -301,6 +331,7 @@ def run_lint(kb_dir: Path) -> dict:
|
||||
"malformed_edges": malformed_edges,
|
||||
"unlabelled_edges": unlabelled_edges,
|
||||
"unauthorised_labels": unauthorised_labels,
|
||||
"redundant_see_also": redundant_see_also,
|
||||
"unbalanced_markers": unbalanced_marker_findings,
|
||||
"quote_limit_violations": quote_limit_violations,
|
||||
"invalid_type_paths": invalid_type_paths,
|
||||
@@ -403,6 +434,11 @@ def render_markdown(report: dict) -> str:
|
||||
report.get("unauthorised_labels", []),
|
||||
lambda i: f"[[{i['page']}]] `{i['label']}` -> kb/{i['destination']}/ ([[{i['target']}]])",
|
||||
)
|
||||
_section(
|
||||
lines, "Redundant see-also (the other page already says something specific)",
|
||||
report.get("redundant_see_also", []),
|
||||
lambda i: f"[[{i['page']}]] `see-also` -> [[{i['target']}]], but [[{i['target']}]] already asserts `{i['reverse_label']}` back - drop the weaker edge, the inbound view renders the other one here",
|
||||
)
|
||||
_section(
|
||||
lines, "Dangling Frontmatter References", report["dangling_frontmatter_refs"],
|
||||
lambda i: f"[[{i['page']}]] `{i['field']}:` names `{i['target']}`, which is not a page",
|
||||
@@ -485,7 +521,13 @@ def default_report_path(report: dict) -> Path:
|
||||
# Findings that make a tree structurally wrong rather than merely untidy.
|
||||
# `orphan_pages` is deliberately absent: many pages are validly reachable
|
||||
# through the index or navigation only. `quote_limit_violations` is advisory
|
||||
# too - it flags a habit, not a broken tree.
|
||||
# too - it flags a habit, not a broken tree. `redundant_see_also` joins them for
|
||||
# both of those reasons at once: a weak edge beside a specific one is redundant
|
||||
# rather than wrong, and the check arrived long after the corpora it judges, so
|
||||
# promoting it would turn every existing instance red on the upgrade that
|
||||
# shipped it. Unlike `unlabelled_edges` it is not migration-gated either - there
|
||||
# is no version at which the redundancy becomes an error, only a sweep someone
|
||||
# does or does not get to.
|
||||
#
|
||||
# `malformed_edges` and `unbalanced_markers` are hard from the start: neither
|
||||
# describes an unconverted page, only a broken one.
|
||||
|
||||
Reference in New Issue
Block a user