Repository navigation
Trace citation metadata through Yoast SEO and NLWeb - #253
Conversation
Adds tools/yoast-nlweb-trace: a local WordPress 7.1 + Borges + Yoast SEO 28.8 + NLWeb site, built by setup.sh, and scripts that capture the fixture post (the markup-value corpus) at each stage on the way to an agent: the page's JSON-LD, Yoast's graph, Yoast's schema aggregator feed, NLWeb's index (its own ingest code, from a crawl and from the feed), and NLWeb's WordPress plugin answering an MCP `ask`. measure.py scores 78 field values per stage; probe.py checks which questions each stage can still answer. Today only titles (and DOIs inside @id URLs) get past Yoast: the full records stay in Borges' ItemList, which NLWeb's trim drops. NLWeb's WordPress plugin got no citations at all (fixed in #252). Two prototypes show what putting full records into Yoast's graph would carry, and at what page weight. No model was run: the ranking LLM is a recording stub. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA2F1J2N3yCPk3cUX1P
The trace site's setup scripts set WordPress and plugin options on the throwaway site they build. tools/ is not in the release package, so the no-persistence audit now skips it, as the metrics doc says. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA2F1J2N3yCPk3cUX1P
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #253 +/- ##
=========================================
Coverage 88.68% 88.68%
Complexity 67 67
=========================================
Files 102 102
Lines 10989 10989
Branches 962 962
=========================================
Hits 9746 9746
Misses 445 445
Partials 798 798 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…-builder into yoast-trace # Conflicts: # docs/current-metrics.md
|
@codex review Generated by Claude Code |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67d9edf084
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
measure.py read only 1-page.html, which the committed runs replace with 1-page-json-ld.json, so the published tables could not be recomputed without the stack. It now falls back to the extracted JSON-LD and picks Yoast's graph as the block with an @graph. Recomputing all four committed runs reproduces their survival.json byte for byte. The README now says the pr-252 rows need #252's context fix (78947a5 or later) checked out, and keeps the main baseline run separate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA2F1J2N3yCPk3cUX1P
|
@codex review Generated by Claude Code |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
* Read the post from Yoast's context when adding citations Borges added the cited works to Yoast SEO's Article (or WebPage) piece using the main query's post, so a graph Yoast built for another caller had no citations. NLWeb's WordPress plugin is one: it calls YoastSEO()->meta->for_post() to answer agents over MCP, and its answers lost the citation edge. Found while tracing citation metadata through Yoast and NLWeb on a local site. The Yoast filters now take the post from the context Yoast passes, and bibliography_builder_json_ld_page_url() accepts that post, passing it to its filter as a second argument. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA2F1J2N3yCPk3cUX1P * Satisfy Psalm and update the PHP line count get_permalink() takes a WP_Post or an ID, so pass the context post's ID when it is some other object, and declare the context post as an object. docs/current-metrics.md follows the new first-party PHP line count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA2F1J2N3yCPk3cUX1P * Type the post get_cited_work_refs() accepts as any object It already reads any object with post_content; Psalm now accepts the post from Yoast's context there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA2F1J2N3yCPk3cUX1P * Put full citation records into Yoast SEO's graph Yoast's schema aggregator and NLWeb (crawler and WordPress plugin MCP answers) read only Yoast's graph, where Borges put {@type, @id, name} stubs, so 12 of 78 traced field values reached them. The Yoast Article and WebPage filters now embed each cited work's full record, the same one the ItemList carries, deduplicated by @id and without @context. The bibliography_builder_yoast_citation_records filter returns to the short references. Rank Math and the no-SEO WebPage node keep them. Verified with tools/yoast-nlweb-trace (PR #253): 78/78 at the Yoast graph, aggregator feed, NLWeb index, and NLWeb MCP answer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WPtgA2F1J2N3yCPk3cUX1P --------- Co-authored-by: Claude <noreply@anthropic.com>
…-builder into yoast-trace # Conflicts: # docs/current-metrics.md
Requested by Dan · project thread
Summary
tools/yoast-nlweb-trace/, a reproducible trace of Borges' citation metadata through Yoast SEO's schema graph and NLWeb on the way to an AI agent.setup.shbuilds a local site: WordPress 7.1.4 on SQLite, this checkout of Borges, Yoast SEO 28.8 with schema aggregation on, and NLWeb atb423f15(both its WordPress plugin and its Python ingest code). The fixture post is the markup-value corpus: 12 works, 8 DOIs, 2 ISBNs, and 78 field values.capture.shsaves every stage,measure.pyscores each field at each stage, andprobe.pyasks questions that only the fields lost along the way could answer. Results are inresults/2026-11-04/, and the README explains the method and the findings. The only change outsidetools/is one line in.prettierignore.Findings
Labeled field values that survive, out of 78:
citation@idURLs. It gets no authors, years, journals, pages, ISBNs, or publishers. Those stay in Borges'ItemList, and nothing past Yoast reads that list.trim_schema_jsondrops everyItemList. It also dropsWebPagenodes and every top-levelpublisher. So crawling the page gets no more than Yoast's feed does.citationis the only option that also reaches the plugin's MCP answer. The cost: Yoast's script on this page goes from 7.6 KB to about 28 KB.The prototypes live in
trace-variants.php, a test-site mu-plugin. Whether Borges should adopt one is Dan's call, and it would be its own PR.Validation
setup.sh, and the numbers matchednpm run format:checkpassestools/is in.distignore.Checklist
Generated by Claude Code