Skip to content

scripts/kg: the pipeline ingests SCHEMA_/Edge-Types/log docs as content, so their illustrative examples become real entities in the graph #85

Description

@psaboia

Summary

scripts/kg/build-graph.sh walks every .md in the wiki, including the files that only describe the format — SCHEMA_<repo>.md, Edge-Types.md, log_<repo>.md, and correction-log pages. Their illustrative examples are parsed as real frontmatter and real links, so placeholder names become entities and edges in the knowledge graph.

Found while rendering the KG for the first time during a reciprocity experiment. It is independent of reciprocity — it reproduces in a wiki that never ran any sweep, and in this template's own production wiki.

Evidence

Production — this repo's own wiki (33 pages), after ./scripts/kg/build-graph.sh, these appear as graph nodes:

Page-Name   Parent-Page   WIKI-INDEX   Markov-Chain-v5c2

A control wiki from a --agent=claude-code instantiation that never ran a lint sweep — same contamination:

Page   Page-Name   Parent-Page   Theory-X   WIKI-INDEX

The graph contains real triples built from documentation examples, e.g. SCHEMA_<repo> --extends--> Theory-X (from the SCHEMA's own example of a typed edge) and up: "[[Parent-Page]]" (SCHEMA line 41, the example frontmatter block).

Markov-Chain-v5c2 is the sharpest case: it was a naming placeholder on a lesson page, already fixed there by a lint pass. It survives in the KG because it is now quoted in Wiki-Corrections-Log — the page that records the fix, whose text even says the replacement was made "to keep the example from showing up as a dead link to the lint pass and the KG". The correction record reintroduced the entity it documented removing.

Impact

Any SPARQL query, hub calculation, orphan detection, or graph metric over the KG is computed against invented entities and edges. Nobody had noticed because the graph is built and SHACL-validated but never inspected — validation does not ask "are these nodes real pages?".

Suggested fix

Exclude the scaffolding files from the walk, the way the other tools already do. scripts/wiki-reciprocity.py (shipped in #84) and the experiment's scorer both use the same exclusion and stay clean:

SPECIAL = re.compile(r'^(Home|Home_|index_|log_|SCHEMA_|Edge-Types)')

Edge-Types.md needs care: wiki-to-jsonld.py already treats it specially (EDGE_TYPES_PAGE = 'Edge-Types') as the predicate vocabulary source, so it should stay readable as vocabulary while not contributing page entities/edges.

Correction-log pages that quote dead examples in prose are a residual case the regex won't catch; worth deciding whether that matters or whether such pages should carry a frontmatter opt-out.

Red-first suggestion, per .claude/rules/observe-the-failure.md: assert the current build produces Theory-X/Parent-Page nodes (it does — that's the red), then that the filtered build does not.

Related, but a separate concern

The same inspection showed the pipeline accepts off-vocabulary predicates without complaint: the SCHEMA declares extends/supports/criticizes/related/source/derived_from, but agents invented dependsOn, prerequisiteOf, partOf, hasPart — and the build not only keeps them, it materialises inverses for them. In one measured chain the semantic layer was 13 triples, most of them off-vocabulary.

That is a design decision (reject? warn? widen the SCHEMA?) rather than a defect, and it overlaps the open-taxonomy proposal in #79, so I have left it out of this issue. Happy to file it separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions